SZTU NEW STAR CTF 游记

@2023年11月19日 2.7k字 §游记 #CTF
目录
  • 前言
  • Write Up
  • 总结
  • 前言

    在比赛前一天被 LZY 拉来玩的,之前对 CTF 啥的没有任何经验,索性也没做啥准备,提前把比赛可能用到的一些工具下载准备之后就啥也没干了,毕竟之后看 CTF 玩的东西可真够杂的。

    然后不知道为啥他给惯了个及其抽象的队名:ACM?CTF!

    Write Up

    0x01 不知道你喜不喜欢吃培根

    题目.txt

    babbaaabaaababbaaabaabbbaabbaaaabaabaabbabbbabaababbaabbaabbbabaa

    思路

    一眼看过去只有 a 和 b 两种字符,所以想到应该换成二进制 0 和 1。

    后来看到题目说培根,所以找到了培根密码,直接就解码出来了:

    welcometosztu

    0x02 你也喜欢福尔摩斯吗?

    题目.txt

    .. .-.. --- ...- . -.-- --- ..-

    思路

    一眼莫尔斯电码:

    iloveyou

    0x03 brainfuck

    题目.txt

    ++++++++++[>+++++++>++++++++++>+++>+<<<<-]>++.>+.+++++++..+++.>++.<<+++++++++++++++.>.+++.------.--------.>+.>.

    思路

    找一个 bf 在线运行就能得到 flag:

    Hello World!

    然后一直提交错误,直到主办方说空格要换成下划线。

    这根本就是不是啥惯例,我还用半角减号替代空格呢,强烈建议题目写清楚。


    0x04 Vigenère

    题目.txt

    iltg{fcy33a4h-a620-856t-a990-9563eb1x5142}

    思路

    题目写的很清楚了,维吉尼亚加密,暴力尝试密钥把前四个字母解码成 flag 就行,最后尝试得到密钥为 data

    flag{ccf33a4e-a620-856a-a990-9563bb1e5142}

    0x05 babyRSA

    babyRSA.py

    from Crypto.Util.number import *
    from flag import flag
    
    def gen_prime(n):
      res = 1
    
      for i in range(15):
        res *= getPrime(n)
    
      return res
    
    
    if __name__ == '__main__':
      n = gen_prime(32)
      e = 65537
      m = bytes_to_long(flag)
      c = pow(m,e,n)
      print(n)
      print(c)
    # 17290066070594979571009663381214201320459569851358502368651245514213538229969915658064992558167323586895088933922835353804055772638980251328261
    # 14322038433761655404678393568158537849783589481463521075694802654611048898878605144663750410655734675423328256213114422929994037240752995363595
    

    思路

    显然题目已知 RSA 公钥和密文,要求爆破明文。

    已知密钥的计算如下:

    de1(modφ(n))d\equiv e^{-1}(\mathrm{mod}\enspace \varphi(n))

    由于 nn 是由 15 个质数相乘得到的,所以先找个 网站nn 分解质因数,得到 p0,p1,,p14p_0,p_1,\cdots,p_{14}

    由欧拉函数知识可知:

    φ(n)=(p01)(p11)(p141)\varphi(n)=(p_0-1)(p_1-1)\cdots(p_{14}-1)

    所以解密代码如下:

    import gmpy2
    from Crypto.Util.number import *
    from functools import reduce
    
    n = 17290066070594979571009663381214201320459569851358502368651245514213538229969915658064992558167323586895088933922835353804055772638980251328261
    e = 65537
    c = 14322038433761655404678393568158537849783589481463521075694802654611048898878605144663750410655734675423328256213114422929994037240752995363595
    
    p = [2217990919, 2338725373, 2370292207, 2463878387, 2706073949, 2794985117, 2804303069, 2923072267, 2970591037, 3207148519, 3654864131, 3831680819, 3939901243, 4093178561, 4278428893]
    
    phi = reduce(lambda x, y: x * (y - 1), p, 1)
    d = gmpy2.invert(e, phi)
    m = pow(c, d, n)
    
    print(long_to_bytes(m))

    解得:

    flag{us4_s1ge_t0_cal_phI}

    0x06 Fence

    题目.txt

    fet_lbriysyaysr_dogCeuneu{ce}

    思路

    由题目可知使用栅栏加密,暴力解算密钥为 5,故答案为:

    flag{cybersecurity_needs_you}

    0x07 好像是有点奇怪

    题目.txt

    flag就是下面这个,不过它看起来真的好奇怪:
    4C4A575851324332474E324547574B594A5A57465136534647464D4443544C584C4159464D324444474E57474D564A524F424B564D57425148553D3D3D3D3D3D

    思路

    看见全大写 + 数字,一眼 URL 编码,于是加入百分号分隔解码得:

    LJWXQ2C2GN2EGWKYJZWFQ6SFGFMDCTLXLAYFM2DDGNWGMVJROBKVMWBQHU======

    又是全大写 + 数字,后面还有等于号,于是尝试 Base32,解码得:

    ZmxhZ3tCYXNlXzE1X1MwX0Vhc3lfU1pUVX0=

    现在出现小写了,所以可以尝试 Base64:

    flag{Base_15_S0_Easy_SZTU}

    0x08 小猫咪

    flag.jpg

    (此处应有一张 Pussy Cat 图片,但是我太懒了)

    思路

    直接检查图片属性 - 备注,发现答案已赫然在目:

    flag{little_cat_15_cute}

    0x09 给阿姨来一杯卡布奇诺

    challenge.png

    (不知名的女性.png)

    思路

    没想出来,看着图片干着急。


    0x0A 很难的flag

    (一堆文件)

    (唯一有用的只有 task.py)

    思路

    打开 task.py,flag 已经写好了:

    msg = 'Hahaha, Hastad\'s method don\'t work on this. Flag is flag{fa0f8335-ae80-448e-a329-6fb69048aae4}.'

    0x0B 一个空白的Word

    新建Word文档.docx

    (非常干净)

    思路

    打开显示隐藏字符,你就能得到一串新佛曰:

    新佛曰:毘諸隸僧降吽諸陀摩隸僧缽薩願毘耨咤陀願羅咤喃修願宣亦宣寂叻寂阿是吽阿塞尊劫毘般毘所聞降毘咒塞尊薩咒毘所若降般斯毘嚴毘嚴波斯迦毘色毘波嚴毘喃念若修嘚般毘我毘如毘如囑囑

    解码得:

    flag{Th1s_F0_1s_s00_Cyp3r_495586e3df3a}

    0x0C 加密

    test.php

    <?php
      function encrypt($str)
      {
        $cryptedstr = "";
        srand(3284724);
        for ($i =0; $i < strlen($str); $i++)
        {
          $temp = ord(substr($str,$i,1)) ^ rand(0, 255);
          while(strlen($temp)<3)
          {
            $temp = "0".$temp;
          }
          $cryptedstr .= $temp. "";
        }
        return base64_encode($cryptedstr);
      }
    ?>

    题目.txt

    MDEzMjE5MDAyMTg0MTUzMjQwMTQ0MDc3MjUzMDk2MTc1MTUzMTE4MTg4MDEwMDA2MTg4MDA0MjM4MDI1MTA3MTU4MTc5MTM4

    思路

    根据 PHP 代码可知 flag 被套上一个伪随机生成器给每个字符进行了异或操作,最后转码成 Base64 输出。

    所以只需要根据代码思路写出反流程就行:

    <?php
    $enc = 'MDEzMjE5MDAyMTg0MTUzMjQwMTQ0MDc3MjUzMDk2MTc1MTUzMTE4MTg4MDEwMDA2MTg4MDA0MjM4MDI1MTA3MTU4MTc5MTM4';
    $enc = base64_decode($enc);
    
    $arr = str_split($enc, 3);
    $dec = '';
    
    srand(3284724);
    for ($i = 0; $i < count($arr); $i++) {
      $dec .= chr(intval($arr[$i]) ^ rand(0, 255));
    }
    
    echo($dec);
    

    但是这题非常坑的地方是 srand 伪随机生成器在不同 PHP 版本下输出是不同的,本题只有在 5.x 版本下能得到正解,7.x 和 8.x 返回的都是乱码。

    答案如下:

    flag{you_are_successful}

    0x0D 当emoji遇上你

    flag.txt

    🙃💵🌿🎤🚪🌏🐎🥋🚫😆😍👁☺🐍🔪💵🐎😀🦓🖐🌿🐅🍵📂🍵🌪🔪🐍🌏🚫📂💵🚫😁🙃🐅🚫🛩🔄🕹🖐🏎🌏😊🐍📮ℹ📂🍌☀🎈✖😡📮🌊✅🔬🚹🕹😆🏹📂💵🕹💧ℹ😀🔄🚫🍍👑🍌🤣❓😀📮👣😎⌨☺🤣🖐🍎🏎🐘😀🗒🗒

    secret.txt

    平等和谐平等友善自由平等自由平等平等平等友善敬业平等富强自由富强法治和谐法治和谐平等法治和谐富强法治文明公正自由平等诚信平等公正敬业法治和谐平等诚信平等法治敬业公正诚信平等法治平等平等友善敬业公正和谐公正民主公正友善爱国平等友善敬业公正自由公正友善敬业平等诚信平等公正敬业法治自由

    思路

    secret.txt 可知使用了()编码,解码如下:

    SZTU_P@ssW0rd_is_you_can_do_it

    但是由于不知道主办方到底用了哪款 Emoji 编码器,所以这题没解出来,Emoji 编码这种没有统一标准的东西建议不要用来出题。


    0x0E foremost分离

    10.xls

    (打不开的玩意)

    思路

    由于题目提示,先 binwalk 看看文件藏了啥:

    DECIMAL       HEXADECIMAL     DESCRIPTION
    --------------------------------------------------------------------------------
    0             0x0             Zip archive data, at least v2.0 to extract, compressed size: 19, uncompressed size: 17, name: xl/charts/flag.txt
    67            0x43            Zip archive data, at least v1.0 to extract, name: docProps/
    106           0x6A            Zip archive data, at least v2.0 to extract, compressed size: 404, uncompressed size: 872, name: docProps/app.xml
    ...(以下省略一大堆文件)

    所以直接 foremost 分解,得到了一个 zip 文件,观察 zip 文件结构,显然这是一个 excel 文件,但是这并不重要。

    注意到 zip 文件的路径 xl/charts/ 下有一个文件 flag.txt,打开得:

    flag{M9eVfi2Pcs#}

    0x0F 别想着破解密码

    attachme.xls

    (一个带了密码的 excel)

    思路

    懒得找软件破解,LZY 提出直接 Hex 搜索 flag,然后就在 H50550 找到了:

    00050550 3F 51 2B 51 03 73 4A 12 52 27 66 6C 61 67 20 00 ?Q+Q.sJ.R'flag .
    00050560 69 73 20 68 65 72 65 20 00 43 54 46 7B 6F 66 66 is here .CTF{off
    00050570 69 00 63 65 5F 65 61 73 79 5F 00 63 72 61 63 6B i.ce_easy_.crack
    00050580 65 64 7D 00 OD 0A 00 00 00 00 00 00 00 00 00 00 ed}.............

    把文本处理一下就得到 flag 了:

    CTF{office_easy_cracked}

    0x10 很小的n

    题目.txt

    c = 28767758880940662779934612526152562406674613203406706867456395986985664083182
    n = 73069886771625642807435783661014062604264768481735145873508846925735521695159
    e = 65537

    思路

    显然又是知道公钥和密文爆破明文,直接找一个在线 RSA 解密网站就完成了:

    wctf2020{just_@_piece_0f_cak3}

    0x11 Caesar_cipher

    题目.txt

    mshn{121j6kl9-5i41-l729-1895-hm1k4076m9m2}

    思路

    典中典凯撒密码,暴力枚举得到密钥 7,答案如下:

    flag{121c6de9-5b41-e729-1895-af1d4076f9f2}

    0x12 低解密指数

    低解密指数攻击.py

    from secret import flag
    from Crypto.Util.number import *
    
    p = getPrime(1024)
    q = getPrime(1024)
    
    d = getPrime(32)
    e = inverse(d, (p-1)*(q-1))
    n = p*q
    m = bytes_to_long(flag)
    
    c = pow(m,e,n)
    
    print(c)
    print(e)
    print(n)
    
    # c = 6755916696778185952300108824880341673727005249517850628424982499865744864158808968764135637141068930913626093598728925195859592078242679206690525678584698906782028671968557701271591419982370839581872779561897896707128815668722609285484978303216863236997021197576337940204757331749701872808443246927772977500576853559531421931943600185923610329322219591977644573509755483679059951426686170296018798771243136530651597181988040668586240449099412301454312937065604961224359235038190145852108473520413909014198600434679037524165523422401364208450631557380207996597981309168360160658308982745545442756884931141501387954248
    # e = 8614531087131806536072176126608505396485998912193090420094510792595101158240453985055053653848556325011409922394711124558383619830290017950912353027270400567568622816245822324422993074690183971093882640779808546479195604743230137113293752897968332220989640710311998150108315298333817030634179487075421403617790823560886688860928133117536724977888683732478708628314857313700596522339509581915323452695136877802816003353853220986492007970183551041303875958750496892867954477510966708935358534322867404860267180294538231734184176727805289746004999969923736528783436876728104351783351879340959568183101515294393048651825
    # n = 19873634983456087520110552277450497529248494581902299327237268030756398057752510103012336452522030173329321726779935832106030157682672262548076895370443461558851584951681093787821035488952691034250115440441807557595256984719995983158595843451037546929918777883675020571945533922321514120075488490479009468943286990002735169371404973284096869826357659027627815888558391520276866122370551115223282637855894202170474955274129276356625364663165723431215981184996513023372433862053624792195361271141451880123090158644095287045862204954829998614717677163841391272754122687961264723993880239407106030370047794145123292991433
    

    思路

    显然又是知道公钥和密文爆破明文,依然是找一个在线 RSA 解密网站就完成了:

    flag{learn_some_continued_fraction_technique#dc16885c}

    0x13 这个压缩包的密码是?

    你可以的.rar

    (加密的 RAR 文件)

    思路

    题目给的提示是 4 位数密码,所以直接开 AAPR 破解,得到密钥 2563,解压得到 flag:

    ZmxhZ3s3MDM1NDMwMGE1MTAwYmE3ODA2ODgwNTY2MWI5M2E1Y30=

    再来一轮 Base64 得:

    flag{70354300a5100ba78068805661b93a5c}

    0x14 这个excel好像也很奇怪诶

    content_1700239619612.xlsx

    (一个填满了不可见字符的 excel 文档)

    思路

    对字符染色之后可以看出有的单元格是有加粗的,当时没想到怎么解密。


    0x15 网络抓包

    网络抓包.pcapng

    (一个可以被 wireshark 读取的抓包日志文件)

    题目.txt

    参考 网络抓包.pcapng  文件回答以下题目,给出正在进行Nmap扫描的计算机互联网协议地址?提示: 以IPV4格式给出答案,并包裹上flag{}

    思路

    直接用 wireshark 打开抓包日志,显然可以看出 192.168.186.132 在进行 nmap 扫描,所以答案为:

    flag{192.168.186.132}

    0x16 nmap扫描了几个

    题目.txt

    接上题(21题),有多少个 Nmap 扫瞄正在同时进行? 提示:以阿拉伯数字给出,答案依然包裹上flag{}

    思路

    不太明白啥叫有多少个 Nmap 扫描正在进行,所以一开始就一直在数在短时间内有多少次发送请求,数出来大概 10~14 个,所以每个都试了一下,结果都不对。

    结果网上说要数协议数量,看了看就只有 TCP 和 UDP,所以就写 2 试着交了一下,结果对了。太玄学了。

    flag{2}

    0x17 超能陆战队

    dabai.png

    (一张大白的图)

    思路

    LZY 的女朋友说这张图和网图相比缺失了下部分,可能被修改了高度,所以把 PNG 的高度数据调大了一倍,结果刚好显示了全图:

    flag{Hello_SZTU}

    直接改原题目的 flag,主办方可真够懒的。


    0x18 这个RAR的文件头好像

    24_这个RAR的文件头好像.rar

    (打不开的 RAR 文件)

    思路

    根据题目提示,十六进制查看 RAR 文件头:

    00000000 61 52 72 21 1A 07 01 00 94 E6 41 F6 0B 01 05 07 aRr!......A.....

    很明显不是 RAR 文件头,所以将它修复就能打开了:

    00000000 52 61 72 21 1A 07 01 00 94 E6 41 F6 0B 01 05 07 Rar!......A.....

    打开压缩包之后得到一个 word 文件,里面有一串不明所以的音符(当然也是隐藏文字):

    呀!一不小心把文档里的东西弄没了……
    
    
    
    
    ♭♯♪‖¶♬♭♭♪♭‖‖♭♭♬‖♫♪‖♩♬‖♬♬♭♭♫‖♩♫‖♬♪♭♭♭‖¶∮‖‖‖‖♩♬‖♬♪‖♩♫♭♭♭♭♭§‖♩♩♭♭♫♭♭♭‖♬♭‖¶§♭♭♯‖♫∮‖♬¶‖¶∮‖♬♫‖♫♬‖♫♫§=
    这都让你发现了,可是你能看懂吗?

    这是某种音符加密,经过一番寻找找到了对应的解码网站,解得:

    MRCTF{thEse_n0tes_ArE_am@zing~}

    0x19 Registration

    MinesweeperChampionshipRegistration.jar

    (一个简单的 Java 包)

    Description.txt

    Welcome to the Fifth Annual Flare-On Challenge! The Minesweeper World Championship is coming soon and we found the registration app. You weren't *officially* invited but if you can figure out what the code is you can probably get in anyway. Good luck!
    
    Hint:本题解出相应字符串后请用flag{}包裹,形如:flag{123456@flare-on.com}
    思路

    打开 Jar 弹出对话框要求输入密码,那么密码就是 flag 了。

    直接使用 JD-GUI 打开 Jar 文件,看到反编译代码:

    import javax.swing.JOptionPane;
    
    public class InviteValidator {
      public static void main(String[] args) {
        String response = JOptionPane.showInputDialog(null, "Enter your invitation code:", "Minesweeper Championship 2018", 3);
        if (response.equals("GoldenTicket2018@flare-on.com")) {
          JOptionPane.showMessageDialog(null, "Welcome to the Minesweeper Championship 2018!\nPlease enter the following code to the ctfd.flare-on.com website to compete:\n\n" + response, "Success!", -1);
        } else {
          JOptionPane.showMessageDialog(null, "Incorrect invitation code. Please try again next year.", "Failure", 0);
        }
      }
    }

    显然 flag 就是 equals 后面的内容:

    flag{GoldenTicket2018@flare-on.com}

    0x1A 神奇的gif

    题目.txt

    咦!这个文件怎么打不开?

    6.gif

    (打不开的 GIF 图)

    思路

    没有心思去分析了,改头、添头都试了,无济于事,不知道哪里出问题了,索性放弃了。

    总结

    最终成绩是 22/26,以 20 分的分差位居第二。

    还是非常有趣的,因为之前我也做过基于 Web 的解密小游戏,那种更加考验网络审计,像今天的比赛就比较考研对文件的各种处理还有编码学知识了。

    结果音频处理完全没用上。

    正在加载索引……