这让我疯了,我正试图基于fritzbox SPEC进行一些MD5计算来登录。基本上,你必须将挑战和密码转换为UTF-16LE,然后通过MD5进行哈希,然后连接challenge-MD5(uft-16LE(挑战密码))
为此,我在脚本中使用macOSX中的iconv和md5
echo -n "challenge-password1234" | iconv -f ISO8859-1 -t UTF-16LE | md5
哪个输出到2f42ad272c7aec4c94f0d9525080e6de
只需将其粘贴到外壳中即可完成1722e126192656712a1d352e550f1317
的输出
后一个是正确的(被fritzbox接受)第一个是错误的。
用bash script.sh
调用脚本会产生正确的哈希,用sh script.sh
调用脚本会导致错误的哈希,这就引出了一个新的问题:为什么sh和bash的输出有什么不同?
不同版本的echo
的行为方式截然不同。有些采用命令选项(如-n
)来修改其行为(包括-n
抑制尾随换行),有些则不采用。一些解释字符串本身中的转义序列(包括字符串末尾的c
,抑制尾部换行)。。。有些人没有。有些人两者兼而有之。系统上的echo
(/bin/echo)版本似乎不接受选项,因此将-n
视为要打印的字符串。如果您使用bash,它的内置版本会覆盖/bin/echo,会解释标志。
基本上,echo
是一堆不一致性和可移植性陷阱。所以不要使用它,而是使用printf
。这有点复杂,因为你必须指定一个格式字符串,然后是你想要打印的实际内容,但这可以省去很多麻烦。
$ printf "%s" "challenge-password1234" | iconv -f ISO8859-1 -t UTF-16LE | md5
1722e126192656712a1d352e550f1317
顺便说一下,以下是echo
命令实际打印的内容:
$ printf "%sn" "-n challenge-password1234" | iconv -f ISO8859-1 -t UTF-16LE | md5
2f42ad272c7aec4c94f0d9525080e6de
您特别询问脚本和命令行结果之间的区别。请注意,在其他情况下,脚本结果可能无法用于Fritzbox。
AVM Fritzbox文档中的会话处理示例代码是用C#编写的,请参阅
- https://avm.de/fileadmin/user_upload/Global/Service/Schnittstellen/AVM_Technical_Note_-_Session_ID.pdf
从我得到的代码https://github.com/WolfgangFahl/fritz-csharp-api并添加了一些测试:
- https://github.com/WolfgangFahl/fritz-csharp-api/blob/master/fritzsimpletest.cs
其灵感来源于中的测试
- https://github.com/WolfgangFahl/fritzbox-java-api/blob/master/src/test/java/com/github/kaklakariada/fritzbox/Md5ServiceTest.java
基本上有5个例子:
- "->"d41d8cd98f00b204e9800998ecf8427e"
- "秘密","09433e1853385270b51511571e35eeca"
- "测试","c8059e2ec7419f590e79d7f1b774bfe6"
- "1234567z-äbc","9e224a41eefa284df7bb0f26c2913e2"
- "!\"§$%&()=?ßüäÜÖ-,;:_`´+*#'<>≤|"->"ad44a7cb10a95cb0c4d7ae90b0ff118a"现在你的例子是6:
-
"challenge-password1234"->"1722e 126192656712a1d352e50f1317"并且这些在Java和C#实现中表现相同。现在用下面有的bash脚本来尝试这些
echo-n"$l_s"|iconv--从代码ISO8859-1--到代码UTF-16LE|md5sum-b|gawk'{print substr($0,1,32)}'
例如在https://www.ip-phone-forum.de/threads/fritzbox-challenge-response-in-sh.264639/
因为它的getmd5函数为元音变音符的情况给出了不同的结果,例如在Mac OS Sierra上的bash中。
已经添加了一些调试输出。
为1234567z-äbc给出的编码具有字节序列2d c3 a4 62 63,而例如java实现具有2d e4 62 63。
因此,请注意密码中的元音变音符-使用此脚本解决方案,fritzbox访问可能会失败。我正在寻找一个变通方法,当我找到它时会把它发布在这里。
bash脚本
#!/bin/bash
# WF 2017-10-30
# Fritzbox handling
#
# get the property with the given name
# params
# 1: the property name e.g. fritzbox.url, fritzbox.username, fritzbox.password
#
getprop() {
local l_prop="$1"
cat $HOME/.fritzbox/application.properties | grep "$l_prop" | cut -f2 -d=
}
#
# get a value from the fritzbox login_sid.lua
#
getboxval() {
local l_node="$1"
local l_response="$2"
if [ "$l_response" != "" ]
then
l_data="&response=$l_response"
fi
fxml=/tmp/fxml$$
curl --insecure -s "${box_url}/login_sid.lua?username=${username}$l_response" > $fxml
cat $fxml |
gawk -v node=$l_node 'match($0,"<"node">([0-9a-f]+)</"node">",m) { print m[1] }'
cat $fxml
rm $fxml
}
#
# get the md5 for the given string
#
# see https://avm.de/fileadmin/user_upload/Global/Service/Schnittstellen/AVM_Technical_Note_-_Session_ID.pdf
#
# param
# 1: s - the string
#
# return
# md5
#
getmd5() {
local l_s="$1"
echo -n "$l_s" | iconv -f ISO8859-1 -t UTF-16LE | od -x
echo -n "$l_s" | iconv --from-code ISO8859-1 --to-code UTF-16LE | md5sum -b | gawk '{print substr($0,1,32)}'
}
# get global settings from application properties
box_url=$(getprop fritzbox.url)
username=$(getprop fritzbox.username)
password=$(getprop fritzbox.password)
# uncomment to test
getmd5 ""
# should be d41d8cd98f00b204e9800998ecf8427e
getmd5 secret
# should be 09433e1853385270b51511571e35eeca
getmd5 test
# should be c8059e2ec7419f590e79d7f1b774bfe6
getmd5 1234567z-äbc
# should be 9e224a41eeefa284df7bb0f26c2913e2
getmd5 "!"§$%&/()=?ßüäöÜÄÖ-.,;:_`´+*#'<>≤|"
# should be ad44a7cb10a95cb0c4d7ae90b0ff118a
exit
# Login and get SID
challenge=$(getboxval Challenge "")
echo "challenge=$challenge"
md5=$(getmd5 "${challenge}-${password}")
echo "md5=$md5"
response="${challenge}-${md5}"
echo "response=$response"
getboxval SID "$response"