Pwn-CTF 2018红帽杯redhat GameServer题目writeup

开始前的例行叨叨:

学pwn萌新,欢迎交流赐教~



先放一波题目:

我传了github上 pwn2就是题目了。( 若有侵权,请博客留言立马删除)

https://github.com/staticStr/ForCTF/blob/master/pwn2



来看看这个程序是做什么用的

功能很简单,输入名字,职业,就会问你是否要修改,填Y修改,写一个新的进去。

ida打开分析一波,顺手把变量名能改就改了,分析看图吧。



开始想办法溢出

从图里看到了溢出点,是read函数的参数nbytes可控,溢出s变量。


那如何控制nbytes呢?

nbytes是snprintf函数的返回值,我们看一下snprintf这个函数。


snprintf这个函数用来格式化字符串,把name和occ会填入%s %s的位置中,拼成字符串,赋给s

若拼好的字符串长度大于第二个参数限定的0x100,返回值就会变成预计写入的长度。

也就是说,若字符串把name和occ拼进去后变成了0x200长度,那么snprintf的返回值就会是0x200,若出错返回-1。

那么可以控制输入的名字和职业,控制nbytes的长度了。



那么第二个问题:

需要多长才能溢出read函数呢?


具体的需要本地搭建后用语句测试了。

但大概猜一下,预期的变量&s的长度是sp+7

下一个变量v2是sp+107

之间隔了0x100也就是256个长度,那想要溢出至少要read256长度<

### 非栈上格式化字符串漏洞概述 在CTF比赛的PWN类别中,格式化字符串漏洞是一种常见的安全漏洞,通常出现在使用不安全的格式化函数(如`printf`、`sprintf`等)时。如果程序允许用户直接控制格式化字符串参数,而未进行适当的验证和过滤,则可能导致攻击者利用该漏洞读取或写入内存数据。 在栈上的格式化字符串漏洞利用较为常见,而非栈上格式化字符串漏洞则涉及对堆内存或其他非栈内存区域的利用。这类漏洞通常更具挑战性,但也提供了更多的攻击面。 ### 利用方法 非栈上格式化字符串漏洞的利用主要依赖于对格式化字符串中特殊格式符的使用,尤其是`%n`。`%n`的作用是将当前已经输出的字符数写入指定的指针位置。通过精心构造格式化字符串,攻击者可以实现任意地址写入(Arbitrary Write)。 在非栈上场景中,通常需要找到一个可以控制的指针,指向堆内存或其他可写区域。例如,攻击者可以通过泄露堆地址,然后利用`%n`将数据写入堆中的特定位置。这种方法常用于覆盖函数指针或全局偏移表(GOT)中的条目,从而实现控制流劫持。 ```c // 示例代码,展示不安全的格式化字符串使用 #include <stdio.h> void vulnerable_function(char *user_input) { printf(user_input); // 不安全的格式化字符串使用 } int main(int argc, char **argv) { if (argc > 1) { vulnerable_function(argv[1]); } return 0; } ``` 在上述示例中,如果攻击者能够控制`user_input`的内容,则可以构造特定的格式化字符串来触发漏洞。例如,攻击者可以输入类似`%x%x%x%n`的字符串,试图读取栈上的数据并写入特定地址。 ### 防御方法 为了防止非栈上格式化字符串漏洞的利用,可以采取以下几种防御措施: 1. **避免使用不安全的格式化函数**:尽量使用带有显式参数的格式化函数,如`fprintf`、`snprintf`等,并确保格式字符串是静态常量,而不是用户可控的输入。 2. **输入验证和过滤**:对用户输入进行严格的验证和过滤,确保输入中不包含任何格式化字符(如`%`)。可以通过白名单机制来限制输入内容。 3. **地址空间布局随机化(ASLR)**:启用ASLR可以增加攻击者预测内存地址的难度,从而降低漏洞利用的成功率。 4. **堆内存保护**:使用现代编译器提供的堆内存保护机制,如堆栈保护(Stack Canaries)、地址随机化等,以增加攻击者利用堆漏洞的难度。 5. **代码审计和静态分析**:定期进行代码审计和静态分析,查找并修复潜在的安全漏洞。使用静态分析工具可以帮助识别不安全的格式化字符串使用。 6. **运行时检测**:在程序运行时检测格式化字符串的使用情况,及时发现并阻止异常行为。 ### 示例:修复不安全的格式化字符串使用 ```c // 修复后的代码,使用安全的格式化字符串使用方式 #include <stdio.h> void safe_function(char *user_input) { printf("%s", user_input); // 使用安全的方式处理用户输入 } int main(int argc, char **argv) { if (argc > 1) { safe_function(argv[1]); } return 0; } ``` 在修复后的代码中,通过使用`%s`格式化符并显式传递用户输入,避免了用户输入直接作为格式化字符串的风险。 ### 总结 非栈上格式化字符串漏洞的利用虽然较为复杂,但通过精心构造的格式化字符串和内存操作,攻击者仍然可以实现严重的攻击效果。因此,在开发过程中,必须采取有效的防御措施,确保程序的安全性。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值