跟qqg学python--mitmproxy插件

1.背景

想自己整个被动扫描,看了那么多开源的,发现别人的写的太好了(因为自己太菜),改我都不知道怎么改,所以自己想了个蠢框架,整一下当学习。

2.框架

简单的框架就是这样想的

upload successful

看起来很蠢,其实确实很蠢,为什么要用flink泛化,是因为我想学一下,就那么简单。然后工作量最大的应该是proxyscan,合包扫描的部分,应该会抄来抄去,甚至直接用开源的,还是因为太菜了,没写过项目。

3.mitmproxy插件

首先装mitmproxy很简单

1
pip3 install mitmproxy

就完事了。

(有一个坑就是windows装的时候会需要windows sdk,装的时候报错百度解决就好了。)

然后mitmproxy插件的简单介绍是能从官方文档查到的

https://docs.mitmproxy.org/stable/addons-overview/

但是如果要看文档的话是需要用pydoc

upload successful

当时问了qqg,说是自己就纯看pydoc整完的。

于是我就抄了下。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
#coding=utf-8
import json
import mitmproxy.http
from mitmproxy import ctx
import asyncio
from kafka import KafkaProducer
from kafka.errors import KafkaError
from kafka.errors import NoBrokersAvailable
'''
mitmproxy插件,kafka生产者
'''

class Proxy:

def __init__(self):
#kafka连接,topic
self.topic = 'proxy'
self.connect_kafka()

def connect_kafka(self):
try:
           self.producer = KafkaProducer(bootstrap_servers='x.x.x.x:9092')
except NoBrokersAvailable as e:
ctx.log.error("KafkaConnectError: {}".format(e))

def flow_to_dict(self, flow: mitmproxy.http.HTTPFlow):
#处理有无body情况下的content和content_length
if flow.request:
if flow.request.raw_content:
request_content = flow.request.content.decode()
content_length = len(flow.request.raw_content)
raw_content = flow.request.raw_content.decode()
else:
request_content = None
content_length = None
raw_content = None

headers = {}
for k, v in flow.request.headers.items(True):
headers[k] = v

#处理请求到dict
request = {
"method": flow.request.method,
"scheme": flow.request.scheme,
"host": flow.request.host,
"port": flow.request.port,
"path": flow.request.path,
"url": flow.request.url,
"http_version": flow.request.http_version,
"headers": headers,
"content_length": content_length,
"content": request_content,
"raw_content": raw_content,
"timestamp_start": flow.request.timestamp_start,
"timestamp_end": flow.request.timestamp_end
}
return request
#协程大成功
async def send_json(self, flow: mitmproxy.http.HTTPFlow):
try:
request = self.flow_to_dict(flow)
self.producer.send(self.topic, json.dumps(request).encode())

except NoBrokersAvailable as e:
self.connect_kafka()

except KafkaError as e:
ctx.log.error("KafkaError: {}".format(e))

def request(self, flow):
asyncio.get_event_loop().create_task(self.send_json(flow))


addons = [
Proxy()
]

其实就是简单的将flow对象的各种需要的内容,存到字典里,然后直接转成json,最后丢到kafka里。

asyncio这部分写法则是抄的mitmproxy本身的插件,因为mitmproxy本身的一些功能就是通过写插件完成的。

比如这个
https://github.com/mitmproxy/mitmproxy/blob/master/mitmproxy/addons/readfile.py

upload successful

翻了翻mitmproxy的源码,这里因为本身插件就是用event_loop去执行的,所以只需要create_task就可以了。(如果有理解的不对,请教教我)

upload successful

最后加载插件启动就完事了。
mitmdump -q -s addon.py –listen-host 127.0.0.1 –listen-port 8080

装证书的话,挂上代理访问mitm.it,按照安装步骤装好就行了。

upload successful