Android AES

附件

链接:https://pan.baidu.com/s/1AgYjnhu-KwWbpE37RDHnbg?pwd=1111
提取码:1111

考点:TEA AES

程序的主逻辑如下,输入经过aes加密和native内部的密文进行比较

进入lib查看,尽量每一个都看一下,因为不同架构IDA反编译的结果可能不一样

密文和密钥

很明显的tea加密 ,还有findcrypt也识别为TEA加密

关于arm架构的一些资料

知识点一:TEA加密

TEA 是一种常见的分组加密算法,密钥为 128 比特位,明文为 64 比特位,主要做了 32 轮变换,每轮变换中都涉及移位和变换。

识别方法为:TEA 算法中有一个固定的常数 0x9e3779b9 或者 0x61c88647

解题代码和TEA加解密源码

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
#include <stdio.h>
#include <stdint.h>
void encrypt(uint32_t *v, uint32_t *k)
{
uint32_t v0 = v[0], v1 = v[1], sum = 0, i;
uint32_t delta = 0x9e3779b9;
uint32_t k0 = k[0], k1 = k[1], k2 = k[2], k3 = k[3];
for (i = 0; i < 32; i++)
{
sum += delta;
v0 += ((v1 << 4) + k0) ^ (v1 + sum) ^ ((v1 >> 5) + k1);
v1 += ((v0 << 4) + k2) ^ (v0 + sum) ^ ((v0 >> 5) + k3);
}
v[0] = v0;
v[1] = v1;
}
void decrypt(uint32_t *v, uint32_t *k)
{
uint32_t v0 = v[0], v1 = v[1], sum = 0xC6EF3720, i;
uint32_t delta = 0x9e3779b9;
uint32_t k0 = k[0], k1 = k[1], k2 = k[2], k3 = k[3];
for (i = 0; i < 32; i++)
{
v1 -= ((v0 << 4) + k2) ^ (v0 + sum) ^ ((v0 >> 5) + k3);
v0 -= ((v1 << 4) + k0) ^ (v1 + sum) ^ ((v1 >> 5) + k1);
sum -= delta;
}
v[0] = v0;
v[1] = v1;
}
int main()
{
unsigned int v[4] = {370962600, 1695475146, 1118301157, 328319843}, key[4] = {1, 2, 3, 4};
for (int i = 0; i < 4; i += 2)
{
decrypt(v + i, key);
printf("%x, %x, ", (v + i)[0], (v + i)[1]);
}
}
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
#include <stdio.h>

void encrypt(unsigned int *v, unsigned int *key)
{
unsigned int l = v[0], r = v[1], sum = 0, delta = 0x9e3779b9;
for (size_t i = 0; i < 32; i++)
{
sum += delta;
l += ((r << 4) + key[0]) ^ (r + sum) ^ ((r >> 5) + key[1]);
r += ((l << 4) + key[2]) ^ (l + sum) ^ ((l >> 5) + key[3]);
}
v[0] = l;
v[1] = r;
}

void decrypt(unsigned int *v, unsigned int *key)
{
unsigned int l = v[0], r = v[1], sum = 0, delta = 0x9e3779b9;
sum = delta * 32;
for (size_t i = 0; i < 32; i++)
{
r -= ((l << 4) + key[2]) ^ (l + sum) ^ ((l >> 5) + key[3]);
l -= ((r << 4) + key[0]) ^ (r + sum) ^ ((r >> 5) + key[1]);
sum -= delta;
}
v[0] = l;
v[1] = r;
}

int main(int argc, char const *argv[])
{
unsigned int v[4] = {370962600, 1695475146, 1118301157, 328319843}, key[4] = {1, 2, 3, 4};
for (int i = 0; i < 4; i += 2)
{
decrypt(v + i, key);
printf("%x, %x, ", (v + i)[0], (v + i)[1]);
}
return 0;
}
1
2
3
4
5
6
from Crypto.Cipher import AES
c = [0x5a87be5e, 0x13e418d0, 0x66aaefdd, 0xb322754f]
key = b'win_crack_god!@#'
cipher = b''.join([i.to_bytes(4, 'little') for i in c])
aes = AES.new(key, AES.MODE_ECB)
print(aes.decrypt(cipher))
  • 代码解释:来自Chatgpt
    当我们观察到这段代码时,可以看到它使用了列表推导式和join()函数来将一组整数转换为一个字节字符串。

    让我们逐步解释这段代码的功能:

    1. [i.to_bytes(4, 'little') for i in c]:这是一个列表推导式,遍历列表c中的每个整数i,并将每个整数转换为一个4字节的小端字节序。to_bytes(4, 'little')方法将整数转换为一个字节字符串,其中参数4表示要生成的字节数,’little’表示使用小端字节序进行编码。
    2. b''.join(...)join()函数用于连接字符串。在这里,它将列表推导式生成的所有字节字符串连接在一起。b''是一个空的字节字符串,作为连接时的分隔符。

    综合起来,cipher = b''.join([i.to_bytes(4, 'little') for i in c])的作用是将列表c中的每个整数转换为4字节的小端字节序,并将它们连接成一个字节字符串。结果存储在cipher变量中,用于后续的解密操作。

  • 至于填充模式,默认就是PKCS5Padding

黑客偷走的密码(AES)

附件

链接:https://pan.baidu.com/s/1F5S5juDhDUdkdHiMMCesug?pwd=1111
提取码:1111

描述:财务人员的电脑中了勒索病毒,重要账号的密码文件被加密了,必须向攻击者支付比特币才能获得解密密码。作为安全人员,你有办法还原文件,找回文件中的密码吗?

考点:AES WIN API分析

插件识别出来是AES

Key

解题代码

1
2
3
4
5
6
7
from Crypto.Cipher import AES
k = [0x16157E2B, 0xA6D2AE28, 0x8815F7AB, 0x3C4FCF09]
key = b"".join([i.to_bytes(4, "little") for i in k ])
cry = open("flag.txt.cry", "rb").read()
aes = AES.new(key, AES.MODE_ECB)
plain = aes.decrypt(cry).decode()
print(f"plain text: {plain}")

汇编跳转指令解析

  1. **jmp**(Jump):无条件跳转指令。它会无条件地将程序的执行流程转移到指定的地址处,从而实现无条件的跳转。
  2. **jg**(Jump If Greater):有符号数比较跳转指令。当”大于”条件成立时,即前一个操作数大于后一个操作数时,执行跳转。
  3. **jl**(Jump If Less):有符号数比较跳转指令。当”小于”条件成立时,即前一个操作数小于后一个操作数时,执行跳转。
  4. **jge**(Jump If Greater or Equal):有符号数比较跳转指令。当”大于等于”条件成立时,即前一个操作数大于或等于后一个操作数时,执行跳转。
  5. **jle**(Jump If Less or Equal):有符号数比较跳转指令。当”小于等于”条件成立时,即前一个操作数小于或等于后一个操作数时,执行跳转。
  6. **je**(Jump If Equal):有符号数比较跳转指令。当”等于”条件成立时,即两个操作数相等时,执行跳转。
  7. **jne**(Jump If Not Equal):有符号数比较跳转指令。当”不等于”条件成立时,即两个操作数不相等时,执行跳转。

总结: 跳转指令一共四种

  • 无条件: jmp
  • 比较:jg> jl<
  • 等号比较:jge>= jle<=
  • 等于比较:je= jne/=

代码例子:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
compare:
; Compare a and b
cmp edi, esi ; Compare a (edi) with b (esi)

; Jump if greater (a > b)
jg greater

; Jump if not greater (a <= b)
jmp not_greater

; Jump if greater (a > b)
jg greater

; Jump if less (a < b)
jl less

; Jump if equal (a == b)
je equal