one_gadget. constraints analyze & troubleshooting
one_gadget은 어떤 버젼의 libc냐의 따라 완전히 constraints이 달라지게 된다. 그중 최근의 Dreamhack 문제를 풀면서 해결한 문제의 대해서 다룬다.
일반적으로 최근버젼의 libc에 대해서 one_gadget을 실행하면
C
(pwn) amemoyoi ~$ one_gadget /lib/i386-linux-gnu/libc.so.6
0xe2ff0 execve("/bin/sh", [ebp-0x30], esi)
constraints:
address ebp-0x24 is writable
[ebp-0x2c] is the GOT address of libc
[[ebp-0x30]] == NULL || [ebp-0x30] == NULL || [ebp-0x30] is a valid argv
[esi] == NULL || esi == NULL || esi is a valid envp
0xe2ff3 execve("/bin/sh", [ebp-0x30], esi)
constraints:
address ebp-0x24 is writable
ecx is the GOT address of libc
[[ebp-0x30]] == NULL || [ebp-0x30] == NULL || [ebp-0x30] is a valid argv
[esi] == NULL || esi == NULL || esi is a valid envp
0xe2ff9 execve("/bin/sh", [ebp-0x30], esi)
constraints:
address ebp-0x20 is writable
ecx is the GOT address of libc
[[ebp-0x30]] == NULL || [ebp-0x30] == NULL || [ebp-0x30] is a valid argv
[esi] == NULL || esi == NULL || esi is a valid envp
0xe3000 execve("/bin/sh", [ebp-0x30], esi)
constraints:
address ebp-0x30 is writable
ecx is the GOT address of libc
[[ebp-0x30]] == NULL || [ebp-0x30] == NULL || [ebp-0x30] is a valid argv
[esi] == NULL || esi == NULL || esi is a valid envp
0x17e0b1 execl("/bin/sh", eax)
constraints:
esi is the GOT address of libc
eax == NULL
0x17e0b2 execl("/bin/sh", [esp])
constraints:
esi is the GOT address of libc
[esp] == NULL다음과 같이 나오게 된다.
많은 제약조건들이 있음을 알 수 있다. 근데 자세히 보면 is the GOT address of libc 이 문장이 필수로 포함되어 있다. 이게 어떤 조건을 말하는 것이고 왜 필요한지 알아보자
일단 가장 쉬운 조건은 주로
C
0x17e0b1 execl("/bin/sh", eax)
constraints:
esi is the GOT address of libc
eax == NULL이런 형태이다. eax == NULL도 return 0; 문장이 있다면 바로 충족이 가능하기 때문이다. 따라서 이 조건을 만족시키겠다.

libc의 0x17e0b1 오프셋에는 사진과 같은 코드가 존재한다.
자세히 보면 $esi ( X86 문제라서 ) 에 특정 오프셋값을 빼고 그 값을 스택에 넣고 execl 함수를 실행한다. execl 함수는 execve 함수와 같은 맥락을 가진다.
따라서 저 %eax 에는 “/bin/sh”의 주소가 들어가야 한다.
원래 의도도 같다. 저 %eax에 “/bin/sh”의 주소가 들어가게 설계가 되어 있다.
즉, 원래 %esi 값에 조건 대로
esi is the GOT address of libc 라는 것이다.
C
(pwn) amemoyoi ~$ objdump -h /lib/i386-linux-gnu/libc.so.6 | grep .got
13 .plt.got 00000010 00023190 00023190 00023190 2**3
26 .got 000001cc 00230e34 00230e34 00230e34 2**2다음과 같이 오프셋을 알 수 있고 그러면 libc_base + 00230e34 의 값을 $esi에 넣으면 된다.