抓包
—
burp抓包测试(抓不到)
httpcanary
HttpCanary 可以抓到包,可以看到有请求包有加密。可以看到报文有显著的特征:params
代码分析
—
直接将 app 拖到 Jadx-gui 中,可以看到没有加壳:
然后搜索报文中的:"params",然后定位到了加解密的地方,有报文的参数进行搜索,找加解密还是比较快的。
下面是加解密的核心代码:
小tips:jadx-gui 中,可以在类或方法名称上右键——复制为 frida片段,便可以自动生成 frida hook 代码了。
使用 objection 对加密和解密的方法进行验证:
android hooking watch class_methon [方法的完整路径] --
dump
-args --
dump
-backtrace --
dump
-
return
通过 hook 的结果,可以判断该处代码就是报文的加解密代码。
编写hook + rpc代码
—
function
main
(
)
{
Java.perform(
function
(
)
{
console
.log(
"正在注入"
)
var
data = Java.use(
'com.xxxx.http.HttpEncrypt'
);
data.encryptParams.implementation =
function
(
json, signdata
)
{
console
.log(
"===========================加密算法=========================="
);
send(json.toString());
//因为是json类型数据,所以需要转换为string类型,否则转发不到burp
var
tmp;
var
op = recv(
'send'
,
function
(
value
)
{
tmp = value.payload;
console
.log(
"请求篡改后----->: "
, tmp);
return
tmp;
});
op.wait();
return
this
.encryptParams(tmp, signdata);
}
var
shuju = Java.use(
'com.xxxx.http.HttpEncrypt'
);
data.decryptReponse.implementation =
function
(
content, i
)
{
console
.log(
"==========================解密算法=============================="
);
var
ret =
this
.decryptReponse(content, i);
send(ret);
var
tmp;
var
op = recv(
'send'
,
function
(
value
)
{
tmp = value.payload;
console
.log(
"请求篡改后----->: "
, tmp);
return
tmp;
});
op.wait();
return
tmp;
}
});
}
setTimeout(main,
5000
);
启动 handle_server.py
from http.server import HTTPServer, BaseHTTPRequestHandler
class
RequestHandler
(
BaseHTTPRequestHandler
):
def
do_GET
(
self
)
:
print(
'Recving request connction...'
)
request_headers =
self
.headers
content_length = request_headers.get(
'content-length'
)
length = int(content_length[
0
])
if
content_length
else
0
print(
self
.headers)
self
.send_response(
200
)
self
.end_headers()
self
._send_cors_headers()
self
.wfile.write(
self
.rfile.read(length))
def
do_POST
(
self
)
:
print(
'Recving request connction...'
)
req_datas =
self
.rfile.read(int(
self
.headers[
'content-length'
]))
# print(self.headers)
# print(req_datas)
self
.send_response(
200
)
self
._send_cors_headers()
self
.end_headers()
self
.wfile.write(req_datas)
def
_send_cors_headers
(
self
)
:
self
.send_header(
'Content-type'
,
'application/json'
)
self
.send_header(
"Access-Control-Allow-Origin"
,
"*"
)
self
.send_header(
"Access-Control-Allow-Methods"
,
"*"
)
self
.send_header(
"Access-Control-Allow-Headers"
,
"Authorization, Content-Type"
)
def
do_OPTIONS
(
self
)
:
self
.send_response(
200
)
self
._send_cors_headers()
self
.end_headers()
def
main
(ECHO_PORT)
:
print(
'Listening on localhost: %d'
% ECHO_PORT)
server = HTTPServer((
'127.0.0.1'
, ECHO_PORT), RequestHandler)
server.serve_forever()
if
__name_
_
==
'__main__'
:
main(
8889
)
burpsuite 监听 127.0.0.1:8888
然后使用 adb 转发端口:
adb
forward
tcp
:27042
tcp
:27042
'''
python toBurp.py
中转至burp,动态修改请求
'''
import
os
import
time
import
sys
import
frida
import
requests
import
json
def
on_message
(message, data)
:
if
isinstance(message, dict):
if
message[
'type'
] ==
'send'
:
payload = message[
'payload'
]
if
'{'
in
payload:
data = toburp(message[
"payload"
].encode(
'utf-8'
))
data = {
'type'
:
'send'
,
'payload'
: data}
script.post(data)
#script.post({'type': 'send', 'payload': json.loads(data)})
elif
message[
'type'
] ==
'error'
:
print(message[
'stack'
])
else
:
if
message.has_key(
"payload"
):
print(message[
"payload"
])
#获取设备应用名
def
get_application_name
(device, identifier)
:
for
p
in
device.enumerate_applications():
if
p.identifier == identifier:
return
p.name
# 中转到burp
def
toburp
(data)
:
proxies = {
'http'
:
'http://127.0.0.1:8888'
}
url =
'http://127.0.0.1:8889/Hook'
response=requests.post(url,data=data,proxies=proxies)
return
(response.text)
def
main
()
:
#连接设备
device = frida.get_remote_device()
#需要attach的apk包名
pid = device.spawn(
'com.xxxx.xxxx'
)
#修改为包名
try
:
#attach目标进程
session = device.attach(pid)
device.resume(pid)
#加载javaScript脚本
# 修改此处:aaa.js为hook脚本
script_content = open(
"aaa.js"
,encoding=
'utf-8'
).read()
global
script
script = session.create_script(script_content)
script.on(
"message"
, on_message)
script.load()
sys.stdin.read()
except
KeyboardInterrupt
as
e:
if
session
is
not
None
:
session.detach()
device.kill(pid)
sys.exit(
0
)
if
__name__ ==
"__main__"
:
main()
这是 burpsuite 可以接收到参数,但是提交的时候会失败,就是提交到服务器,服务器并不认识。
通过下图可以看到,参数是被正常打印出来了,但是提示重载,后来我写了重载也是不行。
public
final
String
encryptParams(JSONObject json,
String
signData)
var
ret =
JSON
.stringify(tmp);
第二种:
function
strToJson
(
str
)
{
var
json =
eval
(
'('
+ str +
')'
);
return
json;
}
最終修改后的 js 代码:
function
main
(
)
{
Java.perform(
function
(
)
{
console
.log(
"正在注入"
)
var
data = Java.use(
'com.xxxx.http.HttpEncrypt'
);
data.encryptParams.implementation =
function
(
json,signdata
)
{
console
.log(
"===========================加密算法=========================="
);
send(json.toString());
//因为是json类型数据,所以需要转换为string类型,否则转发不到burp
var
tmp;
var
op = recv(
'send'
,
function
(
value
)
{
tmp = value.payload;
console
.log(
"请求篡改后----->: "
, tmp);
return
tmp;
});
op.wait();
return
this
.encryptParams(tmp,signdata);
}
var
shuju = Java.use(
'com.xxxx.HttpEncrypt'
);
data.decryptReponse.implementation =
function
(
content,i
)
{
console
.log(
"==========================解密算法=============================="
);
var
ret =
this
.decryptReponse(content,i);
send(ret);
var
tmp;
var
op = recv(
'send'
,
function
(
value
)
{
tmp = value.payload;
console
.log(
"请求篡改后----->: "
, tmp);
return
tmp;
});
op.wait();
return
tmp;
}
});
}
setTimeout(main,
5000
);
修改好代码后,重新运行,burp 也能够抓到包了
通过测试发现,加解密的报文只是针对登录、点击功能按钮跳转时生成 token 等生效,经过测试,没发现什么漏洞,而内部页面其实还是 h5,还是需要用传统的抓包方式进行测试。
App内部H5抓包
—
由于刚开始测试了 burp 是抓不到包的,而 httpcanary 使用起来又不方便,所以尝试使用 charles。
charles 抓包的时候 app 显示无法连接到服务器,charles 提示证书的问题,怀疑可能是 SSLPinning,使用抓包工具抓包时,抓包工具拦截了服务端返回的内容并重新发给客户端的时候的证书不是服务器端原来的证书了,抓包工具将原本服务器的证书替换成自己的证书,于是就构成了中间人攻击,触发 SSL Pinning 导致连接中断,所以就抓不到包了。
尝试使用 objection 的 SSL Pinning disable 进行绕过。
启动 objection 并注入 app,输入命令:
android sslpinning disabl
运行命令后,charles 也成功抓到包了,而且没有加密,就很 nice
但是问题来了,charles 改包、重放啥的不是很方便,所以联动一下 burp
Charles联动BurpSuite
—
Charles设置
Proxy --> External Proxy Settings
将Web Proxy和Secure Web Proxy均设置为127.0.0.1:8080
BurpSuite设置
成功转发
—
这样手机代理连接 charles,charles 转发到 burp,就实现使用 burp 的抓包改包操作了
这个 app 权限限制的很死,没找到越权类的漏洞,代码也很规范,最后只找到几个中低危的洞。放一个文件上传的洞吧:
通过修改 MIME 类型,可以突破文件上传。
转载至Adminxe博客:
https:
//www.adminxe.com/4302.html
--------------------------------------------
原文始发于微信公众号(刨洞技术交流):对某金融App的加解密hook+rpc+绕过SSLPinning抓包
- 左青龙
- 微信扫一扫
-
- 右白虎
- 微信扫一扫
-
评论