Choosing upstream proxy during runtime depending on traffic contents

hi,

is it possible to switch between several upstream proxies during runtime (preferably using scripting)?

I’m struggling debugging third party app generating lots of AMF traffic, I am using Charles to examine catched AMF, as it is easier to use (has gui :). The problem is, that Charles can’t filter out useless traffic (it depends on specific AMF contents) and I need to search for interesting data one transaction by another :confused:

It would be great to setup mitmproxy to forward useful (and only this) traffic upstream via Charles while passing all the rest directly to internet.

Is it possible as for now?

Hi @internety,

Did you take a look at https://github.com/mitmproxy/mitmproxy/blob/master/examples/change_upstream_proxy.py ? I think that should just do what you are looking for.

I’ve just tried that out, without success. Here’s my short and dirty example:

from libmproxy.script import concurrent
from libmproxy.models import decoded
from amfast import decoder

@concurrent
def request(context, flow):
    with decoded(flow.request):
        m=decoder.decode_packet(flow.request.content)
        try:        
            for t in range(len(m.messages)):
                me=m.messages[t]
                if me.body.body['type']<>1001:
                    flow.live.change_upstream_proxy_server("localhost", 8888)
        except:
            pass

then I ran mitmdump like:
mitmdump -U http://localhost:5311 -p5310 -s changeupstream.py

assuming that I have one proxy on port 5311 and another on 8888, while setting port 5310 in my browser…

that gave me an unusual error output:
> Exception in thread ScriptThread:
> Traceback (most recent call last):
> File “/usr/lib/python2.7/threading.py”, line 801, in __bootstrap_inner
> self.run()
> File “/usr/lib/python2.7/threading.py”, line 754, in run
> self.__target(*self.__args, **self.__kwargs)
> File “/usr/local/lib/python2.7/dist-packages/libmproxy/script/concurrent.py”, line 35, in run
> fn(*args, **kwargs)
> File “differenttypesviacharles.py”, line 21, in request
> m=decoder.decode_packet(flow.request.content)
> BufferError: Attempted to read past end of buffer.
> 127.0.0.1 POST http:// xxx /GameServer03/amf
> << 200 OK 760B
> Exception in thread ScriptThread:
> Traceback (most recent call last):
> File “/usr/lib/python2.7/threading.py”, line 801, in __bootstrap_inner
> self.run()
> File “/usr/lib/python2.7/threading.py”, line 754, in run
> self.__target(*self.__args, **self.__kwargs)
> File “/usr/local/lib/python2.7/dist-packages/libmproxy/script/concurrent.py”, line 35, in run
> fn(*args, **kwargs)
> File “differenttypesviacharles.py”, line 21, in request
> m=decoder.decode_packet(flow.request.content)
> DecodeError: Unknown client type.
> 127.0.0.1:41154: clientconnect
> 127.0.0.1 POST http:// xxx /GameServer03/amf
> << 200 OK 1.32kB

each time it throws BufferError once, then DecodeError from amfast (while I am sure it works)
I am using mitmproxy 0.16

*update using mitmproxy 0.17:
still nothing, but error message is much shorter:
Script error:
Unknown client type.
(with both versions I tried proxy on port 8888 is not receiving any traffic)

Well, both errors already happen in the decoder.decode_packet call, so I doubt this is a mitmproxy issue.

I bet it’s not, no matter how it looks like, because I am using same amfast version exactly the same way as I’ve done with success. I’ve even tried that on same traffic I processed successfully.

I’ve just started digging around to figure out the real reason, as I have some spare time today.
Will surely post any results in this thread.