move mitmproxy
@@ -1,66 +0,0 @@
|
||||
.. _30second:
|
||||
|
||||
Client playback: a 30 second example
|
||||
====================================
|
||||
|
||||
My local cafe is serviced by a rickety and unreliable wireless network,
|
||||
generously sponsored with ratepayers' money by our city council. After
|
||||
connecting, you are redirected to an SSL-protected page that prompts you for a
|
||||
username and password. Once you've entered your details, you are free to enjoy
|
||||
the intermittent dropouts, treacle-like speeds and incorrectly configured
|
||||
transparent proxy.
|
||||
|
||||
I tend to automate this kind of thing at the first opportunity, on the theory
|
||||
that time spent now will be more than made up in the long run. In this case, I
|
||||
might use Firebug_ to ferret out the form post
|
||||
parameters and target URL, then fire up an editor to write a little script
|
||||
using Python's urllib_ to simulate a submission.
|
||||
That's a lot of futzing about. With mitmproxy we can do the job
|
||||
in literally 30 seconds, without having to worry about any of the details.
|
||||
Here's how.
|
||||
|
||||
1. Run mitmdump to record our HTTP conversation to a file.
|
||||
----------------------------------------------------------
|
||||
|
||||
>>> mitmdump -w wireless-login
|
||||
|
||||
2. Point your browser at the mitmdump instance.
|
||||
-----------------------------------------------
|
||||
|
||||
I use a tiny Firefox addon called `Toggle Proxy`_ to switch quickly to and from mitmproxy.
|
||||
I'm assuming you've already :ref:`configured
|
||||
your browser with mitmproxy's SSL certificate
|
||||
authority <certinstall>`.
|
||||
|
||||
3. Log in as usual.
|
||||
-------------------
|
||||
|
||||
And that's it! You now have a serialized version of the login process in the
|
||||
file wireless-login, and you can replay it at any time like this:
|
||||
|
||||
>>> mitmdump -c wireless-login
|
||||
|
||||
Embellishments
|
||||
--------------
|
||||
|
||||
We're really done at this point, but there are a couple of embellishments we
|
||||
could make if we wanted. I use wicd_ to
|
||||
automatically join wireless networks I frequent, and it lets me specify a
|
||||
command to run after connecting. I used the client replay command above and
|
||||
voila! - totally hands-free wireless network startup.
|
||||
|
||||
We might also want to prune requests that download CSS, JS, images and so
|
||||
forth. These add only a few moments to the time it takes to replay, but they're
|
||||
not really needed and I somehow feel compelled to trim them anyway. So, we fire up
|
||||
the mitmproxy console tool on our serialized conversation, like so:
|
||||
|
||||
>>> mitmproxy -r wireless-login
|
||||
|
||||
We can now go through and manually delete (using the :kbd:`d` keyboard shortcut)
|
||||
everything we want to trim. When we're done, we use :kbd:`w` to save the
|
||||
conversation back to the file.
|
||||
|
||||
.. _Firebug: https://getfirebug.com/
|
||||
.. _urllib: https://docs.python.org/library/urllib.html
|
||||
.. _Toggle Proxy: https://addons.mozilla.org/en-us/firefox/addon/toggle-proxy-51740/
|
||||
.. _wicd: https://launchpad.net/wicd
|
||||
@@ -1,128 +0,0 @@
|
||||
.. _gamecenter:
|
||||
|
||||
Setting highscores on Apple's GameCenter
|
||||
========================================
|
||||
|
||||
The setup
|
||||
---------
|
||||
|
||||
In this tutorial, I'm going to show you how simple it is to creatively
|
||||
interfere with Apple Game Center traffic using mitmproxy. To set things up,
|
||||
:ref:`install the mitmproxy root certificate <certinstall>`. Then
|
||||
start mitmproxy on your desktop, and configure the iPhone to use it as a proxy.
|
||||
|
||||
|
||||
Taking a look at the Game Center traffic
|
||||
----------------------------------------
|
||||
|
||||
Lets take a first look at the Game Center traffic. The game I'll use in this
|
||||
tutorial is `Super Mega Worm`_ - a great little retro-apocalyptic sidescroller for the iPhone:
|
||||
|
||||
.. image:: supermega.png
|
||||
:align: center
|
||||
|
||||
|
||||
After finishing a game (take your time), watch the traffic flowing through
|
||||
mitmproxy:
|
||||
|
||||
.. image:: one.png
|
||||
:align: center
|
||||
|
||||
We see a bunch of things we might expect - initialisation, the retrieval of
|
||||
leaderboards and so forth. Then, right at the end, there's a POST to this
|
||||
tantalising URL:
|
||||
|
||||
.. code-block:: none
|
||||
|
||||
https://service.gc.apple.com/WebObjects/GKGameStatsService.woa/wa/submitScore
|
||||
|
||||
The contents of the submission are particularly interesting:
|
||||
|
||||
.. code-block:: xml
|
||||
|
||||
<!--(block|syntax("xml"))-->
|
||||
<plist version="1.0">
|
||||
<dict>
|
||||
<key>scores</key>
|
||||
<array>
|
||||
<dict>
|
||||
<key>category</key>
|
||||
<string>SMW_Adv_USA1</string>
|
||||
<key>context</key>
|
||||
<integer>0</integer>
|
||||
<key>score-value</key>
|
||||
<integer>0</integer>
|
||||
<key>timestamp</key>
|
||||
<integer>1363515361321</integer>
|
||||
</dict>
|
||||
</array>
|
||||
</dict>
|
||||
</plist>
|
||||
<!--(end)-->
|
||||
|
||||
This is a `property list`_, containing an identifier for the game,
|
||||
a score (55, in this case), and a timestamp. Looks pretty simple to mess with.
|
||||
|
||||
Modifying and replaying the score submission
|
||||
--------------------------------------------
|
||||
|
||||
Lets edit the score submission. First, select it in mitmproxy, then press
|
||||
:kbd:`enter` to view it. Make sure you're viewing the request, not the response -
|
||||
you can use :kbd:`tab` to flick between the two. Now press :kbd:`e` for edit. You'll
|
||||
be prompted for the part of the request you want to change - press :kbd:`r` for
|
||||
raw body. Your preferred editor (taken from the EDITOR environment variable) will
|
||||
now fire up. Lets bump the score up to something a bit more ambitious:
|
||||
|
||||
.. code-block:: xml
|
||||
|
||||
<!--(block|syntax("xml"))-->
|
||||
<plist version="1.0">
|
||||
<dict>
|
||||
<key>scores</key>
|
||||
<array>
|
||||
<dict>
|
||||
<key>category</key>
|
||||
<string>SMW_Adv_USA1</string>
|
||||
<key>context</key>
|
||||
<integer>0</integer>
|
||||
<key>score-value</key>
|
||||
<integer>2200272667</integer>
|
||||
<key>timestamp</key>
|
||||
<integer>1363515361321</integer>
|
||||
</dict>
|
||||
</array>
|
||||
</dict>
|
||||
</plist>
|
||||
<!--(end)-->
|
||||
|
||||
Save the file and exit your editor.
|
||||
|
||||
The final step is to replay this modified request. Simply press :kbd:`r` for replay.
|
||||
|
||||
|
||||
The glorious result and some intrigue
|
||||
-------------------------------------
|
||||
|
||||
.. image:: leaderboard.png
|
||||
:align: center
|
||||
|
||||
And that's it - according to the records, I am the greatest Super Mega Worm
|
||||
player of all time.
|
||||
|
||||
There's a curious addendum to this tale. When I first wrote this tutorial, all
|
||||
the top competitors' scores were the same: 2,147,483,647 (this is no longer the
|
||||
case, because there are now so many fellow cheaters using this tutorial). If
|
||||
you think that number seems familiar, you're right: it's 2^31-1, the maximum
|
||||
value you can fit into a signed 32-bit int. Now let me tell you another
|
||||
peculiar thing about Super Mega Worm - at the end of every game, it submits
|
||||
your highest previous score to the Game Center, not your current score. This
|
||||
means that it stores your highscore somewhere, and I'm guessing that it reads
|
||||
that stored score back into a signed integer. So, if you _were_ to cheat by the
|
||||
relatively pedestrian means of modifying the saved score on your jailbroken
|
||||
phone, then 2^31-1 might well be the maximum score you could get. Then again,
|
||||
if the game itself stores its score in a signed 32-bit int, you could get the
|
||||
same score through perfect play, effectively beating the game. So, which is it
|
||||
in this case? I'll leave that for you to decide.
|
||||
|
||||
.. _Super Mega Worm: https://itunes.apple.com/us/app/super-mega-worm/id388541990?mt=8
|
||||
.. _property list: https://en.wikipedia.org/wiki/Property_list
|
||||
|
Before Width: | Height: | Size: 438 KiB |
|
Before Width: | Height: | Size: 138 KiB |
|
Before Width: | Height: | Size: 91 KiB |
@@ -1,89 +0,0 @@
|
||||
.. _transparent-dhcp:
|
||||
|
||||
Transparently proxify virtual machines
|
||||
======================================
|
||||
|
||||
This walkthrough illustrates how to set up transparent proxying with mitmproxy.
|
||||
We use VirtualBox VMs with an Ubuntu proxy machine in this example,
|
||||
but the general *Internet <--> Proxy VM <--> (Virtual) Internal Network* setup can be applied to
|
||||
other setups.
|
||||
|
||||
1. Configure Proxy VM
|
||||
---------------------
|
||||
|
||||
On the proxy machine, **eth0** is connected to the internet. **eth1** is connected to the internal
|
||||
network that will be proxified and configured to use a static ip (192.168.3.1).
|
||||
|
||||
VirtualBox configuration
|
||||
^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
|
||||
.. image:: transparent-dhcp/step1_vbox_eth0.png
|
||||
|
||||
.. image:: transparent-dhcp/step1_vbox_eth1.png
|
||||
|
||||
VM Network Configuration
|
||||
^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
|
||||
.. image:: transparent-dhcp/step1_proxy.png
|
||||
:align: center
|
||||
|
||||
2. Configure DHCP and DNS
|
||||
-------------------------
|
||||
|
||||
We use dnsmasq to provide DHCP and DNS in our internal network.
|
||||
Dnsmasq is a lightweight server designed to provide DNS (and optionally
|
||||
DHCP and TFTP) services to a small-scale network.
|
||||
|
||||
- Before we get to that, we need to fix some Ubuntu quirks:
|
||||
**Ubuntu >12.04** runs an internal dnsmasq instance (listening on loopback only) by default
|
||||
`[1] <https://www.stgraber.org/2012/02/24/dns-in-ubuntu-12-04/>`_. For our use case, this needs
|
||||
to be disabled by changing ``dns=dnsmasq`` to ``#dns=dnsmasq`` in
|
||||
**/etc/NetworkManager/NetworkManager.conf** and running
|
||||
|
||||
>>> sudo restart network-manager
|
||||
|
||||
afterwards.
|
||||
- Now, dnsmasq can be be installed and configured:
|
||||
|
||||
>>> sudo apt-get install dnsmasq
|
||||
|
||||
Replace **/etc/dnsmasq.conf** with the following configuration:
|
||||
|
||||
.. code-block:: none
|
||||
|
||||
# Listen for DNS requests on the internal network
|
||||
interface=eth1
|
||||
# Act as a DHCP server, assign IP addresses to clients
|
||||
dhcp-range=192.168.3.10,192.168.3.100,96h
|
||||
# Broadcast gateway and dns server information
|
||||
dhcp-option=option:router,192.168.3.1
|
||||
dhcp-option=option:dns-server,192.168.3.1
|
||||
|
||||
Apply changes:
|
||||
|
||||
>>> sudo service dnsmasq restart
|
||||
|
||||
Your **proxied machine** in the internal virtual network should now receive an IP address via DHCP:
|
||||
|
||||
.. image:: transparent-dhcp/step2_proxied_vm.png
|
||||
|
||||
3. Redirect traffic to mitmproxy
|
||||
------------------------------------------
|
||||
|
||||
To redirect traffic to mitmproxy, we need to add two iptables rules:
|
||||
|
||||
.. code-block:: none
|
||||
|
||||
iptables -t nat -A PREROUTING -i eth1 -p tcp --dport 80 -j REDIRECT --to-port 8080
|
||||
iptables -t nat -A PREROUTING -i eth1 -p tcp --dport 443 -j REDIRECT --to-port 8080
|
||||
|
||||
4. Run mitmproxy
|
||||
----------------
|
||||
|
||||
Finally, we can run mitmproxy in transparent mode with
|
||||
|
||||
>>> mitmproxy -T
|
||||
|
||||
The proxied machine cannot to leak any data outside of HTTP or DNS requests.
|
||||
If required, you can now :ref:`install the mitmproxy certificates on the proxied machine
|
||||
<certinstall>`.
|
||||
|
Before Width: | Height: | Size: 241 KiB |
|
Before Width: | Height: | Size: 28 KiB |
|
Before Width: | Height: | Size: 28 KiB |
|
Before Width: | Height: | Size: 36 KiB |