Minecraft packet sniffing in python - python-3.x

My aim is to sniff through the Minecraft packets in python and decode the data to get this information:
The server the person is playing on
The player's coordinates on that server
The direction the player is pointing
The player's health
So far, this is my code:
from scapy.all import *
def test(pkt):
payload = pkt
payload = bytes(payload)
if __name__ == '__main__':
single = sniff(filter="tcp and port 25565", prn=test)
The pkt variable is a scapy packet object and therefore has attributes such as .original and .payload. The code so far displays Minecraft's packets, however, I am unsure of how to decode them or what attribute to use. I have found the protocol documentation for 1.12.2 servers.
Thank you for any help in advance.

"As of 12w17a, Minecraft uses encrypted connections for online-mode servers."
https://wiki.vg/Protocol_Encryption
Packet sniffing the connection between a minecraft client and an online-mode server for the purpose of collecting the data you are attempting to collect would be almost impossible.
Maybe consider reading minecraft's memory instead? It would be much simpler if you are attempting to collect this data from a game instance on the same device.

Better late then never I guess.
Public private key encryption is a way to prevent others reading it.
Even by other means you could negotiate a secret:
Let's say you have a chest, put something in it (secret key) and put a padlock on it and send it to someone. The receiver can't open it but he can put an additional padlock on it.
So he locks the chest with an additional lock and sends it back to you. Once you receive the chest it has 2 locks. You remove your lock and send it back again. The chest now only contains the lock of the receiver which he will be able to open when he recieves the chest again.
The chest was never in an unlocked state while in transit and anyone other then the sender or receiver will have been able to see what's inside.

Related

Design of backend TCP/IP communication with Python

I have a theoretical problem i cannot find solution that easily and would love some feedback on my thought process now.
I took over this backend project after colleague, so i inherited some of his thought processes and designs, i never really designed something like this on my own, here is a problem:
I am programming backend in python between a measuring unit(MU) running on LabView, which provides me byte data over tcp/ip socket -> i parse it, cache it, store it in db, whatever, and then send it to frontend. Thing is that it is now set up as me being the server listening for connections and data transfers from MU, but data needs to flow both ways, he needs to listen too for my requests of his data. For some reason it is now programmed so that there is new connection created and closed on my server socket.
The following code is oversimplified, but i hope u get the logic.
self.sock = sock.socket(...) #my listening socket
self.sock.bind(self.host, self.port)
self.sock.listen(1)
client_sock, client_address = self.socket.accept()
data = client_sock.recv(100)
client_sock.close()
client_sock, client_address = self.socket.accept()
and so it goes on and on 4ever, I have a new thread starting for each accept(), so there can be more connections made on this socket.
Thing is as I have found out, there is not a good way to initialize connection from me to MU when i want to send data, since connections is already closed and here is where i need your help. Colleague told me that there is good reason for it to be this way since the connections are atomic and if something goes wrong, the bytestream wont be so corrupt for next data transfer, since it is whole new connection. But I find it hard to accept, my instincts say that I should rather keep the connection open, the traffic there is very frequent.
IS IT SAFE?
By this logic i see no other option than for him to have listening socket as well. How can i connect to him otherwise? no way right?
But if i could just accept this one connection and use this one for two-way traffic, is it ok? Or should both of us be server AND client? The MU should not be doing any backend stuff, we try to keep it very simple in its purpose.
I would probably go with one connection instinctively, but this colleague of mine who handed it over to me confused me with this one connection per transfer idea.
if u managed to read this far, thank you and your thoughts or experiences are welcome!
Thank you.
It's OK to keep a connection for two-way communication.
What exactly could happen to bytestream, so it will become "corrupted" ? Data is transferred in chunks, and if one chunk becomes invalid, you will lost it anyway.
The problem here might be that the next chunks could not be distinguished, but it's easy to defend from such cases. For example, you can use frame/message headers. After all, you can always kill connection on server side if something goes wrong (forcing other side to establish a new one).
It's also worth to mention, that if your MU was a real sensor placed in the field it would become complicated to connect to it since it's address (IP) changes dynamically.

Client server game packet injection

I am trying to learn more about security while developing my online game.
Is it possible and how difficult is it to intercept a packet sent from the server, modify it by using some software and send back data to the server?
Here's a scenario:
A player enters a battle against an AI enemy. A player loses the battle and at the end of the battle, the packet is sent back to the server of what has happened. Would it be possible to modify this packet before it is sent and tell the server that the player has won the battle instead? How would one read this data, and modify it?
Would it be possible to go as far as to say the player entered a battle against 1 enemy but send a packet to the server saying the player has won the battle against 20 enemies? (assuming the server has no implementation of protecting itself from this)
Considering your scenario, if you assume the packets between the clients and the server are encrypted then the possibility of the attack happening is fairly low (Of course this depends on the encryption used).
But let's consider unencrypted packets, a man-in-the-middle attack could be possible and is not difficult to perform. This would require the attacker to be able to understand your packet being sent: for instance, if you have a 'win/lose' bit somewhere and the attacker knows its exact position then he could craft a different packet (check out scapy module in python if you're into crafting packets).
There are tools for intercepting packets, the most common one is Wireshark. The Scapy module for example allows you to sniff packets and send a packet at the same time making it easy for this scenario.
The winning against 20 at once scenario also depends on how the server is handling the game on its end (e.g. does it accept more than one game per user at a time?)

How the socket server knows the client transform data over

In the socket level, when the connection is built, the server will continue read data from the socket, my question is how the server will knows the client won’t send any data?
how the server will knows the client won’t send any data
It doesn't. One option is to scan for pre-agreed-upon "end of message" byte sequence. When server sees this byte sequence, it considers message fully received. If there's more data in the buffer, it belongs to another message.
Or the client must advertise its message length ahead of time. "I'm going to send you X bytes now. Here they are: ..." The server then reads only X bytes from the socket and considers message fully received.
Take a look at redis protocol for an example of the second scheme. It's very simple and fully functional. It is so simple, in fact, that a full client can be implemented in only 20 lines of ruby.

Creating a log in for transformice

I heard the protocol changed..what now? IS there anychance i can make a bot now?
I am trying to make a sort of 'bot' which can connect to a Transformice server(its a game)and post messages.
Anyway, I'm having some trouble understanding how to send packets in python, and how to correctly encode them.
The packets code i found are from the API on this site : http://kikoo.formice.com/doku.php?id=start
Logging on is my problem.
I know I need to be using sockets, and I need to be using struct.pack, but how exactly can I send it?
I don't know if i made the connection the right way.
This is what they tell me to do:
(Establishing a connection)
To connect to the server, send a 28,1 packet to the server containing the protocol version, the connection key and the number 0x17ed (The loader's size).
Logging in
After you connect to the server successfully, the next thing to do is actually log in and join the game. If you already have a good packet building framework, this should be simple enough.
To log in, simply send an old protocol 26,4 packet with your username, the password hashed by sha256, a room to join3) and an origin url – “http://www.transformice.com/Transformice.swf?n=1335716949138” + base64(sha256(sha256(password)+salt)) (see on packet infos) seems to work just fine.
An example piece code that sends a login packet would be marvellous.
(this is what i got so far)
import socket
import struct
import time
from struct import pack, unpack
import hashlib
import sys
s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
s.connect(('www.transformice.com', 80))
print ('Connected')
I heard the protocol changed..what now?

a UDP socket based rateless file transmission

I'm new to socket programming and I need to implement a UDP based rateless file transmission system to verify a scheme in my research. Here is what I need to do:
I want a server S to send a file to a group of peers A, B, C.., etc. The file is divided into a number of packets. At the beginning, peers will send a Request message to the server to initialize transmission. Whenever S receives a request from a client, it ratelessly transmit encoded packets(how to encode is done by my design, the encoding itself has the erasure-correction capability, that's why I can transmit ratelessly via UDP) to that client. The client keeps collecting packets and try to decode them. When it finally decodes all packets and re-construct the file successfully, it sends back a Stop message to the server and S will stop transmitting to this client.
Peers request the file asynchronously (they may request the file at different time). And the server will have to be able to concurrently serve multiple peers. The encoded packets for different clients are different (they are all encoded from the same set source packets, though).
Here is what I'm thinking about the implementation. I have not much experience with unix network programming though, so I'm wondering if you can help me assess it, and see if it is possible or efficient.
I'm gonna implement the server as a concurrent UDP server with two socket ports(similar to TFTP according to the UNP book). One is to receive controlling messages, as in my context it is for the Request and Stop messages. The server will maintain a flag (=1 initially) for each request. When it receives a Stop message from the client, the flag will be set to 0.
When the serve receives a request, it will fork() a new process that use the second socket and port to send encoded packets to the client. The server keeps sending packets to the client as long as the flag is 1. When it turns to 0, the sending ends.
The client program is easy to do. Just send a Request, recvfrom() the server, progressively decode the file and send a Stop message in the end.
Is this design workable? The main concerns I have are: (1), is that efficient by forking multiple processes? Or should I use threads? (2), If I have to use multiple processes, how can the flag bit be known by the child process? Thanks for your comments.
Using UDB for file transfer is not best idea. There is no way for server or client to know if any packet has been lost so you would only know that during reconstruction assuming you have some mechanism (like counter) to detect lost packes. It would then be hard to request just one of those packets that got lost. And in the end you would have a code that would do what TCP sockets do. So I suggest to start with TCP.
Typical design of a server involves a listener thread that spawns a worker thread whenever there is a new client request. That new thread would handle communication with that particular client and then end. You should keep a limit of clients (threads) that are served simultaneously. Do not spawn a new process for each client - that is inefficient and not needed as this will get you nothing that you can't achieve with threads.
Thread programming requires carefulness so do not cut corners. Otherwise you will have hard time finding and diagnosing problems.
File transfer with UDP wil be fun :(
Your struct/class for each message should contain a sequence number and a checksum. This should enable each client to detect, and ask for the retransmission of, any missing blocks at the end of the transfer.
Where UDP might be a huge winner is on a local LAN. You could UDP-broadcast the entire file to all clients at once and then, at the end, ask each client in turn which blocks it has missing and send just those. I wish Kaspersky etc. would use such a scheme for updating all my local boxes.
I have used such a broadcast scheme on a CANBUS network where there are dozens of microControllers that need new images downloaded. Software upgrades take minutes instead of hours.

Resources