`The rubyist'【えぬ】の日記

 | 

2008-04-07

[]Doorman@JUMPERZ.NETのセッション情報をテキストログにダンプする Doorman@JUMPERZ.NETのセッション情報をテキストログにダンプする - `The rubyist'【えぬ】の日記 を含むブックマーク はてなブックマーク - Doorman@JUMPERZ.NETのセッション情報をテキストログにダンプする - `The rubyist'【えぬ】の日記

Doorman@JUMPERZ.NETHTTP/HTTPS通信のモニタリングを行うローカルプロキシツールです。

このソフトでは「HTTP Sessions」→「File」→「Save Sessions」によって通信記録をファイルに保存することができますが、JavaのXMLEncoderとやらwによるシリアライズされた形式です。

今回、これを読みやすいテキスト形式(BurpProxyぽい)に変換するスクリプトをREXMLの勉強がてら作りました。

それにしてもREXMLはいくら書いても覚えられねえ…

これまた添削や「それ車輪ry」といったツッコミを募集します。誰か つД`)タスケレ !!

#!/usr/bin/ruby
# Doorman@JUMPERZ.NET のセッション情報をテキストログにダンプする
# v0.01.080407

class DoormanSessionListener
  require 'rexml/parsers/streamparser'
  require 'rexml/parsers/baseparser'
  require 'rexml/streamlistener'
  require 'zlib'

  include REXML::StreamListener

  def initialize(io)
    @items = {}
    @io = io
    @object = []
    @log = ""
  end

  def tag_start(tag, attr)
    case tag
     when "object"
      @object.push(
       if(attr["class"] == "net.jumperz.app.MDoorman.MSession")
        @prop = {}
        @prop_got = nil
        true
       else
        false
       end
      )      
     when "void"
      @prop_got = attr["property"]
     when "string", "int"
      @cond = true
      @text = ""
    end
  end

  def tag_end(tag)
    case tag
     when "string", "int"
      return unless @text

      @prop[@prop_got] = 
      case @prop_got
       when "requestString", "responseString"
        [@text].pack("H*")
       else
        @text
      end
      @cond = false
      @text = nil

     when "void"
      if(@prop_got == "SSocketString")
        parse_server(@prop["SSocketString"])
      end
     when "object"
      if(@object.pop)
        @log << format_one_session()
      end
    end
  end

  def parse_server(sss)
    https = (sss =~ /\[SSL/)
    sss =~ %r!Socket\[addr=([^/]+)/([^,]+),port=(\d+)!
    @server = %Q!#{(https ? "https" : "http")}://#{$1}:#{$3} [#{$2}]!
  end

  def text(text)
    @text << text if @text
  end
  alias cdata text

  def format_one_session
    return <<"EOF"
======================================================
#{@prop["time"]} #{@server}
======================================================
#{@prop["requestString"]}

======================================================
#{@prop["responseString"]}

======================================================



EOF
  end

  def parse
    zio = (Zlib::GzipReader.new(@io) rescue @io)
    REXML::Parsers::StreamParser.new(zio, self).parse
    @log
  end

  attr_reader :log, :io
end

if __FILE__ == $0
  print DoormanSessionListener.new($<).parse
end
 |