MITM Proxy server in Ruby (evil-proxy와 rails를 이용한 WASE 트래픽 수집 구간 만들기)

WASE를 만들면서 MITM Proxy로 트래픽을 수집하는 서버를 만들었는데요, 이 과정에서 알아봤던거랑 기반(?)이 되었던 심플한 저의 코드 관련해서 글 작성합니다.

아 추가로.. WASE 만드는 프로젝트(?)는 전체적인 구조를 좀 많이 변경했습니다. 혹시라도 좋은 성과가 있다면.. 공유드리도록 할게요. (물론 리밋)

MITM Proxy server in Ruby

Ruby에서 Proxy 서버를 구축하기란 아주 쉽습니다. 간단하게는 WEBRick부터, 각종 Proxy 라이브러리를 이용하면 얼마 안걸리는 부분이지요. 또한 직접 소켓으로 작성하는 방법도 좋은 방법입니다. (속도가 빨라요)

그 와중에 WEBRick의 Proxy는 짧고 다루기 쉽습니다. 많은 Proxy library들이 WEBRick의 HTTPProxy를 베이스로 사용하죠.

require 'webrick/httpproxy'

s = WEBrick::HTTPProxyServer.new(
  :Port => 8080,
  :RequestCallback => Proc.new{|req,res|
    puts "-"*70
    puts req.request_line, req.raw_header
    puts "-"*70
  }
)
trap("INT"){ s.shutdown }
s.start

EVIL-PROXY 아래 보시면 아시겠지만, 제가 선택한 프록시입니다. 기본적으론 바로 아래 WEBRIck의 HTTPProxy를 베이스로 하며 SSL 지원이 아주 잘 됩니다. (이게 선택의 원인)

MITMProxy 이친구도 SSL 지원이 어느정도 되는 것으로 알고 있습니다만, 조금 번거로운 것으로 기억납니다.

RMITM 내용을 잘 살펴보진 않았지만, MITMProxy를 기반으로 만들어진 라이브러리입니다. 느낌 상 EVIL이랑 비슷할 것 같네요.

https://github.com/marcyb/rmitm

evil-proxy와 Rails DB(PostgreSQL)를 이용해서 WASE 뼈대 만들기

우선 WASE 구축하는 과정에선 Rails로 웹 뷰를 구성하고, 쌓여있는 데이터에 대해 로깅합니다. 초기에 컨셉코드로 만든 부분이니 비슷한 구성으로 만들 것이 있으시다면 참고되셨으면 합니다. (WASE 관련해서, 대규모 변경 작업을 진행하였죠… 안그래도 집에서 시간 없는데. 하핳)

코드 보기에 앞서 Rails에 대한 이야기를 잠깐 하려합니다. Rails는 확실히 CRUD 구축은 정말 빠릅니다. Burp를 통해 취약점 분석에 대한 트래픽 수집도 결국은 CRUD이기 떄문에 Rails로 DB와 View를 만들고 evil-proxy를 통해 수집한 데이터를 바로 db로 밀어넣었습니다.

그 과정에서 Rails의 Scaffold로 생성된.. 아니, Rails에서 생성된 모델에 대한 이야기를 잠깐하면, 우리가 예를들어 하나의 모델에 title:string body:text 이라는 2개의 컬럼을 만들 떄 DB에 딱 2개의 스키마만 생성되는건 아닙니다. Rails가 자동으로 PK를 잡아주고, 생성, 수정 날짜에 대해 컬럼을 추가해줍니다. 고로 3rd에서 Rails 쪽으로 데이터를 밀어넣을 때 고려해서 넣어주시면 됩니다.

require 'pg'
require 'evil-proxy'

proxy = EvilProxy::HTTPProxyServer.new Port: 8000
$con = PG.connect :dbname => 'loglog_development', :user => '[username]' , :password => '[passwd]'

proxy.before_request do |req|
  # Do evil things
  # Note that, different from Webrick::HTTPProxyServer,
  #   `req.body` is writable.
  #puts req
end

proxy.before_response do |req, res|
  # Here `res.body` is also writable.
  puts req
  req = req.to_s
  req = req.sub("'",""")
  req = req.sub('"',""")
  rs = $con.exec "insert into logs (data,created_at,updated_at) values ('"+req+"',LOCALTIMESTAMP,LOCALTIMESTAMP);"
end
# Rails 에서  scaffold로 만들어진 모델은 기본적인 구조 이외에 create_at, update_at의 시간 데이터를 가짐
# insert 문으로 같이 넣어주면 rails에서도 데이터를 한번에 볼 수 있음

trap "INT"  do proxy.shutdown end
trap "TERM" do proxy.shutdown end

proxy.start

이런식으로 Proxy를 통해 들어온 데이터를 PostgreSQL로 넘기고, 이를 Rails에서 보거나 제어할 수 있어집니다. 여기에 테스트 로직이나 분석 규칙을 넣으면 WASE의 뼈대가 완성되죠.

원래는 ES를 붙이려고 했는데, 아직은 좀 고민이 생기는 부분입니다. 과연 웹 요청의 데이터가 ES로 제어할만큼 큰 데이터들일까.. 라는 생각이죠. (당장 Burp만 봐도 굉장히 많은데 뭔소리)

물론 ES로 넘기는 것도 어렵진 않습니다. 그냥.. API로 던져주면 끝 (사실 Rails에 붙이기 귀찮아서 PostgreSQL로.. 웹 요청 자체가 틀이 잡혀있기 떄문에 굳이 ES가 필요할까 함)