I'm attempting to reverse engineer (without dissecting the source code, as my understanding is that reverse engineering by analyzing input and output and building something from scratch that fits is both far more legal and less monotonous/brain-dead than decompiling/de-obfuscating the program) a program that acts as client to a server, and one of the main systems I need to figure out is how they communicate (the exact meaning of each byte of data sent over the internet). The way I would like to go about doing this is by developing a program from scratch that attempts to imitate the client, but that acts as middle-man to both client and server so that I can easily see if the output my work-in-progress program would provide matches the actual client's output and how it differs.I'm not sure how to go about doing this, though. I think the site the client connects to is hard-coded into it; is there a way to make the client think that it is talking to the server, and the server to think that it is talking to the client, when in reality both are talking to my in-progress program? I would like for both my program and the client to be on the same (physical) system. I've been using a packet sniffer to monitor communication between the client and server, but it would be much simpler and convenient if I could have my program act as middle-man. I'm using a Lubuntu 15.04 system as my primary system currently, if that helps.
Putting an application in between client and server
linux;networking
You may want to have a look at mitmproxy. This allows you to intercept and modify http(s) traffic, which may or may not be what you need, but it also has tools like mitmdump that just dump what's going over the connection.Mitmproxy also has instructions about setting up the linux tcp stack using iptables to redirect connections. I guess this is the main part of what you're trying to achieve.In your setup, the easiest thing you could do is probably create a virtual machine using virtualbox, running the client within the machine, using iptables inside the machine to redirect server connections to your host, and run the proxy on the host. The advantage of using a virtual machine is that whatever you install/configure on your VM won't interfere with your host, where you may not want to mess with the network to reduce the risk of breaking other things, and you can create a snapshot and go back to it of you break something and don't remember what exactly you've done.Then, on the VM, do something likeiptables -t nat -A OUTPUT -p tcp --dport 1234 -j DNAT --to-destination 1.2.3.4:1234to redirect all traffic from the client, independent from target ip, to the host (assuming the host is 1.2.3.4). The, on the host, write a program to listen on port 1234, dump all data, and pass through to real.server.ip:1234. This way, you don't have to mess with the IP configuration of the host.If you don't want to use a VM, you could also useiptables -t nat -A OUTPUT -p tcp --dport 1234 -j DNAT --to-destination 127.0.0.1:1234iptables -t nat -A OUTPUT -p tcp --dport 1235 -j DNAT --to-destination :1234and have your program listen on port 1234, and connect to 1235 on the real server. The second iptables entry will redirect this to 1234 again, and use the IP the program requested, since you just used a port without an IP in the --to-destination argument. Your client (that uses port 1234) always gets redirected to localhost, and the proxy, that connects to 1235, will get redirected to 1234. Obviously, the order of iptables commands is important here.You can use the real server ip or name as well, of course:iptables -t nat -A OUTPUT -p tcp --dport 1235 -j DNAT --to-destination 192.168.17.135:1234iptables -t nat -A OUTPUT -p tcp --dport 1235 -j DNAT --to-destination real.server.name:1234but note that real.server.name gets resolved the moment you start the iptables command, not when the packet gets sent. So, if your real.server.address changes later, for example if it's behind a dynamic IP, you'll have to remove the iptables entry and create a new one.And to minimize impact on your machine, where you might have an unrelated program connect to an unrelated server on port 1235, you might want to restrict changing the port to one particular server only:iptables -t nat -A OUTPUT -p tcp --dest 192.168.17.135 --dport 1235 -j DNAT --to-destination 192.168.17.135:1234