buu-reverse findit CSRe
buu-reverse-findit
关键代码
怎么提取jar可看:http://poilzero.sipc115.club/index.php/archives/72/
提取jar文件用jd-gui打开可以很容易找到这段关键代码
public void onClick(View param1View) {
char[] arrayOfChar1 = new char[17]; //0-16
char[] arrayOfChar2 = new char[38]; //
int i = 0;
while (true) {
String str;
if (i >= 17) {
if (String.valueOf(arrayOfChar1).equals(edit.getText().toString())) {
for (i = 0;; i++) {
if (i >= 38) { //i:0-37字符
str = String.valueOf(arrayOfChar2);
text.setText(str);
return;
}
if ((b[i] >= 'A' && b[i] <= 'Z') || (b[i] >= 'a' && b[i] <= 'z')) {
arrayOfChar2[i] = (char)(b[i] + 16);
if ((arrayOfChar2[i] > 'Z' && arrayOfChar2[i] < 'a') || arrayOfChar2[i] >= 'z')
arrayOfChar2[i] = (char)(arrayOfChar2[i] - 26);
} else {
arrayOfChar2[i] = b[i];
}
}
break;
}
} else {
if ((a[i] < 'I' && a[i] >= 'A') || (a[i] < 'i' && a[i] >= 'a')) {
str[i] = (char)(a[i] + 18);
} else if ((a[i] >= 'A' && a[i] <= 'Z') || (a[i] >= 'a' && a[i] <= 'z')) {
str[i] = (char)(a[i] - 8);
} else {
str[i] = a[i];
}
i++;
continue;
}
text.setText("答案错了肿么办。。。不给你又不好意思。。。哎呀好纠结啊~~~");
return;
}
}
});
使用androidkiller吧压缩包改.apk后缀后打开查到这两个字符串的定义(类汇编)
:array_0
.array-data 2
0x54s
0x68s
0x69s
0x73s
0x49s
0x73s
0x54s
0x68s
0x65s
0x46s
0x6cs
0x61s
0x67s
0x48s
0x6fs
0x6ds
0x65s
.end array-data
.line 23
nop
:array_1
.array-data 2
0x70s
0x76s
0x6bs
0x71s
0x7bs
0x6ds
0x31s
0x36s
0x34s
0x36s
0x37s
0x35s
0x32s
0x36s
0x32s
0x30s
0x33s
0x33s
0x6cs
0x34s
0x6ds
0x34s
0x39s
0x6cs
0x6es
0x70s
0x37s
0x70s
0x39s
0x6ds
0x6es
0x6bs
0x32s
0x38s
0x6bs
0x37s
0x35s
0x7ds
.end array-data
.end method
转换成字符
base=[0x54,0x68,0x69,0x73,0x49,0x73,0x54,0x68,0x65,0x46,0x6c,0x61,0x67,0x48,0x6f,0x6d,0x65]
code=""
for i in range(len(base)):
code+=chr(base[i])
print(code)
base=[0x70,0x76,0x6b,0x71,0x7b,0x6d,0x31,0x36,0x34,0x36,0x37,0x35,0x32,0x36,0x32,0x30,0x33,0x33,0x6c,0x34,0x6d,0x34,0x39,0x6c,0x6e,0x70,0x37,0x70,0x39,0x6d,0x6e,0x6b,0x32 ,0x38,0x6b,0x37,0x35,0x7d]
code=""
for i in range(len(base)):
code+=chr(base[i])
print(code)
输出
ThisIsTheFlagHome
pvkq{m164675262033l4m49lnp7p9mnk28k75}
逆向过程
怀疑是维吉尼亚密码(需要密钥),或者凯撒密码,因为没有找到对应的其他字符串作为密钥
使用ThisIsTheFlagHome作为密钥尝试解密得到wocy{e164675262033t4t49ejk7e9mhd28w75}
多次解密也不对,看来是凯撒密码了。
计算偏移
print(abs(0x70-ord('f')))
print(abs(0x76-ord('l')))
输出
10
10
使用10的偏移值解得flag{c164675262033b4c49bdf7f9cda28a75}
buu-reverse-[V&N2020 公开赛]CSRe
基本逻辑
程序直接运行报错了,打开IDA查看发现函数名是乱码的,怀疑加壳了
使用exeinfope查看
查到壳了,使用提示的解壳de4dot
.NET obf/license protector - for ver. < 5.0 - Unpack with : de4dot v3.1 2011-2014 de4dot@gmail.com - http://github.com/0xd4d/de4dot
由于虚拟机中没有对应工具,从网上下载
https://github.com/de4dot/de4dot
然后能够得到未加壳的本体
关键代码
前面已经得知是.net文件了,因此直接用dnspy打开不用IDA了
入口点
// C:\Users\15426\Desktop\reverse\buu\0_256_[V&N2020 公开赛]CSRe\CS-cleaned.exe
// CS_exe, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null
// 入口点: Class3.Main
// 时间戳: 5C80ED62 (2019/3/7 18:07:30)
找到主函数
// Token: 0x0600000F RID: 15 RVA: 0x00002374 File Offset: 0x00000574
private static void Main(string[] args)
{
if (!Class1.smethod_1())
{
return;
}
bool flag = true;
Class3 @class = new Class3();
string str = Console.ReadLine();
if (Class3.smethod_0("3" + str + "9") != "B498BFA2498E21325D1178417BEA459EB2CD28F8")
{
flag = false;
}
string text = Console.ReadLine();
string string_ = Class3.smethod_0("re" + text);
string text2 = @class.method_0(string_, "63143B6F8007B98C53CA2149822777B3566F9241");
for (int i = 0; i < text2.Length; i++)
{
if (text2[i] != '0')
{
flag = false;
}
}
if (flag)
{
Console.WriteLine("flag{" + str + text + "}");
}
}
第一部分调用到的相关函数,其实就是sha1(静态函数)
// Token: 0x0600000E RID: 14 RVA: 0x0000231C File Offset: 0x0000051C
public static string smethod_0(string string_0)
{
byte[] bytes = Encoding.UTF8.GetBytes(string_0);
byte[] array = SHA1.Create().ComputeHash(bytes);
StringBuilder stringBuilder = new StringBuilder();
foreach (byte b in array)
{
stringBuilder.Append(b.ToString("X2"));
}
return stringBuilder.ToString();
}
结合理解,第一部分就是验证sha1("3" + str + "9")==B498BFA2498E21325D1178417BEA459EB2CD28F8
第二部分调用到的相关函数(成员方法)
// Token: 0x0600000D RID: 13 RVA: 0x000022C8 File Offset: 0x000004C8
public string method_0(string string_0, string string_1)
{
string text = string.Empty;
char[] array = string_0.ToCharArray();
char[] array2 = string_1.ToCharArray();
int num = (array.Length < array2.Length) ? array.Length : array2.Length; //取小的长度
for (int i = 0; i < num; i++)
{
text += (int)(array[i] ^ array2[i]);
}
return text;
}
结合理解,也就是第二部分异或后结果是,而众所周知,只有相等的数异或才会等于零。
因此本质上第二部分就是验证sha1('re'+text)==63143B6F8007B98C53CA2149822777B3566F9241
逆向过程
分别逆sha1得到
- 314159=》1415
- return=》turn
因此flag为:flag{1415turn}