Sergio Proxy v0.2 Released
Updates in this Release
So after a ridiculously long period of procrastination, I finally got around to updating Sergio Proxy to make it remotely usable. I was never very happy with how the initial code turned out, but given that it was hacked out in a couple days just to test some ideas, I suppose that shouldn't be surprising. My original hope for it was to provide a very easy to extend plugin interface that allowed Python programmers to easily modify requests and responses during a MITM attack on HTTP. While you could extend it without too much trouble, it was far from perfect, and passing options to the thing was an atrocious mess. Worse, my hooks into Twisted weren't the most stable or fast, rendering it not very useful.
I believe I've solved some of these issues in this release, although you can certainly judge for yourself. I've made three major changes: first, rather than using my own transparent proxy classes for interacting with Twisted, I've instead started using Moxie Marlinspike's sslstrip to provide the proxy functionality. Although I didn't know it when I first started Sergio Proxy, sslstrip uses almost exactly the same method for creating the transparent proxy: extending the Twisted framework's HTTP proxy classes. Rather than duplicate effort to create something that would still be miles behind, I instead decided to focus on providing a convenient plugin interface that could hook sslstrip at various points during operation. This brings me to the second change: a new plugin interface that should make it ridiculously simple to extend Sergio Proxy. I've currently implemented three modules (SMBAuth, ArpSpoof, and Upsidedownternet), but really there are tons of other things that could be done. Finally, I completely revamped the logging and options code, which were virtually non-existent in my first release. Combined, these should make Sergio Proxy a nice framework for making use of HTTP MITM attacks. You can grab the new code here: https://code.google.com/p/sergio-proxy/downloads/list
Edit: I've also added a simple BrowserPwn plugin now, grab the current trunk to get it: https://code.google.com/p/sergio-proxy/source/checkout
Using and Abusing Sergio Proxy
So enough about the changes: how would one go about using it? Well, if all you want to do is evoke an SMB authentication attempt or launch the Upsidedownternet, just run sergio-proxy.py -h and choose your desired options. ArpSpoof will set up the MITM if you so desire (requires ettercap or arpspoof), and sslstrip will record what it normally does. If you want to do something else, though, you'll need to create a new plugin. Don't worry, it's quite simple!
First, you need to do a few simple things. The provided plugins provide good examples, but I will step through the required steps just in case. All plugins inherit from the Plugin class in plugins/plugin.py, and Sergio Proxy needs to know the subclass relationship, so you must do a "from plugins.plugin import Plugin" in every plugin file. No exceptions. Then, you need to define some class attributes to tell Sergio Proxy about your plugin. These are as follows: name (human friendly name), optname (option name to enable plugin), has_opts (needs to add opts to argparse object), and implements (a list of hooks it implements). If you require arguments, you need to implement the add_options function. It takes an argparse Parser object as its only argument, where you can then do with it as you please. Be warned, though: if your arguments conflict with others, you may have issues.
Now, you are ready to implement the actual functionality of your plugin. There are 5 functions that really matter, and you can see them in the base Plugin class: initialize, handleHeader, connectionMade, handleResponse, and finish. initialize is passed the namespace that argparse parsed, and is called whenever your plugin has been enabled by a command line switch and is going to be run. You should do any setup you require here rather than __init__, as you won't have options in __init__ and it entirely possible your module won't be run after that point. finish, likewise, is called on shutdown.
There are three points where Sergio Proxy hooks sslstrip by default right now: on connecting to the server prior to sending the victim's request, on receiving any header from the server, and prior to sending a response to the client. These functions are the other three functions I mentioned. It is quite simple to add more if necessary, but that's outside the scope of this post. Whenever sslstrip hits any of these three points during execution, Sergio Proxy checks to see if any plugin wants to hook that function and, if so, calls the function with arguments that were provided to the function call in sslstrip. Generally, if you have changes you want to send back to sslstrip, you should modify the request object, and not return anything. However, in the handleResponse hook this is not possible (as the local var data is used rather than an object attribute), and you must return a dictionary containing the modified arguments. This is currently the only case where this is necessary, but it's important to note.
Now, all you need to do is override these functions to do what you want. If you're wondering what information you have access to through the request object, it may be useful to either a.) hook the function you want and print out information about it at that time or b.) look through sslstrip and the Twisted proxy documentation. Also, the plugins I provided show some of the basic things you might want to do.
Hopefully you all find the new changes useful. If you end up writing a plugin, please feel free to submit it! If it was useful to you, it is likely it will be useful to others as well. Happy hacking
Sergio Proxy – Injecting, Modifying, and Blocking HTTP Traffic
Edit: You can grab new releases of this tool here: https://code.google.com/p/sergio-proxy/downloads/list
I've gotten all settled in my new place (finally), so I figured I should get caught up on my blog again. Lots of posts coming soon, I promise!
Today, I'm releasing a tool that I'll be working on (and with) a lot this summer that I'm calling Sergio Proxy: a Super Effective Regexer of Gathered Inputs and Outputs (download here). Yeah, yeah, I know: there are a billion other HTTP proxies out there that are way better than mine and I should use. I know all about them; I just wanted to make one myself. It's an interesting project, and I've learned a lot about HTTP proxies and the Twisted networking framework in the process. In addition, this tool has made it *much* easier for me to use Python to work with data captured from MITM'd HTTP connections than the other tools that I experimented with. I also blindly stumbled into an awesome topic for my next post too, to be released in the next few days (I'm particularly excited for this one). A big fat warning before we go on though: this is a very alpha release, so don't have your hopes way up. It still has a long way to go (like adding HTTPS support...:P).
So why did I originally start on this project? Mainly because Ettercap filters suck. I mean, really suck. Now, don't get me wrong, they can be useful in some situations, but automatically injecting data into HTTP sessions is not one of them. So why did I need Ettercap filters to inject data into HTTP sessions? Why, to attack SMB servers by means of challenge-hash cracking of course.
The attack works by injecting specially crafted HTML into a page that the victim is requesting that references a file located on a local samba server. The browser will then automatically try to authenticate with the remote server using its current user's credentials, exposing challenge hashes of the user's password on the wire, the first 7 characters of which can then be cracked with rainbow tables. To do this, we obviously need to first be in a position where we can modify the network traffic, which we can easily do using various methods (the most popular probably being ARP poisoning, but Ettercap has a number to chose from). However, once we have our MITM attack working, we are still presented with the problem of injecting our content into the HTML file.
In all the examples I have seen, the attack used Ettercap filters to do this injection, or an email with embedded HTML. Unfortunately, neither is very unreliable. All the filters that I tried seemed to corrupt the pages in the best case. In the worst case, it even prevented the victim from accessing certain servers, as the attack would try to kill gzip support on servers that required it. Obviously, this kind of degradation would be noticed even by the common computer user. As for the email, you still generally need to trick the user into viewing it before the attack will work. Not incredibly hard, but slower and still less reliable than a forced HTML injection.
After looking through some Wireshark captures, it seemed that the root problem in the Ettercap method was that the HTTP content length wasn't being modified, confusing the browser when it got more data than it was expecting. While it was probably possible to work around that in a similar manner as the gzip compression was broken, it wouldn't solve the heart of the problem: that trying to modify HTTP traffic at the TCP level is neither effective nor powerful.
Enter Sergio. It was obvious that what I was looking for was a forced, transparent HTTP proxy. I looked at some other proxies, and I probably could have adapted them to my purposes pretty easily. However, I decided I would rather code one myself, and get familiar with the inner workings of these tools, and to let me do everything in Python. I also have had my eye on the Twisted framework for awhile, and figured that this would be the perfect opportunity to familiarize myself with it.
To run this attack, all you need to do is run the included start_smbchall.py file. However, Sergio isn't just limited to evoking SMB authentication attempts of course. Sergio can inject, modify, and delete any content going through a victim's HTTP sessions, meaning that we can do much, much more with it than just this attack. In addition to this SMB fun, just for kicks, I also implemented my version of the classic Upsidedownternet
. Beyond these implemented attacks, Sergio makes it easy to insert some malicious Javascript, replace all the links on the page with links to a malicious site, prevent the victim from accessing any update sites, redirect them to malicious update sites (more on this later), monitor/record all the traffic going over the connection, or (a fun one) replace any exe file being downloaded with our own, backdoored, malicious executable. Unfortunately, I haven't gotten a chance to actually implement these attacks yet (lame), but I'll have a release soon enough with them included.
Anyway, now that you know the capabilities, here's how to use it. I promise, it's easy. You'll only need two files, start_proxy.py and UserMITM.py, and the module sergio_proxy installed somewhere in your PYTHONPATH (when in doubt, just throw it in a subdirectory named sergio_proxy). Example start_proxy and UserMITM files are included in the tarball in the examples folder. Basically, you just create a subclass of the included MITM class in UserMITM and add your own attacks into it. Then, when creating and starting your transparent proxy, you set UserMITM as transparent_proxy's new MITM instance, and you're ready to go. Pretty straightforward.
If you want to know more about what my proxy does and does not do, read the README. Here's the short of it though: does HTTP 1.0, does not do 1.1 (yet), does not MITM HTTPS (yet). Sorry if this is disappointing, but they weren't critical to my initial attack, and I will of course get these things fixed ASAP.
So that's Sergio Proxy. I could talk more, but it's probably easier for you to just download it and mess around. And please, if you implement some attacks with it, submit them! I'd be happy to add them in. As I mentioned earlier, I should be back in a few days will an interesting application of my tool. Until then, keep hacking.