./c0de/c/dnsrpcscan.txt

0.
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
22.
23.
24.
25.
26.
27.
28.
29.
30.
31.
32.
33.
34.
35.
36.
37.
38.
39.
40.
41.
42.
43.
44.
45.
46.
47.
48.
49.
50.
51.
52.
53.
54.
55.
56.
57.
58.
59.
60.
61.
62.
63.
64.
65.
66.
67.
68.
69.
70.
71.
72.
73.
74.
75.
76.
77.
78.
79.
80.
81.
82.
83.
84.
85.
86.
87.
88.
89.
90.
91.
92.
93.
94.
95.
96.
97.
98.
99.
100.
101.
102.
103.
104.
105.
106.
107.
108.
109.
110.
111.
112.
113.
114.
115.
116.
117.
118.
119.
120.
121.
122.
123.
124.
125.
126.
127.
128.
129.
130.
131.
132.
133.
134.
135.
136.
137.
138.
139.
140.
141.
142.
143.
144.
145.
146.
147.
148.
149.
150.
151.
152.
153.
154.
155.
156.
157.
158.
159.
160.
161.
162.
163.
164.
165.
166.
167.
168.
169.
170.
171.
172.
173.
174.
175.
176.
177.
178.
179.
180.
181.
182.
183.
184.
185.
186.
187.
188.
189.
190.
191.
192.
193.
194.
195.
196.
197.
198.
199.
200.
201.
202.
203.
204.
205.
206.
207.
208.
209.
210.
211.
212.
213.
214.
215.
216.
217.
218.
219.
220.
221.
222.
223.
224.
225.
226.
227.
228.
229.
230.
231.
232.
233.
234.
235.
236.
237.
238.
239.
240.
241.
242.
243.
244.
245.
246.
247.
248.
249.
250.
251.
252.
253.
254.
255.
256.
257.
258.
259.
260.
261.
262.
263.
264.
265.
266.
267.
268.
269.
270.
271.
272.
273.
274.
275.
 /*
Version 1.1,yunshu change dm's code to windows box,please keep private!
 
Complied by dev-cpp 4.9.9
 
C:\>gcc dnsrpc_scanner.cpp -o dnsrpc_scan.exe -I"d:/Dev-Cpp/lib/gcc/mingw32/3.4.2/include"  -I"d:/Dev-cpp/include/c++/3.4.2/backward"  -I"d:/Dev-Cpp/include/c++/3.4.2/mingw32"  -I"d:/Dev-Cpp/include/c++/3.4.2"  -I"d:/Dev-Cpp/include" -L"d:/Dev-Cpp/lib" d:/Dev-Cpp/lib/libws2_32.a -O3
*/
 
#include <stdio.h>
#include <Windows.h>
#include <winsock2.h>
 
#define        DNS_PORT        53                    // DNS服务的端口
 
HANDLE         H_Semaphore = NULL;                    // 信标内核对象句柄,用来控制线程数量
HANDLE        H_Event;                            // 事件,用于判断是否扫描完成
int            TimeOut;                            // Socket超时
long        PreviousCount;
long        ActiveThreads;                        // 活动线程数量
int            MaxThread;                            // 最大线程数量
HANDLE        H_Out;
 
// 显示帮助
void    Help( char *Program_Name )
{
    printf( "\nDnsRPC Scanner,yunshu change dm's code to windows box\n" );
    printf( "Usage: %s    <start_ip>    <end_ip>    <max_thread>    <time_out>\n", Program_Name );
    printf( "Example: %s 59.151.28.1 59.151.28.254 60 4\n\n", Program_Name );
}
 
// 连接到指定的tcp端口,成功返回socket,失败返回SOCKET_ERROR             
int        tcpConnect( long host, unsigned int port, unsigned int timeout )
{
    SOCKET            Sock;
    int                Ret;
    SOCKADDR_IN        Sin;
 
    unsigned int    TM = timeout * 1000 / 2;
 
    // 建立socket
    Sock = socket( AF_INET , SOCK_STREAM , 0 );
    if( Sock == INVALID_SOCKET )
    {
        return SOCKET_ERROR;
    }
 
    //设置发送超时时间
    Ret = setsockopt( Sock, SOL_SOCKET, SO_SNDTIMEO, (char *)&TM, sizeof(TM) );
    if( SOCKET_ERROR == Ret )
    {
        return SOCKET_ERROR;
    }
 
    //设置接收超时时间
    Ret = setsockopt( Sock, SOL_SOCKET, SO_RCVTIMEO, (char *)&TM, sizeof(TM) );
    if( SOCKET_ERROR == Ret )
    {
        return SOCKET_ERROR;
    }
 
    memset( (void *)(&Sin), 0, sizeof(SOCKADDR_IN) );
 
    Sin.sin_family = AF_INET;
    Sin.sin_addr.s_addr = host;
    Sin.sin_port = htons(port);
 
    Ret = connect( Sock , (struct sockaddr*)&Sin , sizeof(SOCKADDR_IN) );
    if( SOCKET_ERROR == Ret )
    {
        return SOCKET_ERROR;
    }
 
    return Sock;
}
 
int Check_Vuln( long host, int port )
{
    SOCKET    Sock;
    int        Ret = 0;
 
    unsigned char    Resp[500] = { 0 };
 
    // bind
    char peer0_0[] =
    {
        0x05, 0x00, 0x0b, 0x03, 0x10, 0x00, 0x00, 0x00,
        0x48, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00,
        0xb8, 0x10, 0xb8, 0x10, 0x00, 0x00, 0x00, 0x00,
        0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00,
        0xa4, 0xc2, 0xab, 0x50, 0x4d, 0x57, 0xb3, 0x40,
        0x9d, 0x66, 0xee, 0x4f, 0xd5, 0xfb, 0xa0, 0x76,
        0x05, 0x00, 0x00, 0x00, 0x04, 0x5d, 0x88, 0x8a,
        0xeb, 0x1c, 0xc9, 0x11, 0x9f, 0xe8, 0x08, 0x00,
        0x2b, 0x10, 0x48, 0x60, 0x02, 0x00, 0x00, 0x00
    };
 
    // opnum 9
    char peer0_1[] =
    {
        0x05, 0x00, 0x00, 0x03, 0x10, 0x00, 0x00, 0x00,
        0x24, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00,
        0x0c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x09, 0x00,
        0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
        0x00, 0x00, 0x00, 0x00
    };
 
    if ( (Sock = tcpConnect(host, port, TimeOut) ) == SOCKET_ERROR )
    {
        goto check_vulnout;
    }
 
    if ( (Ret = send(Sock, peer0_0, sizeof(peer0_0), 0)) < 0)
    {
        goto check_vulnout;
    }
 
    if ( (Ret = recv(Sock, (char *)Resp, sizeof(Resp), 0)) != 60 )
    {
        goto check_vulnout;
    }
 
    // not accept packet
    if (Resp[0] != 0x05 && Resp[2] != 0x0c && Resp[36] != 0x00 && Resp[37] != 0x00)
    {
        goto check_vulnout;
    }
 
    if ( (Ret = send(Sock, peer0_1, sizeof(peer0_1), 0)) < 0 )
    {
        goto check_vulnout;
    }
 
    memset(Resp, 0x00, sizeof(Resp));
 
    if ( (Ret = recv(Sock, (char *)Resp, sizeof(Resp), 0)) != 32 )
    {
        goto check_vulnout;
    }
 
    // not valid falut packet
    if (Resp[0] != 0x05 && Resp[1] != 0x00 && Resp[2] != 0x03)
    {
        goto check_vulnout;
    }
 
    // windows 2000
    if ( (Resp[24] == 0x02) && (Resp[25] == 0x00) && (Resp[26] == 0x01) && (Resp[27] == 0x1c) )
    {
        printf( "[+] %s\tDNSRPC running on[%d] OS: windows 2000 !\n", inet_ntoa(*(struct in_addr *)(&host)), port );
        Ret = 1;
    }
    // windows 2003
    else if ( (Resp[24] == 0xf7) && (Resp[25] == 0x06) && (Resp[26] == 0x00) && (Resp[27] == 0x00) )
    {
        printf( "[+] %s\tDNSRPC running on[%d] OS: windows 2003 !\n", inet_ntoa(*(struct in_addr *)(&host)), port );
        Ret = 1;
    }
 
    check_vulnout:
 
    if (Sock != SOCKET_ERROR)
    {
        closesocket(Sock);
    }
 
    return(Ret);
}
 
void WINAPI    Scan_Host( LPVOID host )
{
    long    DstHost = (long)host;
    int        Ret;
 
    DstHost = htonl(DstHost);
 
    /*
    * check DNS port
    */
    SOCKET Sock;
    if ( (Sock = tcpConnect( DstHost, DNS_PORT, TimeOut) ) == SOCKET_ERROR )
    {
        closesocket(Sock);
        goto finish;
    }
    closesocket(Sock);
 
    for( int DnsPort = 1025; DnsPort < 1500; DnsPort ++ )
    {
        Ret = Check_Vuln( DstHost, DnsPort );
 
        if ( Ret == 1 )
        {
            break;
        }
    }
 
    finish:
 
    //printf( "[+] scaning %s done.\n",inet_ntoa(*(struct in_addr *)(&DstHost)) );
 
    ReleaseSemaphore( H_Semaphore, 1, &PreviousCount );
 
    ActiveThreads = MaxThread - PreviousCount - 1;
 
    if( ActiveThreads == 0 )
    {
        SetEvent(H_Event);
    }
}
 
int    main( int argc, char *argv[] )
{
    if( argc != 5 )
    {
        Help( argv[0] );
        return -1;
    }
 
    WSAData        wsa;
 
    // 初始化网络库
    if( WSAStartup(0x0202,&wsa) != 0 )
    {
        printf( "[-] WSAStartup failed with error: %d\n" , GetLastError() );
        return -1;
    }
 
    long    StartHost = ntohl( inet_addr( argv[1] ) );
    long    EndHost = ntohl( inet_addr( argv[2] ) );
 
    MaxThread = atoi( argv[3] );
    TimeOut = atoi( argv[4] );
 
    H_Out = GetStdHandle(STD_OUTPUT_HANDLE);
 
    H_Semaphore = CreateSemaphore( NULL, MaxThread, MaxThread, NULL );
    if( NULL == H_Semaphore )
    {
        printf( "[-] CreateSemaphore failed with error: %d\n", GetLastError() );
        return -1;
    }
 
    // 创建事件内核对象,初始状态为未通知
    H_Event = CreateEvent( NULL, TRUE, FALSE, NULL );
    if( NULL == H_Event )
    {
        printf( "[-] CreateEvent failed with error: %d\n", GetLastError() );
 
        CloseHandle(H_Semaphore);
        return -1;
    }
 
    printf( "[+] Start scaning...\n" );
 
    DWORD    ThreadId = 0;
    for( long index = StartHost; index <= EndHost; index ++ )
    {
        WaitForSingleObject( H_Semaphore, INFINITE );
 
        HANDLE    H_Thread = CreateThread( NULL, 0, (LPTHREAD_START_ROUTINE)Scan_Host, (void *)index, 0, &ThreadId );
        if( NULL != H_Thread )
        {
            CloseHandle( H_Thread );
        }
    }
 
    // 等待事件内核对象通知所有线程结束
    WaitForSingleObject( H_Event, INFINITE );
 
    printf( "[+] All thread done!");
 
    WSACleanup( );
 
    return 0;
} 

Back