稍微学学逆向

FindKey

拿到文件顺手就往ida里拖,结果说是bin文件,所以还是乖乖将他拖到了kali里,file查看文件属性,是个pyc?(仿佛想到了某入群题)
将pyc还原成py文件
发现一个简单的加密过程(不过还是有点没太明白那个 +- & 的执行顺序)
直接上wp

1
2
3
4
5
6
7
8
9
10
11
import sys
lookup = [ 196, 153, 149, 206, 17, 221, 10, 217, 167, 18, 36, 135, 103, 61, 111, 31, 92, 152, 21, 228, 105, 191, 173, 41, 2, 245, 23, 144, 1, 246, 89, 178, 182, 119, 38, 85, 48, 226, 165, 241, 166, 214, 71, 90, 151, 3, 109, 169, 150, 224, 69, 156, 158, 57, 181, 29, 200, 37, 51, 252, 227, 93, 65, 82, 66, 80, 170, 77, 49, 177, 81, 94, 202, 107, 25, 73, 148, 98, 129, 231, 212, 14, 84, 121, 174, 171, 64, 180, 233, 74, 140, 242, 75, 104, 253, 44, 39, 87, 86, 27, 68, 22, 55, 76, 35, 248, 96, 5, 56, 20, 161, 213, 238, 220, 72, 100, 247, 8, 63, 249, 145, 243, 155, 222, 122, 32, 43, 186, 0, 102, 216, 126, 15, 42, 115, 138, 240, 147, 229, 204, 117, 223, 141, 159, 131, 232, 124, 254, 60, 116, 46, 113, 79, 16, 128, 6, 251, 40, 205, 137, 199, 83, 54, 188, 19, 184, 201, 110, 255, 26, 91, 211, 132, 160, 168, 154, 185, 183, 244, 78, 33, 123, 28, 59, 12, 210, 218, 47, 163, 215, 209, 108, 235, 237, 118, 101, 24, 234, 106, 143, 88, 9, 136, 95, 30, 193, 176, 225, 198, 197, 194, 239, 134, 162, 192, 11, 70, 58, 187, 50, 67, 236, 230, 13, 99, 190, 208, 207, 7, 53, 219, 203, 62, 114, 127, 125, 164, 179, 175, 112, 172, 250, 133, 130, 52, 189, 97, 146, 34, 157, 120, 195, 45, 4, 142, 139]
pwda = [ 188, 155, 11, 58, 251, 208, 204, 202, 150, 120, 206, 237, 114, 92, 126, 6, 42]
pwdb = [53,222,230,35,67,248 226,216,17,209,32,2,181,200,171,60,108]

flag = " "
for i in range (0,17):
flag += chr(lookup[i + pwdb[i]] - pwda[i] & 255 )

f = flag[::-1]
print(f)
  • 对od产生了深深的抗拒!! 除了打开会报毒,用起来整个电脑都卡炸了!! 差点gg

stheasy

没什么套路。。简单的加密就完事了,不过知道了ida可以使用shift+e 批量提取数据。。不用苦逼的一个个写了。

脚本:

1
2
3
4
5
6
7
8
9
10
11
a = [0x48,0x5d,0x8d,0x24,0x84,0x27,0x99,0x9f,0x54,0x18,0x1e,0x69,0x73,0x33,0x15,0x72,0x8d,0x33,0x24,0x63,0x21,0x54,0x0c,0x78,0x78,0x78,0x78,0x78,0x1b]
b = 'lk2j9Gh}AgfY4ds-a6QW1#k5ER_T[cvLbV7nOm3ZeX{CMt8SZo]U'
c = ''
for i in range(29):
c+= b[a[i]/3-2]

print c


$ python ctf2wp.py
kctf{YoU_hAVO-GOt-fLg_233333}

hello

还是简单的加密,mach-o 文件,ida分析一下, 还是简单的处理,直接上脚本

1
2
3
4
5
6
7
8
9
10
11
12
v2 = (0x20 >> 2 )^ 0x41

a=[ 0x41, 0x10, 0x11, 0x11, 0x1B, 0x0A, 0x64, 0x67, 0x6A, 0x68, 0x62, 0x68, 0x6E, 0x67, 0x68, 0x6B, 0x62, 0x3D, 0x65, 0x6A, 0x6A, 0x3D, 0x68, 0x04, 0x05, 0x08, 0x03, 0x02, 0x02, 0x55, 0x08, 0x5D, 0x61, 0x55, 0x0A, 0x5F, 0x0D, 0x5D, 0x61, 0x32, 0x17, 0x1D, 0x19, 0x1F, 0x18, 0x20, 0x04, 0x02, 0x12, 0x16,0x1E, 0x54, 0x20, 0x13, 0x14, 0x00, 0x00]

b = ''
for i in range(55):
b += chr((a[i]-2)^v2)
v2+=1
print b

$ python wp.py
vDDCTF-5943293119a845e9bbdbde5a369c1f50@didichuxing.com

软件密码破解-1

如果可以定位到关键函数的话其实还是挺简单的,ida全是函数无从下手,od 将程序跑起来,中文字符串搜索中能看到有个你赢了
到了地址之后,稍微往上翻便可以确定到关键判断的地方

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
01191C51  |. /7E 16         jle short CTF_100_.01191C69
01191C53 |. |B9 F8773001 mov ecx,CTF_100_.013077F8 ; 在此输入口令:
01191C58 |. |8BC3 mov eax,ebx
01191C5A |. |2BCB sub ecx,ebx
01191C5C |. |8D6424 00 lea esp,dword ptr ss:[esp]
01191C60 |> |8A1401 /mov dl,byte ptr ds:[ecx+eax]
01191C63 |. |3010 |xor byte ptr ds:[eax],dl
01191C65 |. |40 |inc eax
01191C66 |. |4E |dec esi
01191C67 |.^|75 F7 \jnz short CTF_100_.01191C60 --》 对输入的字符串分别xor

01191C69 |> \813B 1B1C1746 cmp dword ptr ds:[ebx],0x46171C1B
01191C6F |. 0F85 E7000000 jnz CTF_100_.01191D5C
01191C75 |. 817B 04 F4FD2>cmp dword ptr ds:[ebx+0x4],0x3020FDF4
01191C7C |. 0F85 DA000000 jnz CTF_100_.01191D5C
01191C82 |. 817B 08 B70C8>cmp dword ptr ds:[ebx+0x8],0x7E8E0CB7
01191C89 |. 0F85 CD000000 jnz CTF_100_.01191D5C
01191C8F |. 807B 0C 78 cmp byte ptr ds:[ebx+0xC],0x78
01191C93 |. 0F85 C3000000 jnz CTF_100_.01191D5C
01191C99 |. 807B 0D DE cmp byte ptr ds:[ebx+0xD],0xDE --》 xor后的值进行判断
01191C9D |. 0F85 B9000000 jnz CTF_100_.01191D5C

很明显就是xor之后比较一下就行了,直接上脚本

1
2
3
4
5
6
7
8
9
10
a = [0x28,0x57,0x64 ,0x6B ,0x93,0x8F ,0x65 ,0x51 ,0xE3 ,0x53 ,0xE4 ,0x4E ,0x1A ,0xFF]
b = [0x1b,0x1c,0x17,0x46,0xf4,0xfd,0x20,0x30,0xb7,0x0c,0x8e,0x7e,0x78,0xde]
c = ''
for i in range(len(a)):
c += chr(a[i]^b[i])

print c

$ python 1wp.py
3Ks-grEaT_j0b!

软件密码破解-2

一道比较有趣的逆向。

思路

开始看是先接收输入然后进入一个函数一通操作之后检查返回值是否为-1。进入该函数后可以看到把输入作为参数又起了一个子进程等待返回,然后往子进程的内存里面写了一些数据,然后又读了一些数据,之后对这些数据进行判断。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
*(_DWORD *)v22 = 0x148A4690;
*(_DWORD *)&v22[4] = 0xF14300E;
*(_DWORD *)&v22[8] = 0x75C83B41;
v22[12] = 0xF5u;
WriteProcessMemory(ProcessInformation.hProcess, (LPVOID)(Context.Eip - 1), v22, 0xDu, &NumberOfBytesWritten);
...
...

ReadProcessMemory(
ProcessInformation.hProcess,
DebugEvent.u.CreateThread.hThread,
Buffer,
DebugEvent.u.DebugString.nDebugStringLength,
&NumberOfBytesRead);
if ( Buffer[0] != 0x2B5C5C25 || Buffer[1] != 0x36195D2F || Buffer[2] != 0x7672642C )
result = -1;
else
result = -(Buffer[3] != 0x524E6680);

这样调试就有点无从下手了,直接重启一个程序加入参数,发现程序进入了另一个分支,然后调试单步继续走会碰到int 3使得中断等待父进程,所以父进程的WriteProcess应该就是写入这里。
手动把写入进去之后,发现是将输入的参数与’elcome to CFF test!’进行异或操作,在之后对每个字节的值加一后就返回了。

所以直接写下脚本就行

1
2
3
4
5
6
7
s = [0x25,0x5c,0x5c,0x2b,0x2F,0x5d,0x19,0x36,0x2c,0x64,0x72,0x76,0x80,0x66,0x4e,0x52]
ss = b'elcome to CFF test!'

flag = ''
for i in range(16):
flag += chr((ss[i])^(s[i]-1))
print(flag)

Classic Crackme 2

.net 逆向。

思路

需要用dnspy逆向,刚开始看挺吓人。直接开始调试,在入口处断点,发现run了个函数。

1
2
3
Application.EnableVisualStyles();
Application.SetCompatibleTextRenderingDefault(false);
Application.Run(new Wm@@9OrPgw\u0020d/p?i,N>l*h@Y!());

直接进入该函数,看到有加密环节,下个断点跟一下,发现就是使用AES对输入进行加密之后base64与一个字符串比较,写脚本即可

1
2
3
4
5
6
7
8
9
import base64
from Crypto.Cipher import AES

enc = "x/nzolo0TTIyrEISd4AP1spCzlhSWJXeNbY81SjPgmk="
key = "pctf2016"*4
aes = AES.new(key,AES.MODE_ECB)
flag = aes.decrypt(base64.b64decode(enc))

print flag

FindPass

apk调试

思路

正常的apk逆向发现一堆流程之后最后直接进行比较,发现与一串字符串相同即为flag,便尝试看能不能直接调试。

前面尝试了好久的android stdio与模拟器连接调试一直有各种各样的问题,(辣鸡as hhh

最后发现jeb也可以直接调试!!

之前尝试的时候对apk进行了可选调试的处理,不太清楚这里是否是必须的

1
2
3
4
5
6
7
针对release版本apk的处理:

反编译后
* AndroidManifest.xml 中寻找位置插入android:debuggable="true"
* MainActivity.smali 中OnCreate 附近写入invoke-static{},Landroid/os/Debug;->waitForDebugger()V

之后使用apktool 回编译为apk,签名

模拟器上安装该apk,连接后开启等待调试的包名

1
2
adb.exe connect 127.0.0.1:62001
adb.exe shell am start -D -n com.example.findpass/.MainActivity

jeb打开apk,ctrl+B下好断点,开启调试,可以直接搜索到模拟器上等待调试的应用,调试即可。

Fibonacci

2020.9.21 好久没做过题了,试图回归学习正轨~

知识点:java转exe程序逆向

运行提示我 Java Runtime Environment not valid,查了下发现是jre有问题,装了个新的就可以运行了。也可以知道这是java转的exe。

ida打开发现找不到关键函数也没有相关字符串,想来java转的exe应该不是对源函数进行转义的。相关java打包成exe主要操作为将jvm一起打包进去,最后运行时仍然相当于在jvm的基础上运行java程序。

找个exe2jar的程序,按方法在文件夹先运行设置环境变量,再运行源程序,会生成dump.jar文件,使用jd-gui查看该文件,得到一个Fibonacci类。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
package top.phrack.ctf.Fibonacci;

import java.io.PrintStream;
import java.util.Scanner;

public class Fibonacci
{
private static void heheda()
{
String bb = new String(b.x);
String cb = new String(b.y);
String m = hello(cb, bb);
}

public static void main(String[] args)
{
System.out.println("来让我们玩一个数列游戏:");
System.out.println("a[0]=0,a[1]=1");
System.out.println("a[2]=1,a[3]=2");
System.out.println("a[4]=3,a[5]=5");
System.out.println("..............");
System.out.println("请计算a[100000000000000]:");
Scanner scan = new Scanner(System.in);
String read = scan.nextLine();
read = read;
System.out.println("答案错误!!");
}

private static String hello(String aaa, String bbb)
{
int[] iS = new int[256];
byte[] iK = new byte[256];
for (int i = 0; i < 256; i++) {
iS[i] = i;
}
int j = 1;
for (short i = 0; i < 256; i = (short)(i + 1)) {
iK[i] = ((byte)bbb.charAt(i % bbb.length()));
}
j = 0;
for (int i = 0; i < 255; i++)
{
j = (j + iS[i] + iK[i]) % 256;
int temp = iS[i];
iS[i] = iS[j];
iS[j] = temp;
}
int i = 0;
j = 0;
char[] iInputChar = aaa.toCharArray();
char[] iOutputChar = new char[iInputChar.length];
for (short x = 0; x < iInputChar.length; x = (short)(x + 1))
{
i = (i + 1) % 256;
j = (j + iS[i]) % 256;
int temp = iS[i];
iS[i] = iS[j];
iS[j] = temp;
int t = (iS[i] + iS[j] % 256) % 256;
int iY = iS[t];
char iCY = (char)iY;
iOutputChar[x] = ((char)(iInputChar[x] ^ iCY));
}
return new String(iOutputChar);
}
}

发现主函数根本没有校验函数,hello函数应该是RC4加密,heheda函数是调用了类b里面的两个变量进行了RC4,但是没dump出类b,因为类b中没用方法,e2j中使用的Java Agent监控法无法监控到。

关于对jar2exe程序的解包教程相关文件 下载