buu练题记录6-[WUSTCTF2020]level4

本文详细介绍了通过IDA分析一个ELF文件,发现其内部涉及到二叉树的中序和后序遍历。通过对代码的动态调试和模拟执行,作者成功还原了字符串的排列顺序,揭示了隐藏的CTF挑战的flag。此外,还提供了根据已知中序和后序遍历求前序遍历的代码实现,进一步解释了二叉树遍历的概念。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

0x00 查壳

image-20210415102931673

没有壳,发现是ELF文件,用IDA打开

0x01 IDA分析

直接看到main函数,总共就调用了init,type1,type2三个函数,也没有用户输入。所以放进虚拟机看看会输出什么

image-20210415103348006

输出两个字符串,显而易见顺序不一样:

image-20210415103640852

可以猜测的是type1和type2是两种不同的排序或者遍历方式。回到IDA再分析一下这三个函数:

image-20210415103855773

这里对 x 字符数组有一个赋值操作,需要注意的是,这里每次保存一个值都要增加24字节的地址,说明x可能不是常见的char或者int类型,(盲猜是结构体),然后再将之前的值传到x里面的其他相对比较奇怪的位置(其他结构体?)。


exp1

这里的赋值循序也是奇奇怪怪,就不是顺序的,所以我想看一下。动调了下,看了下内存,然后有了惊人的发现。因为动调只能一个字符一个字符的查看,所以写了个exp来还原当时的调用顺序:

Index = [0x11E8,0x1260,0x10F8,0x1110,0x1140,0x1230,0x1158,0x1098,0x1200,0x1188,0x1170,0x11B8,0x10B0,0x1080,0x1218,0x1278,0x10E0,0x11A0,0x1128,0x12A8,0x11D0,0x1248,0x10C8]
s = 'I{_}Af2700ih_secTS2Et_wr'

for i in Index:
    x = int((i-0x1080)/0x18)
    print(s[x],end='')
    
    #ctf2020{This_IS_A_7reE}

结果就是得到了flag。这里没有用到字符’w’,结合题目所以应该是wctf2020{This_IS_A_7reE}

然后这题就奇奇怪怪的结束了。哈哈哈哈哈哈哈哈哈哈红红火火恍恍惚惚。


回到IDA,还是继续看完这个题的其他部分:

image-20210415105630395

第一时间我还真没看出来这是二叉树的中序和后续遍历,不过看明白后就好办了。根据二叉树的两种遍历可以知道另一张遍历(中序例外)。

这里是已知中序和后序,求二叉树的前序遍历

exp2

#include <iostream>
#include <cstring>
using namespace std;

void preorder(string mid,string post,int len){
    int tail = 0;
    string mid1="";string post1="";
    string mid2="";string post2="";
    if(len)
	    printf("%c",post[len-1]);
    if(len>1){
        tail= mid.find(post[len-1]);
        mid1=mid.substr(0,tail);
        post1=post.substr(0,tail);
        mid2=mid.substr(tail+1,len-1-tail);
        post2=post.substr(tail,len-tail-1);//考虑分割后左右序列为空。
        preorder(mid1, post1, mid1.length());
        preorder(mid2, post2, mid2.length());
        
        
    }
   //find函数从左侧0索引开始,查找第一个出现的字符位置,如果查到,返回以0索引起始的位置;未查到,返回-1。
   //start所需的子字符串的起始位置。字符串中的第一个字符的索引为 0。
   //length在返回的子字符串中应包括的字符个数。
   //s.substr(pos, n)返回一个string,包含s中从pos开始的n个字符的拷贝
}
int main() {
    int len = 24;
	string mid ="2f0t02T{hcsiI_SwA__r7Ee}\0";
	string post="20f0Th{2tsIS_icArE}e7__w\0";    
    preorder(mid, post, len);
    return 0;
}

运行得到flag:

image-20210415112324183
### SQL注入基础知识 SQL注入是一种常见的网络安全漏洞,允许攻击者通过向应用程序提交恶意SQL语句来操纵数据库操作。这种攻击利用了程序未能正确处理用户输入的情况,从而可能造成敏感数据泄露、数据损坏或其他严重后果[^1]。 #### 攻击原理 SQL注入的核心在于攻击者能够通过特定字符(如单引号 `'` 或双引号 `"`),修改原始SQL查询的结构并执行未经授权的操作。例如,在登录表单中输入用户名为 `admin' --` 可能会关闭后续的部分SQL语法,导致非法访问成功[^2]。 --- ### 防御方法概述 针对SQL注入的风险,可以通过多种技术手段加以防范: #### 参数化查询 参数化查询是预防SQL注入最有效的方法之一。它强制区分SQL代码与动态传入的数据部分,即使输入包含危险字符也不会影响原有查询逻辑。以下是Python中的一个例子使用SQLite库实现参数绑定: ```python import sqlite3 conn = sqlite3.connect('example.db') cursor = conn.cursor() # 安全的方式传递变量给SQL命令 username = 'test_user' password = 'secure_password' query = "SELECT * FROM users WHERE username=? AND password=?" cursor.execute(query, (username, password)) results = cursor.fetchall() print(results) conn.close() ``` 上述代码片段展示了如何借助占位符(`?`)代替直接拼接字符串构建最终SQL指令,避免潜在风险。 #### 输入验证 除了采用参数化外,还应该实施严格的输入校验机制。这不仅限于简单的长度限制或者正则表达式匹配,还需要考虑业务场景下的合理性判断。比如对于电子邮件地址字段,则需确认其格式是否符合标准RFC规范;而对于整数型ID值,则要确保只接受纯数字形式。 #### 使用ORM框架 对象关系映射(Object Relational Mapping) 技术简化了开发者编写复杂SQL的过程,并内置了许多安全性保障措施。像Django ORM或Hibernate这样的高级抽象层自动实现了必要的转义功能,减少了手动犯错的机会[^3]。 #### Web应用防火墙(WAF) 部署WAF作为额外防线也是明智之举。这些设备位于客户端请求到达实际服务器之前的位置上,能够识别已知模式特征的可疑流量并将之拦截下来。然而需要注意的是,尽管它们提供了即时保护作用,但并不能完全替代良好的编程习惯和全面测试流程。 --- ### 工具推荐 为了更高效地定位可能存在隐患的地方,可以引入专门设计用来评估网站是否存在此类弱点的应用软件包。下面列举了几款流行的选择供参考: - **sqlmap**: 开源自动化渗透测试工具,支持大量自定义选项以便深入探索目标环境内的每一个角落。 - **Burp Suite Professional**: 商业版提供强大的代理监听能力配合手动作业完成更加精细粒度上的分析工作。 - **Nessus / OpenVAS**: 综合性漏洞管理解决方案的一部分,覆盖范围广泛不仅仅局限于单一类型的威胁类别。 ---
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值