#include <stdlib.h>
#include <unistd.h>
#include <string.h>
#include <stdio.h>
#include <sys/types.h>
struct internet {
int priority;
char *name;
};
void winner()
{
printf("and we have a winner @ %d\n", time(NULL));
}
int main(int argc, char **argv)
{
struct internet *i1, *i2, *i3;
i1 = malloc(sizeof(struct internet));
i1->priority = 1;
i1->name = malloc(8);
i2 = malloc(sizeof(struct internet));
i2->priority = 2;
i2->name = malloc(8);
strcpy(i1->name, argv[1]);
strcpy(i2->name, argv[2]);
printf("and that's a wrap folks!\n");
}
모든 보호기법이 없고 ASLR도 0이다.
이 문제는 heap를 그려야 이해하기 편하다.
[그림 1-2]를 보면 i1->name에 써진 주소로 이동해 해당 주소에 argv[1]값을 입력을한다.
이를 이용해 코드에서 strcpy(i1->name,argv[1])을 overflow로 이용해 i2->name에는 printf got 주소를 넣고 argv[2]에는 winner 주소를 넣으면 strcpy(i2->name,argv[2]) 실행시 strcpy(printf got, winner 주소) 되는 것이다.
printf got 주소가 winner 주소로 바뀌어 코드 마지막 printf 가 실행될 때 winner 함수가 실행될 것이다.
필요한 정보를 모아보자
winner 주소와 printf got 주소를 찾았다.
payload를 짜기위해 heap을 열어보자
r AAAA BBBB을 넣고 heap를 보면 [그림 1-2]처럼 생겼다.
0x804a184 주소에 printf got 주소를 넣고 argv[2]에는 winner 주소를 넣으면 된다.
코드에서는 printf를 사용했지만 컴파일러가 puts로 바꿨다.
결국 printf got 주소를 넣는게 아니라 puts got 주소를 넣어야 익스가 된다..