【审计试题案例】
一、常见的题目类型
1、直接给出题目源码
2、源码泄露
二、HCTF 2018 Warmup
url二次编码绕过WAF
查看源代码发现有提示
source.php
hint.php
回到source.php,包含文件之前有三个校验
checkfile里先是一个白名单,传入的file就是里面的hint,判断是否为str类型和判断是否在白名单里
用mb_substr取问号之前的字符,取了字符后判断是否在白名单里,再进行url解码,再取问号之前的字符是否在白名单里
这个安全检查机制存在逻辑漏洞。它只检查了问号 ?之前的部分是否在白名单内。这意味着攻击者可以在白名单文件名后拼接路径遍历(…/) payload 来绕过检查。
漏洞原理:
攻击者传入 file=source.php?/…/…/…/…/fffflllllaaaaagggg
checkFile函数会截取问号前的内容:source.php
source.php在白名单中,所以安全检查通过。
但是,最终执行 include语句时,PHP 包含的完整路径是 source.php?/…/…/…/…/fffflllllaaaaagggg。
在PHP中,?在文件路径中会被解释为截断符。/…/…/…/…/fffflllllaaaaagggg这部分路径会成功地将目录向上遍历,最终包含系统根目录下的 fffflllllaaaaagggg文件。
三、0ctf 2016 piapiapia
打开后是一个登录框
源代码中也没有什么提示
这种一般都会有源码泄露,输入www.zip找到一个源码,也可以通过其他扫描器扫描目录
解压后的文件目录
config.php中有一个flag变量,可以猜测,flag是在这个文件中的
中目录中可以获取到有注册页,所以可以先注册一个
注册后登录需要更新信息,随便填写更新后跳转到新页面,这就是所有的功能
代码审计
源码泄露的题目一般考的都是反序列化,直接搜索反序列号函数
它会把传入的值进行反序列化
这里代码的功能是把profile值反序化后,读取里面的phone、email、name和photo其中,photo的位置有get_contents函数可以读取文件内容,由于之前观察到之前的config有flag值,就需要利用这里的函数读取config文件获取flag
这个profile是通过$user里面的show_profile函数通过username查询到的,user这里没有定义,那就是在包含的class.php文件中
class文件的末尾有一个user
调用了这个类的show_profile()
第一行filter函数是用来过滤的,进入函数后可以看到,会把关键词替换成hacker
后面定义了where变量,用户名为传入的值,查询后返回了查询到的结果,查询后如果返回为空则跳转更新数据页面
否则的话就反序列化获取,所以得找到控制photo输入的点
这些信息是在updata.php里面输入的,接着看
if($_POST['phone'] && $_POST['email'] && $_POST['nickname'] && $_FILES['photo']) {$username = $_SESSION['username'];if(!preg_match('/^\d{11}$/', $_POST['phone']))die('Invalid phone');if(!preg_match('/^[_a-zA-Z0-9]{1,10}@[_a-zA-Z0-9]{1,10}\.[_a-zA-Z0-9]{1,10}$/', $_POST['email']))die('Invalid email');if(preg_match('/[^a-zA-Z0-9_]/', $_POST['nickname']) || strlen($_POST['nickname']) > 10)die('Invalid nickname');$file = $_FILES['photo'];if($file['size'] < 5 or $file['size'] > 1000000)die('Photo size error');move_uploaded_file($file['tmp_name'], 'upload/' . md5($file['name']));$profile['phone'] = $_POST['phone'];$profile['email'] = $_POST['email'];$profile['nickname'] = $_POST['nickname'];