查看單個文章
舊 2006-10-31, 02:19 PM   #4 (permalink)
psac
榮譽會員
 
psac 的頭像
榮譽勳章
UID - 3662
在線等級: 級別:30 | 在線時長:1048小時 | 升級還需:37小時級別:30 | 在線時長:1048小時 | 升級還需:37小時級別:30 | 在線時長:1048小時 | 升級還需:37小時級別:30 | 在線時長:1048小時 | 升級還需:37小時級別:30 | 在線時長:1048小時 | 升級還需:37小時
註冊日期: 2002-12-07
住址: 木柵市立動物園
文章: 17381
現金: 5253 金幣
資產: 33853 金幣
預設

Radmin服務端保持連接不斷問題分析與解決

1、問題描述
Radmin是一個絕佳的遠端控制軟件,用來做跳板的後門再好不過了,不過每次連過跳板後,察看跳板連線,可以仍然看見我們和跳板上Radmin的連接,只不過顯示為TIME_WAIT,且一直這樣。
Proto Local Address Foreign Address State
TCP 0.0.0.0:135 0.0.0.0:0 LISTENING
TCP 0.0.0.0:445 0.0.0.0:0 LISTENING
TCP 0.0.0.0:1030 0.0.0.0:0 LISTENING
TCP 127.0.0.1:1031 0.0.0.0:0 LISTENING
TCP 192.168.11.1:139 0.0.0.0:0 LISTENING
TCP 192.168.72.1:139 0.0.0.0:0 LISTENING
TCP 192.168.168.220:1030 192.168.168.221:1034 TIME_WAIT
UDP 0.0.0.0:445 *:*
UDP 0.0.0.0:1026 *:*
UDP 127.0.0.1:123 *:*
UDP 127.0.0.1:1900 *:*
UDP 192.168.11.1:123 *:*
UDP 192.168.11.1:137 *:*
UDP 192.168.11.1:138 *:*
UDP 192.168.11.1:1900 *:*
UDP 192.168.72.1:123 *:*
UDP 192.168.72.1:137 *:*
UDP 192.168.72.1:138 *:*
UDP 192.168.72.1:1900 *:*
UDP 192.168.168.220:123 *:*
UDP 192.168.168.220:1900 *:*
2、問題分析
初步猜測應該是setsocketopt設置超時有問題,可能是設置了無限超時?
除錯Radmin服務端,下中斷點在setsocketopt,結果如下:
第一次斷下來
71A42E30 > 8BFF MOV EDI,EDI
71A42E32 55 PUSH EBP
71A42E33 8BEC MOV EBP,ESP
71A42E35 837D 0C 00 CMP DWORD PTR SS:[EBP+C],0
71A42E39 0F84 25010000 JE WSOCK32.71A42F64
71A42E3F 8B45 10 MOV EAX,DWORD PTR SS:[EBP+10]
71A42E42 837D 0C 06 CMP DWORD PTR SS:[EBP+C],6
71A42E46 8B4D 14 MOV ECX,DWORD PTR SS:[EBP+14]
71A42E49 74 75 JE SHORT WSOCK32.71A42EC0
71A42E4B FF75 18 PUSH DWORD PTR SS:[EBP+18]
71A42E4E 51 PUSH ECX
71A42E4F 50 PUSH EAX
71A42E50 FF75 0C PUSH DWORD PTR SS:[EBP+C]
71A42E53 FF75 08 PUSH DWORD PTR SS:[EBP+8]
71A42E56 E8 09000000 CALL <JMP.&WS2_32.#21__setsockopt@20>
71A42E5B 5D POP EBP
71A42E5C C2 1400 RETN 14
71A42E5F 90 NOP
71A42E60 90 NOP
71A42E61 90 NOP
71A42E62 90 NOP
71A42E63 90 NOP
71A42E64 - FF25 0010A471 JMP DWORD PTR DS:[<&WS2_32.#21__setsocko>; WS2_32.setsockopt
察看堆疊:
0012F808 0096D367 /CALL 到 setsockopt 來自 0096D362
0012F80C 0000007C |Socket = 7C
0012F810 0000FFFF |Level = SOL_SOCKET
0012F814 00000080 |Option = SO_LINGER
0012F818 0012F844 |Data = 0012F844
0012F81C 00000004 \DataSize = 4
0012F820 0000FFFF
0012F824 0012F84C
0012F828 /0012F850
0012F82C |009652F2 返回到 009652F2 來自 0096D340
0012F830 |00000080
0012F834 |0012F844
0012F838 |00000004
0012F83C |0012F870
0012F840 |001D0406
0012F844 |00010001
0012F848 |0012F870
0012F84C |0000007C
0012F850 ]0012F884
可以看到,它設置了SO_LINGER選項,值為0x00010001
第二次中斷點:
71A42E30 > 8BFF MOV EDI,EDI
71A42E32 55 PUSH EBP
71A42E33 8BEC MOV EBP,ESP
71A42E35 837D 0C 00 CMP DWORD PTR SS:[EBP+C],0
71A42E39 0F84 25010000 JE WSOCK32.71A42F64
71A42E3F 8B45 10 MOV EAX,DWORD PTR SS:[EBP+10]
71A42E42 837D 0C 06 CMP DWORD PTR SS:[EBP+C],6
71A42E46 8B4D 14 MOV ECX,DWORD PTR SS:[EBP+14]
71A42E49 74 75 JE SHORT WSOCK32.71A42EC0
71A42E4B FF75 18 PUSH DWORD PTR SS:[EBP+18]
71A42E4E 51 PUSH ECX
71A42E4F 50 PUSH EAX
71A42E50 FF75 0C PUSH DWORD PTR SS:[EBP+C]
71A42E53 FF75 08 PUSH DWORD PTR SS:[EBP+8]
71A42E56 E8 09000000 CALL <JMP.&WS2_32.#21__setsockopt@20>
71A42E5B 5D POP EBP
71A42E5C C2 1400 RETN 14
堆疊:
0012F80C 0096D367 /CALL 到 setsockopt 來自 0096D362
0012F810 00000078 |Socket = 78
0012F814 0000FFFF |Level = SOL_SOCKET
0012F818 00000080 |Option = SO_LINGER
0012F81C 0012F84C |Data = 0012F84C
0012F820 00000004 \DataSize = 4
0012F824 0000FFFF
0012F828 0012F848
0012F82C /0012F850
0012F830 |00965419 返回到 00965419 來自 0096D340
0012F834 |00000080
0012F838 |0012F84C
0012F83C |00000004
0012F840 |0012F864
0012F844 |0012F870
0012F848 |00000078
0012F84C |00010001
0012F850 ]0012F884
可見第一次與第二次相同
F9,沒有下個中斷點,可見只有這兩處,上網搜索SO_LINGER選項,其描述如下:

/* 當連接中斷時,需要延遲關閉(linger)以保證所有資料都
   * 被傳輸,所以需要打開SO_LINGER這個選項 //註:大致意思就是說SO_LINGER選項用來設置當呼叫closesocket時是否馬上關閉socket
   * linger的結構在/usr/include/linux/socket.h中定義://註:這個結構就是SetSocketOpt中的Data的資料結構
   *  struct linger
   *  {
   *   int l_onoff;  /* Linger active */ //低字節,0和非0,用來表示是否延時關閉socket
   *   int l_linger; /* How long to linger */ //高字節,延時的時間數,單位為秒
   *  };
   *  如果l_onoff為0,則延遲關閉特性就被取消。如果非零,則允許套接頭延遲關閉。
   *  l_linger字段則指明延遲關閉的時間
   */
更具體的描述如下:
若設置了SO_LINGER(亦即linger結構中的l_onoff域設為非零,參見2.4,4.1.7和4.1.21各節),並設置了零超時間隔,則closesocket()不被阻塞立即執行,不論是否有排隊資料未發送或未被確認。這種關閉方式稱為「強制」或「失效」關閉,因為套接頭的虛電路立即被復位,且丟失了未發送的資料。在遠端的recv()呼叫將以WSAECONNRESET出錯。

若設置了SO_LINGER並確定了非零的超時間隔,則closesocket()呼叫阻塞工作行程,直到所剩資料發送完畢或超時。這種關閉稱為「優雅的」關閉。請注意如果套接頭置為非阻塞且SO_LINGER設為非零超時,則closesocket()呼叫將以WSAEWOULDBLOCK錯誤返回。

若在一個流類套接頭上設置了SO_DONTLINGER(也就是說將linger結構的l_onoff域設為零;參見2.4,4.1.7,4.1.21節),則closesocket()呼叫立即返回。但是,如果可能,排隊的資料將在套接頭關閉前發送。請注意,在這種情況下WINDOWS套接頭實現將在一段不確定的時間內保留套接頭以及其他資源,這對於想用所以套接頭的應用程式來說有一定影響。

這是網上的解釋
主要是影響close socket時的動作
知道了問題的原因,我們就動手修改一下試試
0012F80C 0096D367 /CALL 到 setsockopt 來自 0096D362
0012F810 00000078 |Socket = 78
0012F814 0000FFFF |Level = SOL_SOCKET
0012F818 00000080 |Option = SO_LINGER
0012F81C 0012F84C |Data = 0012F84C
0012F820 00000004 \DataSize = 4
0012F824 0000FFFF
0012F828 0012F848
0012F82C /0012F850
0012F830 |00965419 返回到 00965419 來自 0096D340
0012F834 |00000080
0012F838 |0012F84C
0012F83C |00000004
0012F840 |0012F864
0012F844 |0012F870
0012F848 |00000078
0012F84C |00010100 //原來的00010001表示延時256秒,將延時改為1秒
F9執行,用客戶端連接,連上後再離線,察看服務端連線,發現以前總是顯示為TIME_WAIT的連接,現在馬上消失了,至此問題解決
3、Radmin修改
Radmin的保護措施做的還是很不錯的,它的真正的執行程式是一個RES資源,主程式只負責將其解壓縮到記憶體中並執行,如果要修改就需要自己解壓縮,修改後再自己壓縮了放回去,具體怎麼做我就不說了:)
提示:如果要重複我一樣步驟,直接下setsocketopt是斷不下來的,先下jmp eax ,斷下來後F8一次,再下setsoketopt中斷點,好了,就提示這麼多了
__________________
http://bbsimg.qianlong.com/upload/01/08/29/68/1082968_1136014649812.gif
psac 目前離線  
送花文章: 3, 收花文章: 1631 篇, 收花: 3205 次