#!/usr/bin/ruby =begin ** ** xmitm.rb ** 26/DEC/2007 ** ETD-Software ** - Daniel Martin Gomez ** ** Desc: ** Man in the Middle ASCII based TCP communications ** ** Version: ** v1.0 [26/Dec/2007]: first released ** ** This program is free software: you can redistribute it and/or modify ** it under the terms of the GNU General Public License as published by ** the Free Software Foundation, either version 2 of the License, or ** (at your option) any later version. ** ** This program is distributed in the hope that it will be useful, ** but WITHOUT ANY WARRANTY; without even the implied warranty of ** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the ** GNU General Public License for more details. ** ** You should have received a copy of the GNU General Public License ** along with this program. If not, see . =end require 'socket' require 'net/http' # ------------------------------------------------------------ config # local end point, the client will connect here $local_host = 'localhost' $local_port = 1234 # remote end point, the client wishes to connect here $remote_host = 'www.nomejortu.com' $remote_port = 1234 # external proxy tool $proxy_host = 'localhost' $proxy_port = 8080 # external dummy http server $dummyhttp_host = 'localhost' $dummyhttp_port = 2000 # end of message: client and server end their messages with a NULL byte $eom = '' << 0 # ------------------------------------------------------------ /config # create a server that accepts connections from the client server = TCPServer.new($local_host, $local_port) while(local = server.accept ) do # everytime we accept a connection for the client, we open a connection # with the server to stablish the dialog. remote = TCPSocket.new($remote_host, $remote_port) # if one of the ends of the communication closes the socket, we # toggle this flag alive = true while alive do result = select([local, remote], nil, nil) if result != nil then for socket in result[0] # detect if one end of the connection is closed and # close the other end if (socket.eof?) local.close remote.close alive = false break end # read the information that one peer wants to send to the other data = socket.gets($eom) # encapsulate the data into an HTTP proxy request res = Net::HTTP.new($proxy_host, $proxy_port).start do |http| req = Net::HTTP::Post.new("http://#{$dummyhttp_host}:#{$dummyhttp_port}/") req.body= data http.request(req) end modified_data = res.body.chomp # send the modified data to the other end of the connection if (socket == local) remote.puts(modified_data) else local.puts(modified_data) end socket.flush end end end end