学习报告(最后一次任务)

runwu2204 Lv6

RE1.PYC

先启动该文件看下运行结果

不知道是因为什么无法再次运行,通过搜索找到是因为没有原py文件所以无法再次运行,那就通过ida(32位)看看其源代码

pyc文件主要是无法通过f5反汇编查找代码逻辑

image-20221203235426178

尝试通过shift+f12查询字符串,结果如下

image-20221203234728213

一般有效的字符串,线索之类的会出现在此,如果不有效也一般会放在内存附近(一般)

通过双击寻找,往上翻后最终找到了对应的密文(非flag{}此类格式应该是经过了加密)

image-20221203235623344

下方也有说明,表现是通过base64加密的,将其拖入base64中解密

image-20221203235745853

得到了最后的flag:D0g3{Do_You_Want_To_Hammer_Me}

RE2

image-20221204003416911

通过反汇编找到对应函数极少(一般是通过了加壳)

再通过寻找字符串,发现确实是通过了upx加壳,且是3.96版本,用普通的脱壳尝试如下

image-20221204004546195

发现报错无法脱壳

疯狂百度,发现是经过了特征码修改

image-20221205152424562

image-20221205152739287

尝试通过winhex修改该文件,失败了。

通过开挂发现需要dump

不太成功dump出源文件后(需进行反反编译操作将真正的EOP找到,然后再将源文件dump下来,此处我不知道为什么无法获取对原文加密的函数)

image-20221212212627494

正常情况应该如图

image-20221212213109598

此处以正常情况距离

先通过shift+f12搜索显示的字符串

image-20221212213343179

双击选中

image-20221212213424909

再通过x查询交叉引用

image-20221212213452131

成功找到对应函数

image-20221212213524142

再通过f5反汇编就可以大致看懂了

image-20221212213555159

根据wp所说此处采用了多重加密(包含仿射加密)

根据此处可以获得仿射加密的字典

1
strcpy(v29, "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwzyz0123456789{}");

还有被加密的的字符

unsigned char是因为默认字符有负数

1
2
3
4
5
6
7
8
9
10
unsigned char a[]={
0x0A,0xF2,0xF2,0x0A,0xF3,0x1C,0x1C,0x04,
0xF2,0x02,0xF7,0x08,0xF5,0x08,0xF5,0x08,
0x20,0x32,0xF2,0xF2,0x08,0xF3,0x04,0x0A,
0x0A,0xF2,0xF2,0x04,0xF7,0x08,0x2A,0x12,
0x2A,0xF5,0x04,0xF2,0xF2,0x04,0xF2,0xF2,
0xF2,0xF2,0x0D,0x34,0xF2,0x0D,0xF5,0x0A,
0x12,0xF3,0x02,0xF2,0x12,0x12,0xF2,0xF2,
0xF2,0xF2,0x0D,0xF3,0x0A,
}

根据仿射加密规则c(密文)=(a*m(待加密字符)+b)(mod n)

解密则需要获得密钥a与字典长度n的最大公因数gcd(a,n)

d(解密)=(a-gcd(a,n)(c-b))(mod n)

其通过异或加密和数字分解加密将实际值掩盖了,首先应该通过

先异或回去再将质数乘回来

如下

此处分别异或的为0xf0和0x0f

image-20221213151537448

将分解出的质数拿出来放入数组中得

1
2
3
4
5
6
7
8
9
10
11
int divi_step[] =
{
0x01,0x03,0x02,0x01,
0x01,0x02,0x02,0x02,
0x02,0x01,0x01,0x03,
0x02,0x01,0x01,0x03,
0x02,0x01,0x01,0x01,
0x02,0x03,0x05,0x01,
0x02,0x02,0x01,0x02,
0x02,0x01,0x05,0x02,
}

根据wp

具体处理则为

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
67
68
69
70
#include<stdio.h>


int main()
{
unsigned char a[]={
0x0A,0xF2,0xF2,0x0A,0xF3,0x1C,0x1C,0x04,
0xF2,0x02,0xF7,0x08,0xF5,0x08,0xF5,0x08,
0x20,0x32,0xF2,0xF2,0x08,0xF3,0x04,0x0A,
0x0A,0xF2,0xF2,0x04,0xF7,0x08,0x2A,0x12,
0x2A,0xF5,0x04,0xF2,0xF2,0x04,0xF2,0xF2,
0xF2,0xF2,0x0D,0x34,0xF2,0x0D,0xF5,0x0A,
0x12,0xF3,0x02,0xF2,0x12,0x12,0xF2,0xF2,
0xF2,0xF2,0x0D,0xF3,0x0A,
};//获取的密文
//0 1 4
int divi_step[] =
{
0x01,0x03,0x02,0x01,
0x01,0x02,0x02,0x02,
0x02,0x01,0x01,0x03,
0x02,0x01,0x01,0x03,
0x02,0x01,0x01,0x01,
0x02,0x03,0x05,0x01,
0x02,0x02,0x01,0x02,
0x02,0x01,0x05,0x02,
};//一般F0 最后一位0F
char table[] = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwzyz0123456789{}";
unsigned char wp[64];
unsigned char btmp=0;
int i=0,j=0,pre_base=0;

//素数分解逆推
for(i=0;i<32;i++)
{
btmp=1;
for(j=0;j<divi_step[i];j++)
{
if(j==divi_step[i]-1)
{
btmp=(a[pre_base+j]^0x0F)*btmp;//
}
else
{
btmp=(a[pre_base+j]^0xF0)*btmp;//将原来异或的文字异或回去
}

}
wp[i]=btmp;
pre_base+=divi_step[i];
}
//异或逆推
for(i=31;i>=0;i--)// 1 2 3
{
if(i==31)
wp[i]=wp[i]^wp[0];//通过异或的可逆性恢复原来的字符
else
wp[i]=wp[i]^wp[i+1];
}
//仿射密码学逆推
for(i=0;i<32;i++)
{
wp[i] = (unsigned char)((wp[i] - 47) * 45) % 64;//强制转化为unsigned char 防止出现负数
//这个符号的处理很重要的
wp[i] = table[wp[i]];
}
wp[32]=0;//给字符串一个结尾
puts((char*)wp);
return ;
}

​ 最终代码运行结果不是wp的答案那种而是D8g7{TherefIsfAfLongfWa6fTofGof}

wp中答案则是

D0g3{There_Is_A_Long_Way_To_Go_}

  • 标题: 学习报告(最后一次任务)
  • 作者: runwu2204
  • 创建于 : 2023-01-05 17:05:18
  • 更新于 : 2023-06-23 01:51:27
  • 链接: https://runwu2204.github.io/2023/01/05/Re/实验室报告/学习报告(最后一次任务)/
  • 版权声明: 本文章采用 CC BY-NC-SA 4.0 进行许可。
评论
目录
学习报告(最后一次任务)