很少见有人写关于Hex-Rays的文章,这几天摸索了一下,发现这东西相当不错,现在写篇关于Hex-Rays的文章,因为Hex-Rays是个新玩意(对我来说),有错误的地方请大家见谅。
废话结束………………
打开程序------>exploitmeA 发现是开7777端口,NC链接下看看。打入什么返回什么。
感觉很像《网络渗透技术》那本书的W32溢出例程,好,打开IDA+Hex-Rays分析下。
得到
int __cdecl main(int argc, const char **argv, const char *envp)
{
SOCKET v3; // eax@1
SOCKET v4; // ebp@1
SOCKET v5; // ebx@6
int v6; // esi@7
SOCKET v8; // eax@6
int v9; // eax@7
SOCKET v10; // eax@10
struct WSAData WSAData; // [sp+228h] [bp-190h]@1
struct sockaddr name; // [sp+4h] [bp-3B4h]@4
struct sockaddr addr; // [sp+14h] [bp-3A4h]@6
int v14; // [sp+28h] [bp-390h]@7
WSAStartup(0x101u, &WSAData);
v3 = socket(2, 1, 0);
v4 = v3;
if ( (signed int)v3 < 0 )
{
ostream__operator__(v3);
ostream__operator__("socket creating error!");
ostream__operator__(10);
sub_4012B0(sub_4012D0);
exit(1);
}
*(_WORD *)&name.sa_data[2] = 2;
*(_WORD *)&name.sa_data[4] = htons(0x1E61u);
*(_DWORD *)&name.sa_data[6] = htonl(0);
if ( bind(v4, (const struct sockaddr *)&name.sa_data[2], 16) )
{
ostream__operator__("binding stream socket error!");
ostream__operator__(10);
sub_4012B0(sub_4012D0);
}
ostream__operator__("**************************************");
ostream__operator__(10);
sub_4012B0(sub_4012D0);
ostream__operator__(" exploit target server 1.0\t ");
ostream__operator__(10);
sub_4012B0(sub_4012D0);
ostream__operator__("**************************************");
ostream__operator__(10);
sub_4012B0(sub_4012D0);
listen(v4, 4);
*(_DWORD *)&name.sa_family = 16;
v8 = accept(v4, (struct sockaddr *)&addr.sa_data[2], (int *)&name);
v5 = v8;
if ( v8 != -1 )
{
while ( 1 )
{
memset(&v14, 0, 0x200u);
v9 = recv(v5, (char *)&v14, 512, 0);
v6 = v9;
if ( v9 < 0 )
{
ostream__operator__("reading stream message erro!");
ostream__operator__(10);
sub_4012B0(sub_4012D0);
v6 = 0;
}
sub_401000(&v14);
if ( !v6 )
{
closesocket(v5);
v10 = accept(v4, (struct sockaddr *)&addr.sa_data[2], (int *)&name);
v5 = v10;
if ( v10 == -1 )
break;
}
}
}
ostream__operator__("accept error!");
ostream__operator__(10);
sub_4012B0(sub_4012D0);
return WSACleanup();
}
注意这里
memset(&v14, 0, 0x200u);
v9 = recv(v5, (char *)&v14, 512, 0);
v6 = v9;
if ( v9 < 0 )
{
ostream__operator__("reading stream message erro!");
ostream__operator__(10);
sub_4012B0(sub_4012D0);
v6 = 0;
}
sub_401000(&v14);
这个V14定义了200h的unsigned int
sub_401000函数代码:
int __cdecl sub_401000(int a1)
{
char v2; // [sp+8h] [bp-C8h]@1
strcpy(&v2, (const char *)a1);
ostream__operator__("********************");
ostream__operator__(10);
sub_4012B0(sub_4012D0);
ostream__operator__("received:");
ostream__operator__(10);
sub_4012B0(sub_4012D0);
ostream__operator__(&v2);
ostream__operator__(10);
return sub_4012B0(sub_4012D0);
}
定义出来a1后这个函数很关键strcpy!!!!!!!!!!
感觉溢出就在这里了
开200个FUZZ应该再加JUMP+SHELLCODE就可以了
这是个FUZZ的小程序,不是我写的,抄到这里
#include <stdio.h>
int main(int argc,char **argv)
{
char *buff;
int i,Len;
if(argc < 3)
{
printf("Magic Char By CoolDiyer\n");
printf("Usage:\n\t mc -c <count> [-v]\n");
return -1;
}
Len=atoi(argv[2]);
buff=(char *)malloc(Len+1);
buff[Len]=0;
for(i=0;i<Len;i++)
{
switch(i%4)
{
case 0: buff[i] = 'A'+i/(26*26*26)%26; break;
case 1: buff[i] = 'A'+i/(26*26)%26; break;
case 2: buff[i] = 'A'+i/26%26; break;
case 3: buff[i] = 'A'+i%26; break;
}
}
if(argc == 4)
{
for(i=1; i< Len+1; i++)
{
printf("%c",buff[i-1]);
if(i%4 == 0)
{
printf("\t%d\t0x%.2x",i,i);
printf("\tEIP ==> 0x%.2x%.2x%.2x%.2x\n",buff[i-1],buff[i-2],buff[i-3],buff[i-4]);
}
}
} else {
printf("%s\n",buff);
}
return 0;
}
出一个FUZZ--->
D:\>mc
Magic Char By CoolDiyer
Usage:
mc -c <count> [-v]
D:\>mc -c 500
AAADAAAHAAALAAAPAAATAAAXAABBAABFAABJAABNAABRAABVAABZAACDAACHAACLAACPAACTAACXAADB
AADFAADJAADNAADRAADVAADZAAEDAAEHAAELAAEPAAETAAEXAAFBAAFFAAFJAAFNAAFRAAFVAAFZAAGD
AAGHAAGLAAGPAAGTAAGXAAHBAAHFAAHJAAHNAAHRAAHVAAHZAAIDAAIHAAILAAIPAAITAAIXAAJBAAJF
AAJJAAJNAAJRAAJVAAJZAAKDAAKHAAKLAAKPAAKTAAKXAALBAALFAALJAALNAALRAALVAALZAAMDAAMH
AAMLAAMPAAMTAAMXAANBAANFAANJAANNAANRAANVAANZAAODAAOHAAOLAAOPAAOTAAOXAAPBAAPFAAPJ
AAPNAAPRAAPVAAPZAAQDAAQHAAQLAAQPAAQTAAQXAARBAARFAARJAARNAARRAARVAARZAASDAASHAASL
AASPAASTAASXAATBAATF
用ollydbg加一下exploitmea,用NC把它发出去
程序崩掉了,哈哈,显示程序不知道如何读取地址56484141
好
D:\>mc -c 500 -v
AAAD 4 0x04 EIP ==> 0x44414141
AAAH 8 0x08 EIP ==> 0x48414141
。。。。。。。。。。
AAET 124 0x7c EIP ==> 0x54454141
AAEX 128 0x80 EIP ==> 0x58454141
AAFB 132 0x84 EIP ==> 0x42464141
AAFF 136 0x88 EIP ==> 0x46464141
AAFJ 140 0x8c EIP ==> 0x4a464141
AAFN 144 0x90 EIP ==> 0x4e464141
AAFR 148 0x94 EIP ==> 0x52464141
AAFV 152 0x98 EIP ==> 0x56464141
AAFZ 156 0x9c EIP ==> 0x5a464141
AAGD 160 0xa0 EIP ==> 0x44474141
AAGH 164 0xa4 EIP ==> 0x48474141
AAGL 168 0xa8 EIP ==> 0x4c474141
AAGP 172 0xac EIP ==> 0x50474141
AAGT 176 0xb0 EIP ==> 0x54474141
AAGX 180 0xb4 EIP ==> 0x58474141
AAHB 184 0xb8 EIP ==> 0x42484141
AAHF 188 0xbc EIP ==> 0x46484141
AAHJ 192 0xc0 EIP ==> 0x4a484141
AAHN 196 0xc4 EIP ==> 0x4e484141
AAHR 200 0xc8 EIP ==> 0x52484141
AAHV 204 0xcc EIP ==> 0x56484141 <========这里。
AAHZ 208 0xd0 EIP ==> 0x5a484141
AAID 212 0xd4 EIP ==> 0x44494141
。。。。。。。。。。。。。。。。
AAHV 204 0xcc EIP ==> 0x56484141
注意到204了吧,这就是长度了,多出来的4正式AAHV也就是JMP的位置。
剩下的分析步骤别的贴也说的很清楚了,我就不啰嗦了。
顺便把《网络渗透技术》那本书的W32溢出例程发出来,例程是原码,和exploitmea原理一模一样。
/* server.cpp
*
* 《网络渗透技术》演示程序
* 作者:san, alert7, eyas, watercloud
*
* 存在缓冲区溢出的服务端程序
*/
#include <winsock2.h>
#include <stdio.h>
#pragma comment(lib,"ws2_32")
char Buff[2048];
void overflow(char * s,int size)
{
char s1[50];
printf("receive %d bytes",size);
s[size]=0;
strcpy(s1,s);
}
int main()
{
WSADATA wsa;
SOCKET listenFD;
int ret;
char asd[2048];
WSAStartup(MAKEWORD(2,2),&wsa);
listenFD = WSASocket(2,1,0,0,0,0);
struct sockaddr_in server;
server.sin_family = AF_INET;
server.sin_port = htons(8888);
server.sin_addr.s_addr = INADDR_ANY;
ret=bind(listenFD,(sockaddr *)&server,sizeof(server));
ret=listen(listenFD,2);
int iAddrSize = sizeof(server);
SOCKET clientFD=accept(listenFD,(sockaddr *)&server,&iAddrSize);
unsigned long lBytesRead;
while(1) {
lBytesRead=recv(clientFD,Buff,2048,0);
if(lBytesRead<=0) break;
printf("\nfd = %x\n", clientFD);
overflow(Buff,lBytesRead);
ret=send(clientFD,Buff,lBytesRead,0);
if(ret<=0) break;
}
WSACleanup();
return 0;
}
/* server.cpp
*
* 《网络渗透技术》演示程序
* 作者:san, alert7, eyas, watercloud
*
* 存在缓冲区溢出的服务端程序
*/
#include <winsock2.h>
#include <stdio.h>
#pragma comment(lib,"ws2_32")
char Buff[2048];
void overflow(char * s,int size)
{
char s1[50];
printf("receive %d bytes",size);
s[size]=0;
strcpy(s1,s);
}
int main()
{
WSADATA wsa;
SOCKET listenFD;
int ret;
char asd[2048];
WSAStartup(MAKEWORD(2,2),&wsa);
listenFD = WSASocket(2,1,0,0,0,0);
struct sockaddr_in server;
server.sin_family = AF_INET;
server.sin_port = htons(8888);
server.sin_addr.s_addr = INADDR_ANY;
ret=bind(listenFD,(sockaddr *)&server,sizeof(server));
ret=listen(listenFD,2);
int iAddrSize = sizeof(server);
SOCKET clientFD=accept(listenFD,(sockaddr *)&server,&iAddrSize);
unsigned long lBytesRead;
while(1) {
lBytesRead=recv(clientFD,Buff,2048,0);
if(lBytesRead<=0) break;
printf("\nfd = %x\n", clientFD);
overflow(Buff,lBytesRead);
ret=send(clientFD,Buff,lBytesRead,0);
if(ret<=0) break;
}
WSACleanup();
return 0;
}
[培训]内核驱动高级班,冲击BAT一流互联网大厂工作,每周日13:00-18:00直播授课