VNCTF2024 RE yun WP

动态调试血的教训

不过这题比较麻烦,native层没有x86架构,不能用虚拟机跑,得用真机,而且有的真机还装不上,动调贼麻烦。

那就静态分析

jadx可以看到一些简单的字符串判断逻辑

IDA逆一下so文件(注意用7.7打开,8.3打开没有生成ARM的伪代码的插件

JNI_OnLoad 是 Java Native Interface (JNI) 中的一个特定函数,它允许开发者在加载本地库(如 .so 或 .dll 文件)时执行一些初始化操作。这个函数在 Java 虚拟机(JVM)加载本地库时自动调用。

在 JNI_OnLoad 函数中,你可以执行一些一次性初始化任务,比如注册本地方法、设置本地引用等。这对于确保本地库的正确运行至关重要。

需要注意的是,JNI_OnLoad 函数是可选的,如果你的本地库不需要任何特殊的初始化操作,你可以省略这个函数。但是,如果你的本地库需要注册本地方法或执行其他初始化任务,那么实现 JNI_OnLoad 函数是很有用的。

查看JNI_OnLoad初始化函数

似乎是一些初始化的内容,最后返回一个1FB44的地址,看一下汇编

进行了一些地址的加载并调用了sub_1E9C0函数,点进去看一下

是异或加密,修改了类似密文的数据

c0 = [0x5D, 0x55, 0x75, 0x46, 0x5B, 0x67, 0x66, 0x0B, 0x73, 0x67, 0x7D, 0x09, 0x5C, 0x51, 0x76, 0x46, 0x65, 0x55, 0x75, 0x47, 0x5E, 0x52, 0x0F, 0x46, 0x5B, 0x78, 0x71, 0x49, 0x72, 0x0C, 0x6D, 0x4E, 0x70, 0x78, 0x6E, 0x0F, 0x5A, 0x6B, 0x7D, 0x4F, 0x5B, 0x77, 0x4F, 0x50, 0x72, 0x67, 0x6A, 0x4B, 0x3F]
c1 = ''
for i in range(0x31):c0[i] ^= c0[0x30]c1 += chr(c0[i]&0xff)
print("crypto: ",c1)
#crypto:  bjJydXY4LXB6cnIyZjJxam0ydGNvM3RqOGQ0eTBpdHpoMXUt

查询函数引用定位到了sub_1FA24

给出了地址和密钥两个参数

unk_4D0DE = [0x48, 0x42, 0x4F, 0x49, 0x1E, 0x71, 0x41, 0x2E]
name = ''
for i in range(8):unk_4D0DE[i] ^= unk_4D0DE[7]name += chr(unk_4D0DE[i]&0xff)
print("name: ",name)
#name:  flag0_ounk_4D0EC = [0x47, 0x23, 0x05, 0x0E, 0x19, 0x0E, 0x40, 0x03, 0x0E, 0x01, 0x08, 0x40, 0x3C, 0x1B, 0x1D, 0x06, 0x01, 0x08, 0x54, 0x46, 0x35, 0x6F]
sign = ''
for i in range(22):unk_4D0EC[i] ^= unk_4D0EC[21]sign += chr(unk_4D0EC[i]&0xff)
print("sign: ",sign)
#sign:  (Ljava/lang/String;)Z

一个类似于函数名的东西,另一个是某种签名

xor还有另一个引用,似乎是修改了aVnvn字符串

原本字符串内容是VNVN,不过这里经过了xor修改

这里的伪代码看起来令人疑惑,看一下汇编就很清晰了

W8寄存器里依次入栈了0x4F, 0x3C, 0x7F, 0x3D, 0x36, 然后与索引为5-1=4的那个位置的值异或,得到修改后的字符串(考虑到大小端序,脚本是反过来写的)

avn = [0x4F, 0x3C, 0x7F, 0x3D, 0x36]
avnvn = ''
for i in range(1,5):avn[i] ^= avn[0]avnvn += chr(avn[i]&0xff)
print("avnvn: ",avnvn)
#avnvn:  s0ry

由此该地址前两个参数就分析出来了,看看第三个函数指针

16行 显然是一个字符串的比较

14行 的函数里呈现了复杂的加密过程

末尾有base64的迹象

重点就是中间的主要加密部分,实际上是希尔加密

希尔密码(加密、解密、破解)-CSDN博客文章浏览阅读2w次,点赞6次,收藏58次。希尔密码的加密、解密与破解简介希尔密码是运用基本矩阵论原理的替换密码,由Lester S. Hill在1929年发明。每个字母当作26进制数字:A=0, B=1, C=2… 一串字母当成n维向量,跟一个n×n的矩阵相乘,再将得出的结果模26。(注意用作加密的矩阵(即密匙)在 必须是可逆的,否则就不可能解码。只有矩阵的行列式和26互质,才是可逆的。)例子用希尔密码对明文串 x = ecnu 进行加密,密钥矩阵:加密密文向量 = 明文向量 * 密钥矩阵 (mod 26)1.先将明文串对应英文字_希尔密码https://blog.csdn.net/Secret_1943/article/details/110674955

先把输入的字母数字变成索引保存成一系列数字

然后每四个数一组,组成一系列2*2的明文矩阵

然后生成aVnvn密钥矩阵,正好里面有四个字符(s0ry)

最后将明文矩阵与密钥矩阵做乘法,得到密文矩阵(由于索引长度是37个字符,所以最后取mod37)

然后再把得到的索引转化为字符n2ruv8-pzrr2f2qjm2tco3tj8d4y0itzh1u-

最后base64加密成bjJydXY4LXB6cnIyZjJxam0ydGNvM3RqOGQ0eTBpdHpoMXUt

所以需要求个逆矩阵,不过直接z3爆也可以

#yun wp
unk_4D0DE = [0x48, 0x42, 0x4F, 0x49, 0x1E, 0x71, 0x41, 0x2E]
name = ''
for i in range(8):unk_4D0DE[i] ^= unk_4D0DE[7]name += chr(unk_4D0DE[i]&0xff)
print("name: ",name)
#name:  flag0_ounk_4D0EC = [0x47, 0x23, 0x05, 0x0E, 0x19, 0x0E, 0x40, 0x03, 0x0E, 0x01, 0x08, 0x40, 0x3C, 0x1B, 0x1D, 0x06, 0x01, 0x08, 0x54, 0x46, 0x35, 0x6F]
sign = ''
for i in range(22):unk_4D0EC[i] ^= unk_4D0EC[21]sign += chr(unk_4D0EC[i]&0xff)
print("sign: ",sign)
#sign:  (Ljava/lang/String;)Zavn = [0x4F, 0x3C, 0x7F, 0x3D, 0x36]
avnvn = ''
for i in range(1,5):avn[i] ^= avn[0]avnvn += chr(avn[i]&0xff)
print("avnvn: ",avnvn)
#avnvn:  s0ryc0 = [0x5D, 0x55, 0x75, 0x46, 0x5B, 0x67, 0x66, 0x0B, 0x73, 0x67, 0x7D, 0x09, 0x5C, 0x51, 0x76, 0x46, 0x65, 0x55, 0x75, 0x47, 0x5E, 0x52, 0x0F, 0x46, 0x5B, 0x78, 0x71, 0x49, 0x72, 0x0C, 0x6D, 0x4E, 0x70, 0x78, 0x6E, 0x0F, 0x5A, 0x6B, 0x7D, 0x4F, 0x5B, 0x77, 0x4F, 0x50, 0x72, 0x67, 0x6A, 0x4B, 0x3F]
c1 = ''
for i in range(0x31):c0[i] ^= c0[0x30]c1 += chr(c0[i]&0xff)
print("crypto: ",c1)
#crypto:  bjJydXY4LXB6cnIyZjJxam0ydGNvM3RqOGQ0eTBpdHpoMXUt#解base64: n2ruv8-pzrr2f2qjm2tco3tj8d4y0itzh1u- (36位)
#0x6e,0x32,0x72,0x75,0x76,0x38,0x2d,0x70,0x7a,0x72,0x72,0x32,0x66,0x32,0x71,0x6a,0x6d,0x32,0x74,0x63,0x6f,0x33,0x74,0x6a,0x38,0x64,0x34,0x79,0x30,0x69,0x74,0x7a,0x68,0x31,0x75,0x2d#参考了sln_1550师傅的代码
from z3 import *
s = Solver()
flag = [BitVec('x%d' % i, 16) for i in range(36)] #设个flag用z3爆
tmp=[0]*4 #每个矩阵2*2
key='s0ry'
table='abcdefghijklmnopqrstuvwxyz1234567890-'
res='n2ruv8-pzrr2f2qjm2tco3tj8d4y0itzh1u-'
for i in range(2):for j in range(2):tmp[2*i+j]=table.index(key[2*i+j]) #生成密钥矩阵
ret=[0]*36
for i in range(len(flag)//2):for j in range(2):for k in range(2):ret[i*2+j]+=flag[i*2+k]*tmp[k*2+j] #flag矩阵乘密钥矩阵=密文矩阵
for i in range(36):s.add(And(flag[i]>=0,flag[i]<37)) #索引范围s.add(ret[i]%37==table.index(res[i]))
if s.check() != sat:print ("error!")
if s.check() == sat: #z3求解m = s.model()
print(''. join(table[m[flag[i]].as_long()%37] for i in range(36))) #索引再转字符
#75531c14-8825-44ed-a9ec-74d47d5cb76b

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.hqwc.cn/news/610455.html

如若内容造成侵权/违法违规/事实不符,请联系编程知识网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

高阶流程图(SIPOC)

SIPOC高阶流程图是一种流程映射和改进方法&#xff0c;它使用可视化的方式描述一个或多个流程的输入和输出。SIPOC是五个单词的首字母缩写&#xff0c;分别代表供应商&#xff08;Suppliers&#xff09;、输入&#xff08;Inputs&#xff09;、过程&#xff08;Processes&#…

C++初阶:反向迭代器

reverse_iterator的封装实现 Reverse_Iterator.h namespace xx {// 所有容器的反向迭代器// 迭代器适配器template<class Iterator, class Ref, class Ptr>struct Reverse_iterator{Iterator _it;typedef Reverse_iterator<Iterator, Ref, Ptr> Self;Reverse_iter…

更卷的2024,如何把短剧产品做的更好?| TopOn出海干货

2024年3月14日&#xff0c;TopOn 携手快出海、Cloudflare、SensorTower、Google作举办的《娱乐新纪元——探索短剧出海无限机遇》线下研讨交流会圆满落幕。此次会议不仅为短剧出海从业者们提供了一个深入交流的平台&#xff0c;现场嘉宾们的分享更深入探讨了短剧出海的机遇与挑…

负荷预测 | Matlab基于TCN-LSTM-Attention单输入单输出时间序列多步预测

目录 效果一览基本介绍程序设计参考资料 效果一览 基本介绍 1.负荷预测 | Matlab基于TCN-LSTM-Attention单输入单输出时间序列多步预测&#xff1b; 2.单变量时间序列数据集&#xff0c;采用前12个时刻预测未来96个时刻的数据&#xff1b; 3.excel数据方便替换&#xff0c;运行…

全国贫困县DID数据(2008-2022年)

数据来源&#xff1a;国W院扶贫开发领导小组办公室 时间跨度&#xff1a;2008-2022年 数据范围&#xff1a;各县域 数据指标 年份 县域名称 所属地市 所属省份 县域代码 是否贫困县(是为1&#xff0c;否为0) 参考文献&#xff1a; [1]马雯嘉,吴茂祯.从全面脱贫到乡村振兴…

zookeeper解析

目录 zookeeper定义 zookeeper定义 Zookeeper是一个开源的分布式的&#xff0c;为分布式框架提供协调服务的Apache项目 Zookeeper工作机制 zookeeper从设计模式角度来理解&#xff1a; 是一个基于观察者模式设计的分布式服务管理框架&#xff0c;它负责存储和管理大家都关心…

@Transactional失效的10种场景

Transactional失效的场景都有哪些呢&#xff1f;本章节针对Transactional的问题&#xff0c;做以下总结整理。 1、同一个类中&#xff0c;方法内部调用事务失效 2、事务方法被final、static修饰 3、当前类没有被Spring管理 4、非public修饰的方法&#xff08;存在版本差异&a…

HCIE考试第三题:业务容器化及割接

文章目录 业务容器化及割接题目和做题步骤如下3.1业务容器化及割接3.1创建CCE集群solo3.2创建NAT网关3.2.1申请EIP3.2.2创建NAT网关3.2.3添加SNAT规则3.3创建节点池3.3.1 创建namespace3.3.2创建节点池3.4 安装命令行工具kubectl3.4.1上传kubectl3.4.2上传kubeconfig配置文件3.…

【InternLM 实战营第二期笔记】使用茴香豆搭建你的RAG智能助理

RAG RAG是什么 RAG&#xff08;Retrieval Augmented Generation&#xff09;技术&#xff0c;通过检索与用户输入相关的信息片段&#xff0c;并结合外部知识库来生成更准确、更丰富的回答。解决 LLMs 在处理知识密集型任务时可能遇到的挑战, 如幻觉、知识过时和缺乏透明、可追…

Java日期正则表达式(附Demo)

目录 前言1. 基本知识2. Demo 前言 对于正则匹配&#xff0c;在项目实战中运用比较广泛 原先写过一版Python相关的&#xff1a;ip和端口号的正则表达式 1. 基本知识 对于日期的正则相对比较简单 以下是一些常见的日期格式及其对应的正则表达式示例&#xff1a; 年-月-日&a…

每日一题(力扣)---插入区间

官方网址&#xff1a;. - 力扣&#xff08;LeetCode&#xff09; 题目&#xff1a; 给你一个 无重叠的 &#xff0c;按照区间起始端点排序的区间列表 intervals&#xff0c;其中 intervals[i] [starti, endi] 表示第 i 个区间的开始和结束&#xff0c;并且 intervals按照 st…

C语言中的数据结构--链表的应用2(3)

前言 上一节我们学习了链表的应用&#xff0c;那么这一节我们继续加深一下对链表的理解&#xff0c;我们继续通过Leetcode的经典题目来了解一下链表在实际应用中的功能&#xff0c;废话不多说&#xff0c;我们正式进入今天的学习 单链表相关经典算法OJ题4&#xff1a;合并两个…