启动机器,给的IP和端口为143.110.169.131:32543
直接浏览器打开。
![image-20230716163655704](/../images/HTB%E9%9D%B6%E6%9C%BA-LoveTok/image-20230716163655704.png)
这个机器给了源码,下载下来看看
源码的结构为
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19
| . ├── assets │ ├── cyberpunk.gif │ └── favicon.png ├── controllers │ └── TimeController.php ├── index.php ├── models │ └── TimeModel.php ├── Router.php ├── static │ ├── css │ │ └── main.css │ ├── js │ │ ├── koulis.js │ │ └── main.js │ └── koulis.gif └── views └── index.php
|
index.php中调用了Router,通过Router中的new函数构造TimeController中的index函数。
1 2
| $router = new Router(); $router->new('GET', '/', 'TimeController@index');
|
TimeController.php代码如下
1 2 3 4 5 6 7 8 9 10
| <?php class TimeController { public function index($router) { $format = isset($_GET['format']) ? $_GET['format'] : 'r'; $time = new TimeModel($format); return $router->view('index', ['time' => $time->getTime()]); } }
|
通过get请求接受format参数,并赋值给$format。如果获取不成功则默认赋值字符”r”。
然后传递给TimeModel。
TimeModel.php代码如下
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17
| <?php class TimeModel { public function __construct($format) { $this->format = addslashes($format);
[ $d, $h, $m, $s ] = [ rand(1, 6), rand(1, 23), rand(1, 59), rand(1, 69) ]; $this->prediction = "+${d} day +${h} hour +${m} minute +${s} second"; }
public function getTime() { eval('$time = date("' . $this->format . '", strtotime("' . $this->prediction . '"));'); return isset($time) ? $time : 'Something went terribly wrong'; } }
|
查看TimeModel.php的代码,对传入的$format使用addslashes进行转义。随后拼接到eval函数中。所以这里形成了一条污点流,source是$_GET[‘format’],sink是eval。
但是由于addslashes会转义双引号,因此无法直接闭合eval中的双引号,这里要想办法绕过。