WEBVTT

00:00:01.140 --> 00:00:03.280
The stager is a piece of shell code.

00:00:03.280 --> 00:00:08.350
Shell code is machine code which is ready to be executed by a CPU.

00:00:09.040 --> 00:00:11.670
It is tied to a specific CPU architecture,

00:00:11.680 --> 00:00:16.260
which you can specify when generating the stager using the msfvenom tool.

00:00:17.040 --> 00:00:19.240
Shell code is position independent,

00:00:19.510 --> 00:00:23.250
meaning that it can be dropped anywhere in memory and it should be able to run.

00:00:23.640 --> 00:00:27.150
It doesn't rely on the operating system to load its dependencies.

00:00:28.140 --> 00:00:31.350
For example, if it needs to perform HTTP requests,

00:00:31.840 --> 00:00:36.460
the shell code will resolve the required APIs by itself at runtime so

00:00:36.460 --> 00:00:39.760
that it can call them to communicate over HTTP.

00:00:39.760 --> 00:00:43.910
The stager is written in assembly and compiled using

00:00:43.910 --> 00:00:46.260
the Metasm assessment Ruby compiler.

00:00:47.740 --> 00:00:49.360
Shell code is very versatile.

00:00:49.580 --> 00:00:53.840
It can be sent over the network to exploit memory corruption bugs in software,

00:00:53.850 --> 00:00:56.460
or it can be used to backdoor executable files.

00:00:56.840 --> 00:01:00.140
During the course, we will focus on the latter.

00:01:00.140 --> 00:01:03.840
To generate a reverse the HTTP stager,

00:01:03.850 --> 00:01:07.150
we can go ahead and run the following msfvenom command.

00:01:07.740 --> 00:01:08.610
In this case,

00:01:08.620 --> 00:01:12.980
we choose the payload type using the ‑p option and we configured the

00:01:12.980 --> 00:01:17.830
LHOST and LPORT to specify the IP address and TCP port of the handler

00:01:17.830 --> 00:01:19.860
we want our stager to connect back to.

00:01:21.040 --> 00:01:24.520
We can then specify the format where we can choose hex for a

00:01:24.520 --> 00:01:27.360
hexadecimal representation of the stager shell code.

00:01:28.440 --> 00:01:31.860
When you run this command, some Ruby code is being called,

00:01:31.870 --> 00:01:33.450
which generates a stager.

00:01:33.840 --> 00:01:35.220
Let's take a look at the code.

00:01:35.220 --> 00:01:40.400
In this case, since we generated a 64‑bit reverse HTTP stager,

00:01:40.610 --> 00:01:47.360
the code being run is in the reverse_http_x64.rb file.

00:01:48.840 --> 00:01:52.160
If we take a look at the generate method inside the file,

00:01:52.540 --> 00:01:56.290
we notice that the parameters that were passed to msfvenom are

00:01:56.290 --> 00:02:01.150
being passed into the generate_reverse_http method.

00:02:02.240 --> 00:02:04.030
If we take a look at this method,

00:02:04.070 --> 00:02:07.360
we can see some inline assembly code and two variable

00:02:07.360 --> 00:02:11.490
placeholders which will also hold assembly code,

00:02:11.490 --> 00:02:17.460
asm_block_api and asm_reverse_http.

00:02:18.140 --> 00:02:22.720
The former consists of a function which will be used to locate all the

00:02:22.720 --> 00:02:26.110
APIs which are required by the stager at runtime.

00:02:26.110 --> 00:02:29.560
The latter consists of the actual stager code,

00:02:29.780 --> 00:02:33.550
which will leverage various APIs and make use of the

00:02:33.560 --> 00:02:37.540
asm_block_api function to locate them.

00:02:37.710 --> 00:02:42.940
The asm_block_api uses a structure called the PEB,

00:02:42.950 --> 00:02:45.260
also known as Process Environment Block,

00:02:45.440 --> 00:02:49.960
which contains a linked list of all modules loaded in the current process.

00:02:50.840 --> 00:02:55.040
This list can be used to locate a module's base address in memory,

00:02:55.050 --> 00:02:55.810
which, in turn,

00:02:55.810 --> 00:02:59.350
can be used to access its export table to locate

00:02:59.350 --> 00:03:01.250
the address of a given function.

00:03:01.420 --> 00:03:06.980
If our stager requires the LoadLibraryA function located in the kernel32 module,

00:03:06.980 --> 00:03:11.200
the ROT13 hash of the module and function is calculated,

00:03:11.200 --> 00:03:14.370
and the value is placed inside the assembly code.

00:03:14.570 --> 00:03:20.560
The method which calculates this hash can be found in the block_api_rb file.

00:03:21.240 --> 00:03:24.350
If we debug the Ruby code as we generate the stager,

00:03:24.360 --> 00:03:26.800
we can indeed check the ROT13 hash,

00:03:26.800 --> 00:03:30.950
which is pre‑calculated for the LoadLibraryA API.

00:03:31.170 --> 00:03:36.150
We can load the stager in a disassembler such as Defuse, which is web based.

00:03:37.140 --> 00:03:40.790
You can see that at runtime this ROT13 hash is

00:03:40.790 --> 00:03:44.550
passed to the asm_block_api function.

00:03:44.550 --> 00:03:46.270
Instead of using Defuse,

00:03:46.280 --> 00:03:51.050
we could also regenerate the stager using msfvenom and the raw format to

00:03:51.050 --> 00:03:56.700
send the shell code to a file which can then be disassembled by Metasm We

00:03:56.700 --> 00:03:59.260
can then grep for the ROT13 hash to find it.

00:04:00.540 --> 00:04:01.120
As explained,

00:04:01.120 --> 00:04:04.510
the function first traverses the linked list to find the base address

00:04:04.510 --> 00:04:08.250
of kernel32 then accesses kernel32's export table.

00:04:08.640 --> 00:04:11.250
It then starts looping over the exported functions,

00:04:11.260 --> 00:04:14.530
calculating their ROT13 hashes and comparing them with

00:04:14.530 --> 00:04:16.950
the precomputed hash we just saw.

00:04:16.950 --> 00:04:21.760
If a match is found, the function calls the API with the supplied parameters.

00:04:23.940 --> 00:04:25.420
If we go back to the Ruby code,

00:04:25.420 --> 00:04:28.430
we can take a look at which APIs are resolved and

00:04:28.430 --> 00:04:30.260
called by the stager at runtime.

00:04:31.040 --> 00:04:35.500
It first loads the WinINet library using the LoadLibraryA

00:04:35.500 --> 00:04:39.830
function and then calls a series of APIs inside the WinINet

00:04:39.830 --> 00:04:41.770
module after it has been loaded,

00:04:41.780 --> 00:04:45.160
to make an HTTP request which will be sent to the handler.

00:04:46.340 --> 00:04:49.240
It then allocates the memory using VirtualAlloc,

00:04:49.250 --> 00:04:53.190
and finally reads the HTTP response into the allocated memory

00:04:53.190 --> 00:04:56.260
buffer and jumps to it using a ret instruction.

00:04:57.440 --> 00:05:01.910
All this assembly code is compiled by Metasm and formatted appropriately

00:05:01.920 --> 00:05:05.260
to be sent to standard output or directly to a file.
