jrmdev / mitm_relay

Hackish way to intercept and modify non-HTTP protocols through Burp & others.
Apache License 2.0
582 stars 97 forks source link

Modification of TCP packets #6

Closed alex4628 closed 6 years ago

alex4628 commented 6 years ago

Hi,

I would like to say this is by far the best and most practical non-HTTP proxy that I’ve used!

I am currently doing research on thick client testing. The app that I’m testing uses the TCP protocol to connect to a remote database. One of the requests that the app sends contains a SELECT query that dynamically generates a SQL statement based on the credentials provided in the login form.

I would like to change the SQL query’s …WHERE username = ‘admin’ clause to …WHERE username = ‘bob’

I am able to replace admin with bob using the following script:

 def handle_request(client_request):
    #'admin' is '61646d696e' in HEX
    #'bob' is '626f62' in HEX

    modified_request = client_request.replace('\x00\x61\x00\x64\x00\x6d\x00\x69\x00\x6e\x00', '\x00\x62\x00\x6f\x00\x62\x00')
    return modified_request

However, due to the fact that the length of the modified TCP packet is different to the original packet the thick client that I’m testing just crashes after I receive the FIN, ACK response from the database server.

Your MySQL demo states that the corresponding fields in the TCP protocol will have to be changed if I make changes to the length of the SQL message. Do you have any ideas/suggestions how I should do that? I presume I will have to add some python code to the above script that I’m sending using your tool? I am not fluent in Python so I'm not sure how easy it will be to achieve this task.

Thank you!

jrmdev commented 6 years ago

Hi, Thank you for your comments.

In a MySQL packet. the first 3 bytes of the TCP payload represent the payload length. You will need to update this. Below is a screenshot of a MySQL query packet capture.

image

You can see that the Packet length field is specified in the first 3 bytes. The following byte ('\x00') is the packet number, and the next one ('\x03') indicates that it's a request. You can reuse those 2 bytes from the original request. Therefore you can rebuild the packet like this:

Length (3 bytes) + \x00 + \x03 + Payload

Here is some example code:

>>> import struct
>>> payload = 'Select "NEW_RESULT" from DUAL--'
>>> new_length = struct.pack('<Q', len(payload))[:3]
>>> modified_request = new_length + client_request[3:5] + payload
>>> modified_request
'\x1f\x00\x00\x00\x03Select "NEW_RESULT" from DUAL--'
>>> 

Hope this helps.

alex4628 commented 6 years ago

Thank you for your informative reply! It all makes sense now.