Skip to content

Case Study. Part 2: Global variables

shramos edited this page Oct 1, 2020 · 1 revision

Global variables

Let's continue with the exercise explained in the previous section and try to make additional on-the-fly modifications to the ICMP network packets so that the ping -localhost command works properly.

The problem we have with the previous exercise is that we are modifying on the fly the value of the data field of the ICMP Request network packets, and therefore, the ICMP Reply contains a value in the data field that differs from the original. (This can be checked by using tools such as wireshark).

To remedy this, we will make an on-the-fly modification to the data field value of the ICMP Reply network packets by inserting the original value that the ICMP Request network packets had before making the modification.

We start by importing the template we have saved in the previous case study, this can be done from the main Polymorph interface:



 ██████╗  ██████╗ ██╗  ██╗   ██╗███╗   ███╗ ██████╗ ██████╗ ██████╗ ██╗  ██╗
 ██╔══██╗██╔═══██╗██║  ╚██╗ ██╔╝████╗ ████║██╔═══██╗██╔══██╗██╔══██╗██║  ██║
 ██████╔╝██║   ██║██║   ╚████╔╝ ██╔████╔██║██║   ██║██████╔╝██████╔╝███████║
 ██╔═══╝ ██║   ██║██║    ╚██╔╝  ██║╚██╔╝██║██║   ██║██╔══██╗██╔═══╝ ██╔══██║
 ██║     ╚██████╔╝███████╗██║   ██║ ╚═╝ ██║╚██████╔╝██║  ██║██║     ██║  ██║
 ╚═╝      ╚═════╝ ╚══════╝╚═╝   ╚═╝     ╚═╝ ╚═════╝ ╚═╝  ╚═╝╚═╝     ╚═╝  ╚═╝
                                                < Santiago Hernandez Ramos >

PH > 
PH > 
PH > import -t icmp_template
PH:cap/t0 > 

Once the template has been imported, we can check that the previously generated functions have already been automatically added.

PH:cap/t0 > functions -s 
+-------+----------------------------------------------------------------------+
| Order |                              Functions                               |
+=======+======================================================================+
| 0     | def filter_icmp_packets(packet):                                     |
|       |     try:                                                             |
|       |         if packet['IP']['proto'] == 1:                               |
|       |             if packet['ICMP']['type'] == 8:                          |
|       |                 print("ICMP Request. Executing next function...")    |
|       |                 return packet                                        |
|       |             elif packet['ICMP']['type'] == 0:                        |
|       |                 print("ICMP Reply. Executing next function...")      |
|       |                 return packet                                        |
|       |     except:                                                          |
|       |         return None                                                  |
|       |                                                                      |
+-------+----------------------------------------------------------------------+
| 1     | def modify_icmp(packet):                                             |
|       |     if packet['ICMP']['type'] == 8:                                  |
|       |         packet['ICMP']['data'] = packet['ICMP']['data'][:-8] +       |
|       | b'newvalue'                                                          |
|       |         print("New value inserted")                                  |
|       |         return packet                                                |
|       |                                                                      |
+-------+----------------------------------------------------------------------+

PH:cap/t0 >                   

In order to replace the value of the ICMP Reply network packets with the original value of the ICMP Request network packets, we must somehow "remember" the value of the ICMP Request network packet before making the modification on the fly. To do this we will use a global variable.

Global variables allow us to store values that will persist between executed functions and intercepted network packets.

To modify the function modify_icmp we execute the same command that we used to create it.

PH:cap/t0 > functions -a modify_icmp -e emacs

This sentence will open the function that we indicate with the selected text editor. The new function should be similar to the one shown below.

def modify_icmp(packet):
    # ICMP Request network packet
    if packet['ICMP']['type'] == 8:
        packet.global_var('orig_data', packet['ICMP']['data'])
        packet['ICMP']['data'] = packet['ICMP']['data'][:-8] + b'newvalue'
        print("New value inserted")
    # ICMP Reply network packet
    elif packet['ICMP']['type'] == 0:
        packet['ICMP']['data'] = packet.orig_data
        print("Original value inserted")
    return packet

As we can see, before inserting the new value in the ICMP Request network packet, we save the original value in the global variable orig_data which we later use to replace the value in the data field of the ICMP Reply packets.

The only thing we have to do at this point is to execute the intercept -localhost command in Polymorph and generate ICMP traffic executing the ping localhost command in a terminal of our operating system.

PH:cap/t0 > intercept -localhost  
[*] Waiting for packets...

(Press Ctrl-C to exit)

ICMP Request. Executing next function...
New value inserted
ICMP Reply. Executing next function...
Original value inserted
ICMP Request. Executing next function...
New value inserted
ICMP Reply. Executing next function...
Original value inserted
ICMP Request. Executing next function...
New value inserted
ICMP Reply. Executing next function...
Original value inserted
ICMP Request. Executing next function...
New value inserted
ICMP Reply. Executing next function...
Original value inserted

At this point we can see how we are making a double modification on the fly of ICMP network packets. On the one hand, we insert on the fly a new value in the data field of the ICMP Request network packets, and, on the other hand, when the system generates the ICMP Reply packet with the modified value, we modify on the fly this network packet to insert the original value that the data field had before the first modification.