C# Bot MITM

Inscrit
13 Septembre 2011
Messages
37
Reactions
0
#1
Bonsoir, j'essaye tant bien que mal de coder un bot en MITM et je me demandais si ce que je faisais était bon ou si je suis complètement à côté... (Enfin, il ne doit pas être si mal que ça puisque ça fonctionne jusqu'au packet 42).

Donc voici mon code (Oui je sais, c'est pas très propre, mais j'aimerais juste arriver à finaliser la connexion avant de rendre ça plus propre).

Code:
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;
using System.Net.Sockets;
using System.Threading;
using System.Net;

namespace BotMitm
{
    public partial class Form1 : Form
    {
        Socket _ServeurMitm, _ClientMitm, _Client;
        Thread _ClientThread, _ServeurThread;
        byte[] _buff;

        public Form1()
        {
            InitializeComponent();
        }

        private void button1_Click(object sender, EventArgs e)
        {
            _ServeurThread = new Thread(new ThreadStart(ReceptionClient));
            _ServeurThread.Start();
        }

        private void Form1_Load(object sender, EventArgs e)
        {
            _ServeurMitm = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
            _ClientMitm = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
        }



        private void ReceptionClientMitm()
        {
            while (_ClientMitm.Connected)
            {
                // On crée notre buffer dynamique.
               _buff = new byte[_ClientMitm.Available];

                // Si le buffer n'est pas vide, on le parse.
                if (_buff.Length != 0)
                {
                    _ClientMitm.Receive(_buff); // Récéption des données.       
                    ParseData(_buff);
                }
            }
        }


        private void ReceptionClient()
        {
            _ServeurMitm.Bind(new IPEndPoint(IPAddress.Parse("127.0.0.1"), 5555));

            Chat("Listening...");
            _ServeurMitm.Listen(10);

            _Client = _ServeurMitm.Accept();
            _ClientMitm.Connect("213.248.126.180", 5555);
            Chat("_ClientMitm Connecté");

            _ClientThread = new Thread(new ThreadStart(ReceptionClientMitm));
            _ClientThread.Start();

            while (_Client.Connected)
            {
                // On crée notre buffer dynamique.
                byte[] _buffer = new byte[_Client.Available];

                // Si le buffer n'est pas vide, on le parse.
                if (_buffer.Length != 0)
                {
                    _Client.Receive(_buffer); // Récéption des données.             
                    _ClientMitm.Send(_buffer);
                }
            }
        }


        private void TreatPacket(int PacketID, byte[] PacketContent)
        {
            Reader reader = new Reader(PacketContent);
            Writer writer = new Writer();

            switch (PacketID)
            {
                default:
                    _Client.Send(_buff);
                    break;
            }
        }





        private void Chat(string Text)
        {
            Action log_callback = (Action)delegate
            {
                textBox1.Text += Text + "\r\n";
                if (textBox1.TextLength - Text.Length < 0)
                    textBox1.SelectionStart = 0;
                else
                    textBox1.SelectionStart = textBox1.TextLength - Text.Length;

                textBox1.SelectionLength = Text.Length;
                textBox1.SelectionStart = textBox1.TextLength;
                textBox1.ScrollToCaret();

            };
            this.Invoke(log_callback);
        }

        private void ParseData(byte[] DataToParse)
        {
            // Déclaration des variables qui seront utilisées
            int index = 0;
            short id_and_packet_lenght_type, packet_lenght_type, packet_id;
            Int32 packet_lenght = 0;
            byte[] packet_content;

            // Lecture jusqu'à la fin de byte[] data
            while (index != DataToParse.Length)
            {
                // Décodage du header
                id_and_packet_lenght_type = (short)(DataToParse[index] * 256 + DataToParse[index + 1]); // Selection des 2 premiers octets du paquet
                packet_id = (short)(id_and_packet_lenght_type >> 2); // Récupérer l'ID du paquet
                packet_lenght_type = (short)(id_and_packet_lenght_type & 3); // Récupérer la taille de la taille de la longueur du paquet

                index += 2; // On se déplace 2 octets plus loin

                // Récupération de la taille du paquet
                switch (packet_lenght_type)
                {
                    case 0:
                        packet_lenght = 0;
                        break;
                    case 1:
                        packet_lenght = DataToParse[index];
                        break;
                    case 2:
                        packet_lenght = DataToParse[index] * 256 + DataToParse[index + 1];
                        break;
                    case 3:
                        packet_lenght = DataToParse[index] * 65536 + DataToParse[index + 1] * 256 + DataToParse[index + 2];
                        break;
                }

                // Récupération du contenu du paquet
                packet_content = new byte[(int)packet_lenght];
                Array.Copy(DataToParse, index + packet_lenght_type, packet_content, 0, packet_lenght);

                // Création de la variable contenant le contenu du paquet en héxadécimal
                string content_hex = string.Empty;
                int huit_bytes = 0;
                foreach (byte b in packet_content)
                {
                    if (huit_bytes == 8)
                    {
                        content_hex += "\r\n";
                        huit_bytes = 0;
                    }
                    content_hex += b.ToString("X2") + " ";
                    huit_bytes++;

                }

                // Jounalisation
                Chat("[Reçu] ID = " + packet_id + " | Taille du contenu = " + packet_lenght + "\r\n" + content_hex + "\r\n");

                // Traitement du paquet
                TreatPacket(packet_id, packet_content);


                // Définition de l'index qui démarre le paquet suivant
                index += packet_lenght + packet_lenght_type;
            }
        }


    }
}



Mais c'est surtout sur cette partie ci que j'aimerais avoir vos avis :

Code:
        private void ReceptionClientMitm()
        {
            while (_ClientMitm.Connected)
            {
                // On crée notre buffer dynamique.
               _buff = new byte[_ClientMitm.Available];

                // Si le buffer n'est pas vide, on le parse.
                if (_buff.Length != 0)
                {
                    _ClientMitm.Receive(_buff); // Récéption des données.       
                    ParseData(_buff);
                }
            }
        }


        private void ReceptionClient()
        {
            _ServeurMitm.Bind(new IPEndPoint(IPAddress.Parse("127.0.0.1"), 5555));

            Chat("Listening...");
            _ServeurMitm.Listen(10);

            _Client = _ServeurMitm.Accept();
            _ClientMitm.Connect("213.248.126.180", 5555);
            Chat("_ClientMitm Connecté");

            _ClientThread = new Thread(new ThreadStart(ReceptionClientMitm));
            _ClientThread.Start();

            while (_Client.Connected)
            {
                // On crée notre buffer dynamique.
                byte[] _buffer = new byte[_Client.Available];

                // Si le buffer n'est pas vide, on le parse.
                if (_buffer.Length != 0)
                {
                    _Client.Receive(_buffer); // Récéption des données.             
                    _ClientMitm.Send(_buffer);
                }
            }
        }


        private void TreatPacket(int PacketID, byte[] PacketContent)
        {
            Reader reader = new Reader(PacketContent);
            Writer writer = new Writer();

            switch (PacketID)
            {
                default:
                    _Client.Send(_buff);
                    break;
            }
        }

Voila merci d'avance et bonne soirée ^^'
 

ToOnS

Membre Actif
Inscrit
8 Avril 2009
Messages
974
Reactions
0
#2
Salut ca a l'aire pas trop mal sauf (encore et toujours le meme probleme partout) le parser qui gere pas les messages de + de 8k (donc sur plusieur paquets) ,enfin pour la connexion ca gene pas , y'a pas de message de + de 8k
Pour le 42 il faut que le serveur MITM envoie au client le message recu par le client MITM mais en changeant l'ip recu par 127.0.0.1 (donc fair un init 42 avec les valeurs de 42 sauf l'ip et l'envoyer) , deco le serveur mitm , le reco (pour faire croire au clientqu'on change de serveur) , deco le client MITM , le reco sur l'ip recu dans les 42 avant modification
 
Inscrit
13 Septembre 2011
Messages
37
Reactions
0
#3
Salut, merci pour ta réponse si rapide :)

Alors j'ai fais ce que tu m'as dis, mais j'ai une erreur:

Une connexion établie a été abandonnée par un logiciel de votre ordinateur hôte

Et sur D2 ça m'écrit :

Vous venez de déconnecter un personnage utilisant déjà ce compte.


Voila mon 42 :

Code:
switch (PacketID)
            {
                case 42:
                    SelectedServerDataMessage SSDM = new SelectedServerDataMessage();
                    SSDM.deserialize(reader);

                    this.ip = SSDM.address;
                    this.port = (int)SSDM.port;

                    SelectedServerDataMessage FalseSSDM = new SelectedServerDataMessage();
                    FalseSSDM.initSelectedServerDataMessage(SSDM.serverId, "127.0.0.1", 5555, SSDM.canCreateNewCharacter, SSDM.ticket);
                    FalseSSDM.serialize(writer);
                    _Client.Send(writer.Pack(42));

                    
                    _ClientMitm.Close();
                    _ClientMitm = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
                    _ClientMitm.Connect(ip, port);

                    _Client.Close();
                    _Client = _ServeurMitm.Accept();

                    break;

                default:
                    _Client.Send(_buff);
                    break;
            }
 

ToOnS

Membre Actif
Inscrit
8 Avril 2009
Messages
974
Reactions
0
#4
Salut , en effet , je me suis trompé :
(ici client et server c'est officiel donc pour toi client c'est server mitm et server c'est client mitm)
Code:
If Message_id = 42 Then 'si c'est message qui contient l'ip de serveur de jeu
                        sock.Send(Data_Out) ' on envoie au jeu un faux messsage qui contient 127.0.0.1 pour l'ip de serveur de jeu
                        CType(Form1.lstClient.Items(0), Client).Socket.Close()
                        Do Until Form1.lblStatServeur.Text = "Serveur : Déconnecté"
                            Application.DoEvents()
                        Loop
                        Form1.ServerSock.Connect(Form1.Address, 5555)
                End If
on deco d'abord le serveur mitm :
CType(Form1.lstClient.Items(0), Client).Socket.Close()
on attend que le client mitm soit deco :
Do Until Form1.lblStatServeur.Text = "Serveur : Déconnecté"
Application.DoEvents()
Loop
et on reco le client :
Form1.ServerSock.Connect(Form1.Address, 5555)
 
Inscrit
13 Septembre 2011
Messages
37
Reactions
0
#5
Yeah ! J'avance peu à peu, merci beaucoup :)

Mais il me reste encore une dernière chose (sinon c'est pas drôle ...) :

Comme tu me l'as fait remarquer, mon parseur ne gère pas les gros messages, et ça plante donc lorsque j'appuie sur "Jouer".

Pour remédier à ça, il me suffit de changer 2-3 trucs dans le parseur ou il faut que j'en code un?
 

ToOnS

Membre Actif
Inscrit
8 Avril 2009
Messages
974
Reactions
0
#6
non il y'a pas tout a refaire , tu as le plus gros.
apres // Récupération de la taille du paquet (qui d'ailleur est un message , le paquet c'est datatoparse donc la taille du paquet c'est datatoparse.count )
il faut regarder si packet_lenght (enfin message_lenght) est superieur a datatoparse.count-index , si pas superieur alors ton parseur continu comme il le fait déjà , si superieur alors tu as pas la fin du message qui arrivera au prochain paquet donc garder les bytes qui sont dans datatoparse de index (la ou on c'est arrété) a datatoparse.count (la fin du paquet) dans une variable (on va dire dataWait) et quitter le parser

ensuite tu vas recevoir la fin du message dans un autre paquet , pour verifier si c'est une fin de message (ou qu'on attend pas de fin de message) alors tu regardes si datawait.count>0 , si oui alors tu mets datawait au debut et datatoparse a la fin dans ... datatoparse ce qui fait datatoparse contiendra le debut du message qui était dans dataWait et la fin qui était dans datatoparse.

edit : apres pas sur que quand tu appuis sur jouer c'est un probleme de taille de message , je crois que y'a pas de long message a cet instant , plutôt un des 2 sockets qui est pas connecté
 
Inscrit
13 Septembre 2011
Messages
37
Reactions
0
#7
Merci beaucoup à toi, j'essayerais ça quand j'aurais le temps (Et oui, on est déjà dimanche soir...).

Bonne soirée ;)
 
Haut Bas