#include <stdio.h>
#include <stdlib.h>
#include <signal.h>
#include <unistd.h>
void alarm_handler() {
puts("TIME OUT");
exit(-1);
}
void initialize() {
setvbuf(stdin, NULL, _IONBF, 0);
setvbuf(stdout, NULL, _IONBF, 0);
signal(SIGALRM, alarm_handler);
alarm(30);
}
int main(int argc, char *argv[]) {
char buf[0x40] = {};
initialize();
read(0, buf, 0x400);
write(1, buf, sizeof(buf));
return 0;
}
32bit라는 것만 제외하고 코드는 basic_rop_x64와 동일하다.
32bit는 함수인자값을 스택에서 참조한다.
buf 위치가 ebp-0x44라는 걸 알 수 있다.
puts를 이용해 read_got 값을 출력해 system 함수 주소를 얻고 read를 이용해 read_got 값에 system 함수 주소와 "/bin/sh" 문자열을 넣어 다시 read 함수를 호출하여 system 함수를 실행시키도록 하자
성공!
알게 된 점
1. GOT 값을 overwrite 할 수 있는 이유는 GOT 영역에 쓰기(w) 권한이 있기 때문이다.
익스 코드에서 0x804a00c에 system 함수주소를 넣고 0x804a00c + 0x4 에 "/bin/sh" 문자열을 넣는다.
[그림 2-1] 보면 0x804a00c와 0x804a00c + 0x4 모두 쓰기(w) 권한이 있는 곳에 존재하기 때문에 쓸 수 있다.
2. 32bit 환경에서 라이브러리 주소는 0xf7로 시작한다. 64bit는 0x7f로 시작
3. 문제에서 라이브러리 파일을 제공하면 gdb를 통해 offset 값을 쉽게 확인할 수 있다.
따라서 라이브러리 매핑된 주소만 찾으면 함수를 실행시킬 수 있다.
libc.symbols ['system'] -> 잘 동작되지 않을 때 직접 주소를 넣어보자
4. 문제에서 라이브러리 파일을 제공하면 strings 명령어를 통해 "/bin/sh" offset 값을 쉽게 확인할 수 있다.
따라서 라이브러리 매핑된 주소만 찾으면 실제 "/bin/sh" 위치를 알 수 있다.
"/bin/sh" 문자열을 입력할 수 없을때 사용하자
'Dreamhack - pwnable' 카테고리의 다른 글
RELRO (RELocation Read-Only) (0) | 2023.01.16 |
---|---|
basic_rop_x86 (ret2main + bss 쓰기) (0) | 2023.01.15 |
basic_rop_x64 (ret2main) (0) | 2023.01.15 |
basic_rop_x64 (GOT Overwrite) (0) | 2023.01.14 |
Return Oriented Programming (0) | 2023.01.13 |