mitmproxy套件使用攻略

jopen 9年前發布 | 66K 次閱讀 mitmproxy

mitmproxy是一款支持HTTP(S)的中間人代理工具。不同于Fiddler2,burpsuite等類似功能工具,mitmproxy可在終端下運行。mitmproxy使用Python開發,是輔助web開發&測試,移動端調試,滲透測試的工具。

工作原理介紹(以HTTPS為例)

1.客戶端發起一個到mitmproxy的連接,并且發出HTTP CONNECT請求,

2.mitmproxy作出響應(200),模擬已經建立了CONNECT通信管道,

3.客戶端確信它正在和遠端服務器會話,然后啟動SSL連接。在SSL連接中指明了它正在連接的主機名(SNI),

4.mitmproxy連接服務器,然后使用客戶端發出的SNI指示的主機名建立SSL連接,

5.服務器以匹配的SSL證書作出響應,這個SSL證書里包含生成的攔截證書所必須的通用名(CN)和服務器備用名(SAN),

6.mitmproxy生成攔截證書,然后繼續進行與第3步暫停的客戶端SSL握手,

7.客戶端通過已經建立的SSL連接發送請求,

8.mitmproxy通過第4步建立的SSL連接傳遞這個請求給服務器。

mitmproxy套件使用攻略

配置

1. 設置系統\瀏覽器\終端等的代理地址和端口

2. 瀏覽器或移動端安裝mitmproxy提供的證書

官方提供的安裝方式: http://mitmproxy.org/doc/certinstall.html

mitmproxy 

mitmproxy會提供一個在終端下的圖形界面,具有修改請求和響應,流量重放等功能,具體操作方式有點vim的風格, 參考請點這

mitmproxy套件使用攻略

mitmdump

mitmdump可設定規則保存或重放請求和響應, 點我查看用法

mitmdump的特點是支持inline腳本,由于擁有可以修改request和response中每一個細節的能力,批量測試,劫持等都可以輕松實現,下面是個篡改圖片的例子:

from libmproxy.protocol.http import decoded
def response(context, flow):
    if flow.response.headers.get_first("content-type", "").startswith("image"):
        with decoded(flow.response):
      try:
        img = cStringIO.StringIO(open('freebuf.jpg', 'rb').read())
        flow.response.content = img.getvalue()
        flow.response.headers["content-type"] = ["image/jpg"]
      except:
    pass

判別header中是否存在image,如果有的話替換成指定圖片。

mitmdump --script pic.py

效果如下:

mitmproxy套件使用攻略

libmproxy

libmproxy是mitmproxy的擴展api,新版本的libmproxy(筆者使用的:0.13 on Kali 2.0)與老版本有所差別,官方給出了幾個樣例,這里搜集和總結一些用法。

簡單的例子:

#coding=utf-8
import os
from libmproxy import flow, proxy
from libmproxy.proxy.server import ProxyServer
class MyMaster(flow.FlowMaster):
  def run(self):
    try:
      flow.FlowMaster.run(self)
    except KeyboardInterrupt:
      self.shutdown()
  def handle_request(self, f):
    f = flow.FlowMaster.handle_request(self, f)
    if f:
      print f.request.url
      f.reply()
    return f
  def handle_response(self, f):
    f = flow.FlowMaster.handle_response(self, f)
    if f:
      print f.request.url, f.response
      f.reply()
    return f
def test_start():
  config = proxy.ProxyConfig(
    port=8080,
    # use ~/.mitmproxy/mitmproxy-ca.pem as default CA file.
    cadir="~/.mitmproxy/",
  )
  state = flow.State()
  server = ProxyServer(config)
  m = MyMaster(server, state)
  m.run()
test_start()

當這個腳本運行后,將會監聽127.0.0.1:8080,并輸出經過此代理的request的url和response的摘要,運行下面的腳本做個測試:
#coidng=utf-8
import requests
import gevent
from gevent import monkey; monkey.patch_socket()
class test():
    def task(self, url):
  print gevent.getcurrent(), url
  resp = requests.get(url)
  print url, resp
    def start(self):
  url_list = ['http://www.baidu.com',
        'http://www.amazon.com',
            'http://www.freebuf.com',
        'http://www.google.com',
        'http://jd.com']
  threads = [gevent.spawn(self.task, url) for url in url_list]
  gevent.joinall(threads)
get_test = test()
get_test.start()

效果:

mitmproxy套件使用攻略

mitmproxy套件使用攻略

由于libmproxy/flow.py 提供了處理request和response的能力,這樣使用libmproxy提供的擴展可以方便的判別,修改數據。 下面的代碼可用來修改headers,偽造隨機User-Aent(可用于掃描器,爬蟲等):

if f.request.headers['User-Agent']:
    UAlist = ["Mozilla/5.0 (X11; U; Linux i686; en-GB; rv:1.8.1.6) Gecko/20070914 Firefox/2.0.0.7",
      "Mozilla/5.0 (Windows; U; Windows NT 6.0; en-US; rv:1.8.1.7) Gecko/20070914 Firefox/2.0.0.7",
      "Mozilla/5.0 (Windows; U; Windows NT 6.0; en) AppleWebKit/522.15.5 (KHTML, like Gecko) Version/3.0.3 Safari/522.15.5",
      "Mozilla/5.0 (Macintosh; U; PPC Mac OS X; en) AppleWebKit/103u (KHTML, like Gecko) safari/100",
      "Opera/9.23 (X11; Linux x86_64; U; en)",
      "Opera/9.23 (Windows NT 5.1; U; en)",
      "Mozilla/4.0 (compatible; MSIE 6.1; Windows XP)",
      "Mozilla/5.0 (Windows; U; MSIE 7.0; Windows NT 6.0)",
      "Mozilla/5.0(iPad; U; CPU iPhone OS 3_2 like Mac OS X; en-us) AppleWebKit/531.21.10 (KHTML, like Gecko) Version/4.0.4 Mobile/7B314 Safari/531.21.10"]
      f.request.headers['User-Agent'] = [random.choice(UAlist)]

使用libmproxy的擴展腳本會獨立運行,這時libmproxy/controller.py會在循環監測是否有請求:

mitmproxy套件使用攻略

mitmproxy套件使用攻略

mitmproxy套件使用攻略

當收到請求后,通過調試Queue中的數據看出proxy對請求和響應的處理流程:

mitmproxy套件使用攻略

mitmproxy套件使用攻略

mitmproxy套件使用攻略

mitmproxy套件使用攻略

mitmproxy套件使用攻略

腦洞:利用libmproxy實現代理式掃描器

可以分為3個模塊:

1,利用libmproxy代理抓到的resquest和response,判別后進存入數據庫;
2,定時從數據庫讀取數據,對數據進行預處理,調用掃描模塊(可參考FreeBuf《基于代理的Web掃描器的實現
》文章;
3,掃描模塊(代理式掃描器的核心);

下面的代碼會將請求和響應中的一些數據存入MongoDB(結構供參考,更細節的部分正在開發中)。

#coding=utf-8
import os
import pymongo
import time
from libmproxy import flow, proxy
from libmproxy.proxy.server import ProxyServer
from libmproxy.flow import FlowWriter
class MyMaster(flow.FlowMaster):
  def run(self):
    self.db_init()
    try:
      flow.FlowMaster.run(self)
    except KeyboardInterrupt:
      self.shutdown()
  def handle_request(self, f):
    f = flow.FlowMaster.handle_request(self, f)
    if f:
      print f.request.url
      f.reply()
    return f
  def handle_response(self, f):
    f = flow.FlowMaster.handle_response(self, f)
    if f:
      self.db_insert(f)
      f.reply()
    return f
  def db_init(self):
    self.client = pymongo.MongoClient('127.0.0.1', 27017)
    self.db = self.client['scan']
    self.coll = self.db['scan_res']
    return
  def db_insert(self, flow):
    insert_dict = {}
    if flow:
      insert_dict = {
        'time': time.time(),
        'request': {
          'url': flow.request.url,
          'scheme': flow.request.scheme,
          'path': flow.request.path,
          'method': flow.request.method
        },
        'response': {
          'msg': flow.response.msg,
          'code': flow.response.code,
          'header': dict(flow.response.headers),
          'content': flow.response.content
        }
      }
      self.coll.insert(insert_dict)
    else:
      return
def test_start():
  config = proxy.ProxyConfig(
    port=8080,
    # use ~/.mitmproxy/mitmproxy-ca.pem as default CA file.
    cadir="~/.mitmproxy/",
  )
  state = flow.State()
  server = ProxyServer(config)
  m = MyMaster(server, state)
  m.run()
test_start()

后記

老版本kali升級mitmproxy可能會產生某些庫不可用的問題,并且libmproxy仍存在著些許不足(擴展性不夠強),但mitmproxy仍為一個功能強大的工具,更多功能尚待研究,代理式掃描器已作為私人項目正在逐步開發。

參考來源

http://sigint.ru/writeups/2014/04/13/plaidctf-2014-writeups/

http://acsweb.ucsd.edu/~abuss/backdoor2014.html

http://lilydjwg.is-programmer.com/tag/mitmproxy

https://gist.github.com/yeukhon/8573005

* 作者:漏洞盒子安全團隊gaba,轉載請注明來自FreeBuf黑客與極客(FreeBuf.COM)

 本文由用戶 jopen 自行上傳分享,僅供網友學習交流。所有權歸原作者,若您的權利被侵害,請聯系管理員。
 轉載本站原創文章,請注明出處,并保留原始鏈接、圖片水印。
 本站是一個以用戶分享為主的開源技術平臺,歡迎各類分享!