| 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;
} |