Jarvis OJ 题库练习
Findthekey
文件为pyc, 用uncompyle6
进行反编译, 得到python源码如下
# uncompyle6 version 3.7.4 |
则解密脚本如下:
lookup = [ |
得flag: PCTF{PyC_Cr4ck3r}
CrackMe
.Net架构, 用dnspy反编译, 找到目标函数
则解密脚本为
import base64 |
得到flag: PCTF{Ea5y_Do_Net_Cr4ck3r}
CrackMe2
.Net架构, 用dnspy反编译,找到加密函数
设断点进行调试,追溯到函数如下
则函数逻辑如下:
输入进行AES加密再进行base64编码,最终跟一串常量进行对比 |
常量可由动态调试得到
from Crypto.Cipher import AES |
运行得flag: PCTF{Dot_Net_UnPack3r_yoo}
Fibinacii
本题为用jar2exe打包的程序。jar2exe将java和jvm打包生成exe,从而可以在没有JAVA的机器上直接运行,原理是通过JNI的接口,创建JVM来执行封装的java代码,与exe4j将jar导出生成临时文件不同,jar2exe是在内部执行的,因此无法直接找到临时文件来反编译
用jwscan.jar可以检查出程序用什么打包
D:\CTF\Games\Exam\Jarvis\Re\Fibonacci>java -jar JWScan\jwscan.jar Fibonacci.exe |
归根到底依旧是Java, 那么仍然是通过JVM来执行字节码的JAVA, 而Jae2Exe的打包有三种等级, No Hiding, No Encryption
, Hidden Archive
和 Hidden Archive + Encrypted Class Names
本题应该属于后两种
根据夜影师傅的博客,找到提取经过Jar2Exe编译加密的源代码 教程1, 原理是通过java提供的javaagent接口,使得每个方法执行之前都先执行dump函数, 缺点就是没有被执行的方法就不会被dump了。
下载https://github.com/slavemaster/e2j的e2j后在所在目录下设置set JAVA_TOOL_OPTIONS=-javaagent:e2j-agent.jar
即可
然后运行需要的程序,显示如下
D:\CTF\Games\Exam\Jarvis\Re\Fibonacci>Fibonacci.exe |
目录下便产生了e2j-xxx.dump.jar, 拖入jd-gui
得到所在类,但类b中因为没有方法,所以没有被JavaAgent抓到,因此得到的类是不完整的
package top.phrack.ctf.Fibonacci; |
后根据http://reverseengineeringtips.blogspot.com/2014/12/unpacking-jar2exe-21-extracting-jar.html知道java代码被存放在RCDATA数据中, 因此只要找到RCDATA的数据位置,在程序运行过程中设置访问断点,当程序解密时找到解密后的代码位置即可得到相应的java代码
通过CFF_Explorer查到RCDATA的HEX数据
通过x64dbg直接搜索对于的特征值,于0x477398
找到
设置内存访问断点,运行到解密循环
根据代码逻辑大致可猜测R10指向的内存是JAVA的字节码,而R11就是范围了
使程序解密完成,即运行到0x000000000041E713
, 使用scylla插件Dump内存, 保存为1.jar
使用binwalk进行分离文件
➜ Desktop binwalk -e 1.jar |
其中有两个文件为标准的class文件
➜ Desktop file _1.jar.extracted/* |
将这俩修改后缀名为*.class
拖进jd-gui进行查看,其中c7dce9e9.class
可以得到b类
package top.phrack.ctf.Fibonacci; |
那么完整代码就有了,这题跟斐波那契数列一点关系都没有,cv工程师上线,写个java代码编译运行
import java.util.Scanner; |
运行得flag: PCTF{1ts_not_5c2ipt_Chall3nge}
本题参考:
软件密码破解-1
程序打开来7千多个函数,找不到入口,大致看了一下,发现有个地方很可疑, 这里由于动态调试过,因此基址会有出入(起始地址0x00B01000)
按Alt + A
修改为 Unicode C-style(16 bits)
得到中文 你赢了
找到函数0x00B01BB0
, 猜测校验及加密如下
其中byte_C777F8是生成出来的,可用动态调试得到,但是本题用了反调试,这里直接暴力绕过,即jz => jmp
即可
text:00B01BE8 jmp short loc_B01BF2 ; Keypatch modified this from: |
则在调试过程中可得byte_C777F8,最终解密脚本如下
s = [0x28, 0x57, 0x64, 0x6B, 0x93, 0x8F, 0x65, 0x51, 0xE3, 0x53, |
得到flag:3Ks-grEaT_j0b!