REVERSE-PRACTICE-BUUCTF-26
- [FlareOn6]FlareBear
- [SUCTF2018]babyre
- [GKCTF2020]WannaReverse
- [FlareOn4]greek_to_me
[FlareOn6]FlareBear
apk文件,模拟器上运行,创建一个小熊,有三种方式交互,分别为“吃饭”,“篮球”以及“清理”
jadx-gui打开该apk,在com.fireeye.flarebear.FlareBearActivity中搜索flag,有个"danceWithFlag"
调用danceWithFlag的条件是isEcstatic返回真,去到isEcstatic,要判断三个变量的值
有get(State),对应的就有set(State),来到set的地方,都是在原有的基础上加上传入的参数
看看谁调用了change方法,有三个地方调用,分别是feed,play,clean,正好对应了那三种交互方式
不同的交互方式对三个State的影响不同,由传入的参数决定
使用python的z3库解方程组,知道8次feed,4次play,2次clean
from z3 import *
feed=Int('feed')
play=Int('play')
clean=Int('clean')
s=Solver()
s.add(10*feed+(-2)*play+0*clean==72)
s.add(2*feed+4*play+(-1)*clean==30)
s.add(-1*feed+(-1)*play+6*clean==0)
if s.check():print(s.model())
# [clean = 2, play = 4, feed = 8]
8次feed,4次play,2次clean,顺序不用管,交互完即可得到flag
[SUCTF2018]babyre
exe程序,运行后提示了flag的格式,要求输入key,无壳,ida分析
交叉引用字符串“Please Input Key:”来到sub_7FF739422460函数
主要的逻辑为,读取输入的key,key对0x10000取模,然后进入循环给v6赋值,最后打印v6
由于知道了flag的格式为"SUCTF{xxxxxxxxxxxxxxx}",写脚本爆破key,key正确时的输出即为flag
#include<stdio.h>
char v4_v5[]= {0x02, 0x03, 0x02, 0x01, 0x04, 0x07, 0x04, 0x05, 0x0A, 0x0B,
0x0A, 0x09, 0x0E, 0x0F, 0x0C, 0x0D, 0x10, 0x13, 0x10, 0x11,
0x14, 0x17, 0x16, 0x13, 0x1C, 0x19, 0x1E, 0x1F, 0x1C, 0x19,
0x1A, 0x1F, 0x24, 0x21, 0x22, 0x27, 0x24, 0x21, 0x22, 0x23,
0x28, 0x29, 0x2E, 0x2B, 0x24, 0x2D, 0x26, 0x2F, 0x38, 0x31,
0x3A, 0x3B, 0x34, 0x3D, 0x3E, 0x37, 0x30, 0x39, 0x32, 0x3B,
0x3C, 0x35, 0x36, 0x37, 0x48, 0x49, 0x42, 0x42, 0x44, 0x44,
0x46, 0x47, 0x48, 0x49, 0x4A, 0x4A, 0x4D, 0x4D, 0x4F, 0x4E,
0x50, 0x50, 0x52, 0x53, 0x55, 0x54, 0x56, 0x57, 0x59, 0x59,
0x5A, 0x5B, 0x5C, 0x5D, 0x5E, 0x5E, 0x60, 0x60, 0x63, 0x63,
0x64, 0x65, 0x67, 0x67, 0x69, 0x69, 0x6B, 0x6B, 0x6C, 0x6D,
0x6E, 0x6E, 0x70, 0x70, 0x72, 0x73, 0x74, 0x75, 0x77, 0x77,
0x78, 0x79, 0x7B, 0x7B, 0x7D, 0x7D, 0x7F, 0x7F, 0x81, 0x81,
0x83, 0x83, 0x8C, 0x8D, 0x8E, 0x8F, 0x88, 0x89, 0x8A, 0x8B,
0x8C, 0x8D, 0x8E, 0x87, 0x98, 0x91, 0x92, 0x93, 0x94, 0x95,
0x96, 0x97, 0x98, 0x99, 0x9A, 0x9A, 0x9C, 0x9C, 0x9E, 0x9E,
0xA0, 0xA0, 0xA2, 0xA2, 0xA4, 0xA4, 0xA6, 0xA6, 0xA8, 0xA8,
0xAA, 0xAA, 0xAC, 0xAC, 0xAE, 0xAE, 0xB0, 0xB1, 0xB2, 0xB3};
void main()
{int key = 0;for (; key < 0x10000; key++){char v6[31] = {0};v6[30] = 8;while (v6[30]){--v6[30];int v9;int v10;for (int j = 22; j; v6[j] |= v10 << v6[30]){v9 = v4_v5[22 * v6[30] + --j];v10 = (v9 >> ((key>> (2 * v6[30])) & 3)) & 1;}}if (v6[0] == 'S'&&v6[1] == 'U'&&v6[2] == 'C'&&v6[3] == 'T'&&v6[4] == 'F'&&v6[5]=='{'&&v6[21]=='}'){printf("key=%d\n", key);for (int j = 0; j < 22; j++){printf("%c", v6[j]);}printf("\n");}}
}
/*
key=12345
SUCTF{Flag_8i7244980f}
*/
[GKCTF2020]WannaReverse
勒索病毒程序,压缩包里有四个文件
无论运行哪个exe,由提示点击"Decrypt"按钮,都会得到RSA私钥
ida分析WannaReverse.exe,交叉引用字符串"encrypto success!“来到sub_543220函数
启动clickme.exe,用0~9的十位数字生成一个32位的动态的AES密钥,然后进入sub_542D00函数进行加密
分析sub_542D00函数,首先打开flag.txt文件流,获取文件大小,读取文件内容
从第147行到第174行,完成了对动态AES密钥的RSA加密
RSA加密的公钥在rdata段可以找到
往下走,这个for循环完成了对flag.txt文件内容的AES加密
继续向下走,将WannaReverse、经过RSA加密的32位AES密钥、经过AES加密的flag.txt文件内容写入flag.txt.Encry文件,也就是压缩包里的那个文件
已知RSA的私钥和公钥,从flag.txt.Encry文件中取出经RSA加密的AES密钥,使用在线工具(https://oktools.net/rsa)解出程序使用的动态AES密钥,为"30776159143604297789676442413079”
使用010 editor抠出经AES加密的flag的密文,写脚本解AES即可得到flag
from Crypto.Cipher import AES
from Crypto.Util.number import long_to_bytes
key="30776159143604297789676442413079"
cipher_data=\
"5C BC EA 89 BA 2B 18 27 79 3F 13 0A 8A 97 B4 9B\
CD 78 9B D8 35 92 05 45 4C 22 A5 69 37 EB 6E 2B\
0E BD 84 0F 91 61 38 F6 F1 BA 99 19 41 72 07 91\
F0 26 68 06 61 26 5C 20 35 DD CF FC 77 57 54 81\
F2 F2 E4 AF BF A2 1D 29 AE 6C 08 3B 76 1B 66 B8\
FE 72 CB D6 94 C3 D5 6A E7 0C 7A 28 DC BC AC 80"
cipher_str="0x"
for c in cipher_data:if c!=' ':cipher_str+=c
cipher=long_to_bytes(int(cipher_str,16))
aes=AES.new(key)
print(aes.decrypt(cipher).decode('utf-16'))
#flag{385fa869-3046-44ee-9d30-c03551273867}
[FlareOn4]greek_to_me
exe程序,运行后不能直接输入,无壳,ida分析
start->sub_401008,sub_401121函数监听本机的2222端口,接收信息存到buf,do循环做SMC,要用到接收到的buf,if语句决定发回的内容
sub_401121函数,监听2222端口,接收一个char类型的数据
不知道应发送的正确的char类型数据是多少,爆破,可知应发送的数据为0xa2
import os
import socket
ip = '127.0.0.1'
port = 2222
for i in range(255):os.startfile("D:\\ctfdownloadfiles\\greek_to_me.exe")s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)s.connect((ip, port))s.send(chr(i))data = s.recv(1024)s.close()if 'Congratulations' in data:print(data)print ("%x" % i)break
"""
Congratulations! But wait, where's my flag?
a2
"""
在sub_sub_401008的if语句处下断点,先让exe程序跑起来,发送0xa2给程序
import sys
import os
import socket
ip = '127.0.0.1'
port = 2222
s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
s.connect((ip, port))
s.send(chr(0xa2))
s.close()
停下后,F8单步向下,来到这个地方,填入的字符即为flag