CTF-Show 类型-7 WP


CTF-Show 类型-7 WP

题目描述

flag格式为 ctfshow{明文}

1
094F5A0F0A0D1805103B0B3D143117183B720438350A45550967674D1E064F2969784440455A460F1A1B

TL;DR

本质上是思科路由器和安全设备的一种密码加密方式,由于可以被反向解密,已经被 deprecated 且不被推荐使用。

题解

解密 Link: - https://www.bejson.com/encrypt/type7_decode/ - http://web.chacuo.net/safeciscotype7 - http://www.atoolbox.net/Tool.php?Id=992

btw, insecure.org/sploits/cisco.passwords 处代码有误,我在 github.com/sfc9982/Cisco-Type-7-Password-Decoder 中修复了它,已向作者反馈。

有关思科的各种密码加密方案,可以参考 NSA 的文章 Cisco Password Types: Best Practices

给我们的启发就是生产环境中的加密方案也不一定安全

代码

cdecrypt() 中的迭代方式和数据类型的处理很啰嗦,有时间优化一下。

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
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
#include <ctype.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <strings.h>

char xlat[] = "dsfd;kfoA,.iyewrkldJKDHSUBsgvca69834ncxv9873254k;fg87";

char pw_str1[] = " password 7 ";
char pw_str2[] = "enable password 7 ";
char pw_str3[] = "ip ftp password 7 ";
char pw_str4[] = " ip ospf message-digest-key 1 md5 7 ";

char *pname;

int cdecrypt(char *enc_pw, char *dec_pw)
{
unsigned int seed, i, val = 0;

if (strlen(enc_pw) & 1)
return -1;

seed = (enc_pw[0] - '0') * 10 + enc_pw[1] - '0';

if (seed > 15 || !isdigit(enc_pw[0]) || !isdigit(enc_pw[1]))
return -1;

for (i = 2; i <= strlen(enc_pw); i++)
{
if (i != 2 && !(i & 1))
{
dec_pw[i / 2 - 2] = val ^ xlat[seed++];
val = 0;
}

val *= 16;

if (isdigit(enc_pw[i] = toupper(enc_pw[i])))
{
val += enc_pw[i] - '0';
continue;
}

if (enc_pw[i] >= 'A' && enc_pw[i] <= 'F')
{
val += enc_pw[i] - 'A' + 10;
continue;
}

if (strlen(enc_pw) != i)
return -1;
}

dec_pw[++i / 2] = 0;

return 0;
}

int usage()
{
fprintf(stdout, "Usage: %s -p <encrypted password>\n", pname);
fprintf(stdout, " %s <router config file> <output file>\n", pname);

return 0;
}

int main(int argc, char **argv)
{
FILE *in = stdin, *out = stdout;
char line[257];
char passwd[65];
unsigned int i, pw_pos;

pname = argv[0];

if (argc > 1)
{
if (argc > 3)
{
usage();
exit(1);
}

if (argv[1][0] == '-')
{
switch (argv[1][1])
{
case 'h':
usage();
break;

case 'p':
memset(passwd, 0, sizeof(passwd));
if (cdecrypt(argv[2], passwd))
{
fprintf(stderr, "Error.\n");
exit(1);
}
fprintf(stdout, "password: %s\n", passwd);
break;

default:
fprintf(stderr, "%s: unknow option.", pname);
}

return 0;
}

if ((in = fopen(argv[1], "rt")) == NULL)
exit(1);
if (argc > 2)
if ((out = fopen(argv[2], "wt")) == NULL)
exit(1);
}

while (1)
{
for (i = 0; i < 256; i++)
{
if ((line[i] = fgetc(in)) == EOF)
{
if (i)
break;

fclose(in);
fclose(out);
return 0;
}
if (line[i] == '\r')
i--;

if (line[i] == '\n')
break;
}
pw_pos = 0;
line[i] = 0;

if (!strncmp(line, pw_str1, strlen(pw_str1)))
pw_pos = strlen(pw_str1);
if (!strncmp(line, pw_str2, strlen(pw_str2)))
pw_pos = strlen(pw_str2);
if (!strncmp(line, pw_str3, strlen(pw_str3)))
pw_pos = strlen(pw_str3);
if (!strncmp(line, pw_str4, strlen(pw_str4)))
pw_pos = strlen(pw_str4);

// if (!pw_pos)
// {
// fprintf(stdout, "%s\n", line);
// continue;
// }

memset(passwd, 0, sizeof(passwd));
if (cdecrypt(&line[pw_pos], passwd))
{
fprintf(stderr, "Error.\n");
exit(1);
}
else
{
if (pw_pos == strlen(pw_str1))
fprintf(out, "%s", pw_str1);
else if (pw_pos == strlen(pw_str2))
fprintf(out, "%s", pw_str2);
else if (pw_pos == strlen(pw_str3))
fprintf(out, "%s", pw_str3);
else if (pw_pos == strlen(pw_str4))
fprintf(out, "%s", pw_str4);


fprintf(out, "%s\n", passwd);
}
}
}

文章作者: sfc9982
版权声明: 本博客所有文章除特別声明外,均采用 CC BY-NC-ND 4.0 许可协议。转载请注明来源 sfc9982 !
  目录