2020网鼎杯朱雀组逆向Tree 及其思考

2024-03-08 19:48

本文主要是介绍2020网鼎杯朱雀组逆向Tree 及其思考,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

Tree

IDA打开,先做信息收集:无壳,有符号表,函数窗口发现了未被调用过的可疑函数outtree
在这里插入图片描述

string一下发现了疑似密文的一串字符串
在这里插入图片描述

找到main函数
main函数main函数

checkflag规定输入的数据在‘0’~‘e’之间,并将其作为16进制数转换为4位二进制。
并且给出了flag的模板,可以知道flag长度为42
在这里插入图片描述

checkflag处理完之后将_root内存放的数据作为参数传给__Z5parseP4node
__Z5parseP4node接收一个名为node*的参数,猜想可能是一棵树的根节点。
动调可以发现root内的存放的数据为0x406530
在这里插入图片描述
在这里插入图片描述

函数内部逻辑很清晰,将上面函数得到的二进制串glockflag进行类似查表的操作,控制流程实际上有意义的只有‘1’和‘0’两种路径。
如果v3中的数据满足(*v3 > 96 && *v3 <= 122),就将该数据赋值给result,然后将v3还原成循环开始之前的值a1。显然,结合题目名字,这是一种二叉树查表的操作。

至于是什么二叉树,就需要将它还原出来。
好在程序预留给我们了一个现成的函数outtree,该函数和__Z5parseP4node一样需要传入一个node*参数。
在这里插入图片描述简单的前序遍历二叉树代码。什么是二叉树的前序遍历这里有一张图可以很直观地表现出来。
前序遍历

知道了程序的逻辑和解题思路,只需要在程序运行时在适当的位置修改eip到函数内部,必要时还需要手动修改函数的参数和其它寄存器。
这里我选择的修改点是在call __Z5parseP4node的前一行代码处,执行完mov [esp], eax

在这里插入图片描述在这里插入图片描述

跟进函数,可以发现函数的参数的并不是_root,查看汇编发现,ebp多了4个字节
在这里插入图片描述在这里插入图片描述

把ebp从0x0061FE4C修改为0x0061FE48,函数即可正常执行。结果如下:
在这里插入图片描述在这里插入图片描述

画出二叉树,直接写出解密脚本即可。

在这里插入图片描述

table={'y':'0000','b':'00010','q':'00011','g':'0010','f':'0011','j':'010','w':'01100','p':'01101','x':'011101','d':'0111010','i':'01111011','k':'01111','s':'100','z':'1010','n':'1011','c':'11000','t':'110010','e':'110011','h':'1101','o':'11100','l':'1110100','u':'11101010','r':'111010110','a':'111010111','m':'111011','v':'1111'}ciphertext='zvzjyvosgnzkbjjjypjbjdvmsjjyvsjx'
bin_result=''
for each in ciphertext:bin_result+=table[each]
i=0
while(i<len(bin_result)):temp=bin_result[i:i+4] #每4位二进制一组i+=4result=str(hex(int(temp,2)))result=result[2:]   #'0xa'-->'a'print(result,end='')

得出afa41fc8574f12481a849d7f7120f89c,按照题目给出的格式写出flag即可。

flag{afa41fc8-574f-1248-1a84-9d7f7120f89c}

PS:

如果这道题没有给出outtree函数?

首先可以考虑对密文进行逐字节爆破,密文中每个英文字母对应着一个二进制数,那就把加密过程复现一遍,但并不意味着每4位2进制就对应了一位flag,因为尽管checkflag函数把输入的数变成了4位二进制,但是__Z5parseP4node函数在解析二进制数据查表的时候,并不是按照固定的4位二进制对应一个字符的规则来查表的,具体多少位二进对应flag中的一个字符是由二叉树本身的结构决定的。(这里有点绕,师傅们可以自己用上面的二叉树举个例子。

第一种思路:使用idapython复现二叉树查表算法+爆破

root=0x00406530#根结点地址
secret='zvzjyvosgnzkbjjjypjbjdvmsjjyvsjx'def encrypt(way):a=rootresult=''bin_s='{:010b}'.format(way) #这里设成10位二进制高位补0,起初设成8位导致a和r没有出结果for each in bin_s:     #模拟parse函数if(each=='1'):a=idc.Dword(a+12)result+='0'elif(each=='0'):a=idc.Dword(a+16)result+='1'if(idc.Dword(a)>96 and idc.Dword(a) <=122):return result+':'+chr(idc.Dword(a))return 0L=[]
for each in range(1024):    #开爆,奥里给爆就完了if(encrypt(each)!=0):L.append(encrypt(each))Table=list(set(L))
print(Table)

结果:
在这里插入图片描述
[‘1111:v’, ‘111011:m’, ‘011100:x’, ‘11101010:u’, ‘00010:b’, ‘11100:o’, ‘01101:p’, ‘110011:e’, ‘0000:y’, ‘1110100:l’, ‘0111010:d’, ‘110010:t’, ‘01111:k’, ‘111010111:a’, ‘1101:h’, ‘1010:z’, ‘111010110:r’, ‘0111011:i’, ‘0011:f’, ‘1011:n’, ‘01100:w’, ‘100:s’, ‘010:j’, ‘00011:q’, ‘0010:g’, ‘11000:c’]

得出
‘zvzjyvosgnzkbjjjypjbjdvmsjjyvsjx’ 对应的二进制字符串为

‘10101111101001000001111111001000010101110100111100010010010010000001101010000100100111010111111101110001001000001111100010011100’

后续方法同上,直接每4位二进制输出对应的hex可以了。

第二种思路:

个人认为这种办法比较麻烦,从根节点0x00406530开始,自己手写一个outtree把二叉树输出出来,得出二叉树后,后续步骤同上。

PPS

原来的博客因为是自己搭的,被透穿了,以后就准备在这里写东西了。
芜湖

明日计划:复盘白虎组RE题目

这篇关于2020网鼎杯朱雀组逆向Tree 及其思考的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/788198

相关文章

usaco 1.3 Mixing Milk (结构体排序 qsort) and hdu 2020(sort)

到了这题学会了结构体排序 于是回去修改了 1.2 milking cows 的算法~ 结构体排序核心: 1.结构体定义 struct Milk{int price;int milks;}milk[5000]; 2.自定义的比较函数,若返回值为正,qsort 函数判定a>b ;为负,a<b;为0,a==b; int milkcmp(const void *va,c

【编程底层思考】垃圾收集机制,GC算法,垃圾收集器类型概述

Java的垃圾收集(Garbage Collection,GC)机制是Java语言的一大特色,它负责自动管理内存的回收,释放不再使用的对象所占用的内存。以下是对Java垃圾收集机制的详细介绍: 一、垃圾收集机制概述: 对象存活判断:垃圾收集器定期检查堆内存中的对象,判断哪些对象是“垃圾”,即不再被任何引用链直接或间接引用的对象。内存回收:将判断为垃圾的对象占用的内存进行回收,以便重新使用。

树(Tree)——《啊哈!算法》

树 什么是树?树是一种特殊的图,不包含回路的连通无向树。 正因为树有着“不包含回路”这个特点,所以树就被赋予了很多特性。 一棵树中的任意两个结点有且仅有唯一的一条路径连通。一棵树如果有n个结点,那么它一定恰好有n-1条边。在一棵树中加一条边将会构成一个回路。 一棵树有且只有一个根结点。 没有父结点的结点称为根结点(祖先)。没有子结点的结点称为叶结点。如果一个结点既不是根结点也不是叶

Android逆向(反调,脱壳,过ssl证书脚本)

文章目录 总结 基础Android基础工具 定位关键代码页面activity定位数据包参数定位堆栈追踪 编写反调脱壳好用的脚本过ssl证书校验抓包反调的脚本打印堆栈bilibili反调的脚本 总结 暑假做了两个月的Android逆向,记录一下自己学到的东西。对于app渗透有了一些思路。 这两个月主要做的是代码分析,对于分析完后的持久化等没有学习。主要是如何反编译源码,如何找到

转:android ro.debuggable属性调试修改(mprop逆向)

android ro属性调试修改(mprop逆向)      大家都知道如果需要调试android 的程序,以下两个条件满足一个就行。第一是apk的配置文件内的AndroidManifest.xml的 android:debuggable=”true”,第二就是/default.prop中ro.debuggable=1。两种方式第一种通常是解包添加属性再打包,随着加壳软件以及apk校验等,容易出

226 Invert Binary Tree

//226 Invert Binary Tree//算法思路:主要使用递归算法public class Solution {public TreeNode invertTree(TreeNode root) {//1 出口 空节点if (root==null)return null;//2 递归 调用自己TreeNode left = root.left;TreeNode right = ro

某里227逆向分析

声明: 该文章为学习使用,严禁用于商业用途和非法用途,违者后果自负,由此产生的一切后果均与作者无关。 本文章未经许可禁止转载,禁止任何修改后二次传播,擅自使用本文讲解的技术而导致的任何意外,作者均不负责,若有侵权,请联系作者立即删除! 前言 这次会简单的讲解阿里227版本滑块参数n的逆向分析流程以及简单的补环境,如果有疑问可以在评论区交流讨论,我看到会及时回复的,另外,有需要可联系我。 一

【编程底层思考】详解Java的JUC多线程并发编程底层组件AQS的作用及原理

Java中的AbstractQueuedSynchronizer(简称AQS)是位于java.util.concurrent.locks包中的一个核心组件,用于构建锁和其他同步器。AQS为实现依赖于FIFO(先进先出)等待队列的阻塞锁和相关同步器提供了一套高效、可扩展的框架。 一、AQS的作用 统一同步状态管理:AQS提供了一个int类型的成员变量state,用于表示同步状态。子类可以根据自己

【MyBatis学习14】MyBatis的逆向工程生成代码

1. 什么是逆向工程 mybatis的一个主要的特点就是需要程序员自己编写sql,那么如果表太多的话,难免会很麻烦,所以mybatis官方提供了一个逆向工程,可以针对单表自动生成mybatis执行所需要的代码(包括mapper.xml、mapper.java、po..)。一般在开发中,常用的逆向工程方式是通过数据库的表生成代码。 2. 使用逆向工程 使用mybatis的逆向工程,需要导入逆向

js逆向--cai招网

js逆向--cai招网 一、寻找加密入口1、抓包2、关键字搜索寻找加密入口 二、调试js三、python代码实现 一、寻找加密入口 1、抓包 目标数据来源网址为:https://search.bidcenter.com.cn/search?keywords=%E5%85%AC%E5%85%B1%E4%BD%8F%E5%AE%85,打开开发者工具进行抓包。 目标响应数据被加密。