[00:00.000 --> 00:03.620] Hi, I'm Alessandro, a security researcher at DualSecure, [00:03.620 --> 00:08.680] and today I'm with my colleague Olivier to showcase our RDP interception tool, PyRDP. [00:08.720 --> 00:12.580] PyRDP is a tool that can be used to perform real-time RDP interception, [00:12.580 --> 00:16.860] which were designed to support both honeypots for malware research and offensive capabilities [00:16.860 --> 00:23.000] for intrusion test engagement. Today we'll be highlighting core features for both use cases. [00:23.180 --> 00:28.080] In this section, I'm going to introduce you to PyRDP's core feature set, [00:28.080 --> 00:31.340] which can be used in both offensive and defensive contexts. [00:31.760 --> 00:36.840] In the environment for this demo, we have the PyRDP system deployed in front of a Windows Server [00:36.840 --> 00:44.240] 2016 system. PyRDP is running on a Linux system and deployed using our Docker image. The client [00:44.240 --> 00:50.320] will be a Windows 10 system running Microsoft Terminal Services, also known as MSTSC. [00:50.640 --> 00:55.460] In its default mode of operation, PyRDP will collect a lot of information, [00:55.460 --> 00:59.380] but only output significant events in its logs. [01:00.200 --> 01:05.820] The player component, which has more granular information, will be demoed later. [01:07.160 --> 01:14.220] Let's take a look at the default flags to use PyRDP. In this example, we run it via Docker, [01:14.640 --> 01:20.760] and we map a volume here to make sure that we have access to the artifacts generated with PyRDP [01:20.760 --> 01:31.400] after our demo, after the interactions. The "-p", here, is to give the host access to the port, [01:31.400 --> 01:38.420] so RDP being on 3389. This will ensure that any connection to 3389 on the host is redirected to [01:38.420 --> 01:46.200] the Docker image. This is the Docker image name of the latest PyRDP. The monster in the middle [01:46.200 --> 01:53.540] executable that is used here, and this is the target server. So whenever something connects [01:53.540 --> 02:03.120] on 3389 on this system, it will then forward the connection to this IP address and do its [02:03.120 --> 02:11.500] monster in the middle capabilities. Let's start the PyRDP man in the middle. [02:14.570 --> 02:21.170] You can see that SSL information or private key and certificate are generated upon the start [02:21.170 --> 02:26.490] because we didn't give them in the Docker image in the volume. So they don't exist [02:26.490 --> 02:32.370] and they are created on the fly. This should probably be customized for most users. [02:35.300 --> 02:42.540] Now let's take a look at what we have if a user connects and plays around. I'm going to start [02:42.540 --> 02:52.990] the Microsoft client here. You can see the certificate error that is being generated. [02:53.670 --> 03:02.030] The PyRDP system by default will create a certificate for a hostname called www.example.com. [03:02.030 --> 03:10.410] This is probably not the best. You should generate a certificate more adapted to the target [03:10.410 --> 03:18.710] or the user that you're trying to fool. We provide a tool called PyRDP clone cert to do that. Clone [03:18.710 --> 03:23.610] cert will connect to a specific server and copy the information from the certificate [03:25.950 --> 03:30.290] in a certificate key pair that you can then use with PyRDP. [03:31.470 --> 03:39.530] So this is the reason why we built this tool is to train user to avoid clicking through certificate. [03:39.530 --> 03:43.330] Since if there is an attack tool that is efficient, [03:43.930 --> 03:52.670] then user will be enticed to be more careful. Just like what FireSheep did with the SSL attacks. [03:52.670 --> 03:59.350] It changes the mentality of a lot of people and made TLS enabled by default everywhere. [03:59.350 --> 04:04.130] Well with PyRDP we hope that system administrator will be more careful about those certificate [04:04.130 --> 04:11.810] errors and deploy a PKI internally, which is very rarely the case in our engagements that we see. [04:12.510 --> 04:14.690] So we're going to click on yes. [04:16.590 --> 04:23.890] Now we can see several interesting things happened on the log section of the screen. [04:23.890 --> 04:30.390] You can see that the client random is logged, which is very interesting if you ever take [04:30.390 --> 04:38.710] packet capture, you can then decrypt and do very granular protocol level analysis of the RDP connection. [04:40.580 --> 04:47.080] On the system we get a password prompt, which is different than the usual password prompt, [04:47.250 --> 04:54.920] because we downgrade the authentication and it's now interactive, it's now part of the session. [04:54.920 --> 04:58.780] So I'm gonna write the password. [05:03.340 --> 05:05.920] Made a little mistake here. [05:11.530 --> 05:21.250] Okay, I'm in. So there's a secret file on the desktop. [05:22.470 --> 05:31.330] But you can see in the logs that channel information is logged, username, [05:31.970 --> 05:36.230] since it was not typed and not sent by the client, is not there. [05:37.470 --> 05:41.730] You can see that clipboard data was instantly intercepted. [05:42.990 --> 05:50.190] And you can see that there is a credential candidates from heuristic here, scary demo gods. [05:52.630 --> 05:57.350] This is being done with a heuristic since it doesn't happen at the protocol level. [05:57.350 --> 06:04.030] We are interactively entering credentials inside the started RDP sessions. That's because we are [06:04.030 --> 06:11.190] downgrading the client's request for NLA, since NLA will resist two monster in the middle attacks. [06:11.190 --> 06:17.590] This attack resistance is rather complex and has been partially circumvented in specific cases, [06:17.590 --> 06:20.570] which we will cover in the honeypot section later. [06:23.360 --> 06:32.580] By default, the clipboard content is intercepted. And we can see it, we'll demo it right now. [06:33.080 --> 06:42.080] So if we open this many secret file and we put it in the clipboard, you can see [06:42.080 --> 06:49.520] right away, instantly, that it was intercepted on the server side, in the logs. [06:49.640 --> 06:57.660] What's interesting that you might not have noticed here, is that I didn't interact with [06:57.660 --> 07:05.820] the mstsc client when the output showed in the logs. So let me just give you an example [07:05.820 --> 07:13.400] to highlight it again. So I copied in notepad, not even touching the mstsc client screen. [07:13.400 --> 07:22.200] However, the information was sent to the server. So the clipboard content is being very shared, [07:22.200 --> 07:30.920] very enthusiastically, with mstsc. And also, this is what happens with most RDP clients. [07:34.910 --> 07:38.350] Let's copy a few more times, just to see... [07:40.570 --> 07:44.890] You should be aware that this goes beyond this. [07:44.890 --> 07:52.950] So this Windows machine is in a VirtualBox system, running the mstsc client. The VirtualBox [07:52.950 --> 08:00.110] will also notify the guest, Windows 10, of clipboard events that happen on my host. [08:00.230 --> 08:07.810] So this is very interesting, because, for example, if I would paste a log line here [08:07.810 --> 08:14.590] on my clipboard, what we would expect is the information to flow from my host, to my guest, [08:14.590 --> 08:22.610] from the guest OS clipboard, to the mstsc client, and then to the intercepted system. [08:24.030 --> 08:31.630] And, the expected happened. You can see that the clipboard data is visible here. [08:31.630 --> 08:39.290] And it happened pretty fast. So this is a very interesting capability, [08:39.290 --> 08:46.190] that will probably allow some information to be leaked, if we ever intercept bad actors, [08:46.190 --> 08:51.090] or in a penetration testing context, you can gather a lot of information, [08:51.090 --> 08:56.050] if an administrator leaves an RDP window open in the background for a long time. [08:56.050 --> 09:00.830] You'll be able to get clipboard content with, most likely, sensitive information, [09:00.830 --> 09:06.330] including passwords, if the user uses a password manager like KeePass. [09:12.810 --> 09:19.090] What happens here is that PyRDP just receives a message about new clipboard content, [09:19.090 --> 09:25.410] and will send to the client a message saying, I need it. The content is then never forwarded [09:25.410 --> 09:32.910] to the server. So it's just a standard operation. There's no update of the clipboard on the server [09:32.910 --> 09:40.890] side. So next up in the demo is the file collector. RDP allows clients to share a drive [09:40.890 --> 10:03.440] upon connection. Let's configure it. So let's disconnect. We go in local resources, [10:03.440 --> 10:11.140] and then we can share whole map drives. That's interesting, because the share is [10:11.140 --> 10:28.740] not at a very granular level. So this gives a lot of opportunity for attacker. A new warning is [10:30.320 --> 10:38.620] given to the user, saying that it's potentially dangerous, and it can harm the computer. So that's [10:38.620 --> 10:52.530] interesting, and it's new. It was not there on older MSTSC clients. Same certificate error. [10:54.750 --> 11:22.160] Okay, let's take a look at the file share in action. So we can see that the C drive [11:22.160 --> 11:29.360] on engineering 13, which is my client, is visible through the RDP session. [11:30.100 --> 11:37.260] What happens if we click on it, is we get access to the information on it, [11:37.260 --> 11:44.260] and we see at the same time information being collected by the PyRDP system. [11:48.350 --> 11:57.790] If we open the secret.txt file on the root of the C drive, we also notice that the information [11:57.790 --> 12:11.610] was saved by PyRDP in the output folder. To finalize this part of the demo, [12:12.950 --> 12:17.530] we're gonna stop PyRDP and look at the artifacts generated. [12:29.960 --> 12:39.940] The PyRDP output folder has several items in it. Replays, which are recordings of the exact [12:40.480 --> 12:48.880] sessions, including keystrokes and screen capture, which can be replayed later. [12:51.170 --> 13:06.530] There are logs and there are files. If we look at the logs, we can see that the SSL log is also [13:06.530 --> 13:14.090] available here. So this is very useful, again, if you do packet capture in order to decrypt them [13:14.090 --> 13:20.950] with Wireshark or other tools. There is a JSON log, which will be covered later, [13:20.950 --> 13:25.730] and there is a man-in-the-middle log, which is the exact output that was available [13:26.370 --> 13:38.790] from inside, that you could see on the command line. And if we look at the files, [13:38.790 --> 13:57.410] then you can see all the files that were collected by the system. So we can take a look at the [14:01.890 --> 14:09.530] secret file that we saw earlier, loaded from the C drive, is here with the content. The mapping [14:09.530 --> 14:22.490] of the files to the events is available through the log files. This concludes the PyRDP demo [14:22.490 --> 14:30.570] of the monster-in-the-middle component. If you need fine-grained content, like keystrokes, [14:30.570 --> 14:36.410] and see the screen during an active attack, you need to combine the use of the PyRDP MITM tool [14:36.410 --> 14:44.050] with the PyRDP player. Let's launch both tools right now. Here I'm bringing up the previous [14:44.050 --> 14:49.710] command that we used to run just the monster-in-the-middle component, and now I'm going [14:49.710 --> 15:01.870] to add "-i", and an IP address to this execution. The "-i"-flags tells PyRDP to send recorded [15:01.870 --> 15:09.130] RDP events to a PyRDP player over the network. This allows a player that is decoupled from the [15:09.130 --> 15:16.650] attacker's machine, like the setup we have here. Now we are going to launch the player on my local [15:16.650 --> 15:33.390] system, pyrdp-player. You can see that it is a Qt interface, and that it has tabs for live [15:33.390 --> 15:41.830] connections and replays, so live activity and replay, or previously recorded activities. [15:41.850 --> 15:47.710] Let's connect a client to the monster-in-the-middle and see what the player sees. [15:54.300 --> 16:00.800] In order for the demonstration to be complete, we'll ensure that we have a map drive here. [16:00.800 --> 16:05.580] So the C drive is shared upon an RDP connection. [16:07.360 --> 16:17.410] Then let's connect. You can see that there is some activity already happening in the player interface. [16:20.120 --> 16:27.900] Now, you see that a tab opens called engineering13, which is the hostname that is sent by the client. [16:29.540 --> 16:36.340] The screen is visible, including the pointer position, which is hard to see right now, but if [16:36.340 --> 16:51.140] we see here with the yellow dot. Now if we enter the credential, you can see on the below interface [16:52.840 --> 17:04.320] exactly the keystrokes being inputted, including special characters like space and shift or control. [17:05.400 --> 17:13.200] So this is very interesting and important to have an accurate representation of the connection, [17:14.100 --> 17:20.720] which could be used in many contexts. And you can see that you have also a pixel-perfect [17:21.280 --> 17:28.120] representation of the interactions. This can really demonstrate the impact [17:28.120 --> 17:34.480] of an attack on RDP to executives, for instance. [17:37.370 --> 17:43.850] Additionally, if the client mapped a drive, you can explore his drive without his knowledge. [17:43.850 --> 17:53.250] So we can browse here and we can double... we can right-click and download a file [17:53.250 --> 18:02.090] on our local system. RDP demo. Download this here. [18:04.160 --> 18:13.470] You can also browse and explore the user's file system. So here, for example, [18:13.470 --> 18:21.550] we are loading into Dave's files and looking at his documents. And we can download the many [18:21.550 --> 18:40.570] secrets files again on our system. RDP demo. Here we go. This is a pretty interesting demonstration [18:40.570 --> 18:47.630] of the dangers of mapping a drive. You basically allow the server to query anything using File.io [18:47.630 --> 18:54.190] on your mapped drive. Normally, that is fine. But as you can see, with PyRDP, [18:54.190 --> 18:59.390] it can be abused. And it could also be abused with a malicious RDP server. [19:01.170 --> 19:07.010] Another feature of the player is the Take Control button that you can see right here. [19:07.530 --> 19:13.970] This will be demonstrated later by Alex in the offensive section of the demo. [19:15.070 --> 19:19.790] Lastly, is the ability to replay previous captures. [19:21.960 --> 19:27.120] This is called a replay in PyRDP's context with the player. [19:27.940 --> 19:34.320] I'm gonna demonstrate to you by loading a previous capture for our previous demo. [19:35.480 --> 19:45.320] So this is Susan's interactions. So what we see right now is the initial state. You can [19:45.320 --> 19:55.360] change the speed, play. And once you play, you do have the keyboard and clipboard events [19:55.360 --> 20:00.700] at the bottom of the screen. You can also seek in the video. [20:02.580 --> 20:11.260] We see the clipboard data also here. You can scale the window so that it's easier to see [20:11.260 --> 20:21.170] globally, especially with 4K environments. And you can increase the speed of the replay. [20:22.050 --> 20:27.850] So this is very good if you're hunting for a specific session for a specific interaction. [20:31.610 --> 20:35.720] This concludes our demonstration of the player's features. [20:37.890 --> 20:43.710] PyRDP also comes with a converter tool that can be used to convert pre-recorded replay files [20:43.710 --> 20:51.410] into videos. The converter tool also accepts PCAPs and can output to replay files. [20:51.990 --> 20:56.430] Let's take a look at its option. [21:01.960 --> 21:07.800] Here we will convert a previously recorded session into a video that we will play. [21:08.760 --> 21:11.200] PyRDP convert. [21:12.160 --> 21:28.300] MP4 has the format of output. The input file is a RDP replay. [21:29.200 --> 22:09.490] And let's have a default output file name. Now let's look at the resulting file. [22:26.510 --> 22:31.750] In this section we will describe PyRDP's features that are useful in the context of running [22:31.750 --> 22:38.330] honeypots. Part of PyRDP's honeypot features is a headless mode. This enables server-side [22:38.330 --> 22:45.470] deployments, running it on non-x86 systems like a Raspberry Pi, and allowed us to significantly [22:45.470 --> 22:54.210] reduce the size of our docker image. For example, this is a cloud system where we want to deploy [22:54.210 --> 23:04.210] PyRDP and we are going to run the headless image. This is the command line from PyRDP. [23:05.380 --> 23:13.700] This pulls in the latest master branch image and we are going to use the slim tag so that [23:13.700 --> 23:21.020] we are going to use the smaller version of our image without the graphical interface features [23:21.020 --> 23:28.120] and the video conversion features. Now let's see how long it takes. [23:33.830 --> 23:43.730] The new image is 70 megabytes, which is pretty good for a Python docker image with native code, [23:43.730 --> 23:52.490] down from 600 megabytes for our latest release. And you can see that the service is running right [23:52.490 --> 23:58.950] now. Headless mode also means that we needed a headless player, otherwise keystroke data is [23:58.950 --> 24:10.150] unavailable for command line enthusiasts. Let's see the headless player in action. [24:12.530 --> 24:19.370] We can remove the port, it's no longer required for the player, but we still need the volume mount. [24:23.140 --> 24:31.460] If we look at the options, we can see a dash dash headless at the bottom. So usually the [24:31.460 --> 24:37.420] player is the graphical interface with the Qt, but the new headless feature allows us to look [24:37.420 --> 25:00.950] at replay files without the GUI. The Lena file. The dump is one shot deal. You get all of the [25:00.950 --> 25:08.430] output at once, but you can go back and see everything that was collected, including clicks [25:09.040 --> 25:17.650] and stuff that was sent during the connection. So as is common with the beginning of RDP sessions, [25:17.650 --> 25:23.040] you see a lot of control character released and pressed in order to reset everything. [25:23.520 --> 25:35.280] Then you can see that I entered credentials, so the password is scary demo gods, [25:35.280 --> 25:43.220] and I made a mistake here, so this is a lowercase o. You can see also the backspace that are [25:43.220 --> 25:51.180] pressed, so I started with demo instead of scary, so de backspace backspace scary, [25:51.180 --> 25:54.380] but then I made a mistake, so I authenticated again. [25:55.880 --> 26:02.400] You can see that as soon as I was authenticated, the clipboard was shared, and this was my notes [26:03.020 --> 26:10.800] was sent to the server. Then you can see some clicks, and then during that demo, I pasted [26:10.800 --> 26:18.160] several secrets to show how easy it was to leak data to the server system and easy for [26:18.760 --> 26:27.180] pyrdp to correct, and then I disconnected, which ends the stream. So with the headless player, [26:27.180 --> 26:31.640] you have access to all of this from the command line, instead of having to load [26:31.640 --> 26:38.140] the graphical interface. Another feature specific to honeypot use cases is credential replacement. [26:38.580 --> 26:42.940] This allows your honeypot to accept any credentials entered by the client, [26:42.940 --> 26:46.760] and relay to the server the correct set of credentials for login. [26:46.760 --> 26:50.860] For instance, although the user for this VM is pyrdp, [26:50.860 --> 26:55.380] I will be able to log in using admin and a garbage password. [26:56.300 --> 27:05.580] So let's do the demonstration. For this, I'm going to go back to using the man in the middle. [27:06.060 --> 27:14.300] As you can see below, I'm gonna input the correct credentials for the VM, [27:17.850 --> 27:30.020] and start the man in the middle. Now, using the mstsc client, I'm gonna put a different username [27:30.020 --> 27:39.010] here, admin lulz, to make sure that it doesn't exist, and I'm gonna attempt to, I'm gonna try [27:39.010 --> 27:50.660] to connect to the honeypot. I have the warning because I have a mapped drive, and I have an [27:50.660 --> 28:12.830] error. Let's try again. Okay, transient error. So we have the certificate error, [28:17.600 --> 28:24.410] and we got connected. And if you look at the log, you can see that in the client info, [28:24.920 --> 28:32.380] the admin lulz was supplied. pyrdp has the ability to intercept files in transit, [28:32.380 --> 28:37.720] and to allow client file system exploration from the interactive player. Last year, [28:37.720 --> 28:42.440] these capabilities were extended to allow active file querying from the monster in the middle [28:42.440 --> 28:49.280] component. When a client connects, pyrdp will list mapped drives and download all the files [28:49.280 --> 28:55.100] which match a specific list of allowed files patterns. Let's see this in action. [28:56.060 --> 29:06.760] So, we issue the same MITM command as during normal operation, but we add the crawl [29:08.240 --> 29:20.420] flag. Let's run it. Now, we connect from the Windows system, [29:20.420 --> 29:25.280] and its files using a mapped drive, and its files will be [29:25.860 --> 29:33.200] explored by the man-in-the-middle component. Let's connect. [29:34.280 --> 29:41.170] So, we have the certificate error. Yes. Now, what we see here... [29:42.660 --> 29:50.130] Oh, we need to authenticate before the file system is exposed to the server by the client. [29:56.240 --> 30:04.860] We authenticated. And now, what we see here is a begin-crawling-disk C, [30:04.860 --> 30:14.260] saving secret to pyrdp-output-files-clodia-secret.txt. So, this file was at the root of the C drive, [30:14.260 --> 30:19.760] and so this is why it was the first to be collected, and it was quite fast. [30:19.760 --> 30:25.820] You'll also be able to notice that the directory structure is respected. [30:25.900 --> 30:35.200] So, as the crawling happens in the background, the files are going to be recreated locally on [30:35.200 --> 30:41.700] the pyrdp system. Oh, we can see it's starting now. So, it matched a directory in the users [30:43.360 --> 30:54.440] folder, and documents, stuff.ssh, and then stuff.passwords.keypass.database, a flag, [30:54.440 --> 31:00.960] and so on. And you'll see also that temporary files and executables under the user directory [31:00.960 --> 31:08.580] are going to be saved by default. So, it can take a while to gather all these files based [31:08.580 --> 31:14.900] on network conditions. The list of files to collect or to ignore can be tweaked on the [31:14.900 --> 31:20.260] command line. So, with this feature, we hope that we'll be able to gather very interesting [31:20.260 --> 31:24.640] information, especially on Honeypot's system deployed in the wild. [31:26.420 --> 31:32.180] Pyrdp can also be used as an offensive security tool to gain a foothold or pivot within a network. [31:32.180 --> 31:37.840] Let's look at some attack techniques. Session hijacking can be used to take over an intercepted [31:37.840 --> 31:43.780] RDP connection. First, pyrdp-mitm is launched with the target server and the player address to [31:43.780 --> 32:00.560] connect to, in this case, localhost. Next, the player is launched and waits for intercepted [32:00.560 --> 32:05.300] sessions. The player can handle multiple sessions at the same time and will automatically display [32:05.300 --> 32:12.560] the live feed of the connected session. Clients who connect to the malicious server will receive [32:12.760 --> 32:17.780] a certificate prompt. The certificate can be customized to spoof the common name of the server. [32:18.040 --> 32:21.540] The likelihood of the certificate being accepted is considerably high, [32:21.540 --> 32:26.320] since most companies do not deploy fully signed private key infrastructures for RDP. [32:27.760 --> 32:32.500] After a successful connection is intercepted, the player can be used to monitor the screen [32:32.500 --> 32:43.990] and input of the session. When the attacker clicks the take control button, pyrdp takes over [32:43.990 --> 32:49.050] the session and redirects all player inputs to the server and all server output to the player. [32:49.050 --> 32:54.970] The real RDP client appears frozen during the hijack. Once the attacker is done, the session [32:54.970 --> 33:00.590] is returned to the client, which unfreezes. This technique is noisy, but looks like a network error [33:00.590 --> 33:07.270] to the untrained eye. After the real client recovers control, there may be artifacts on [33:07.270 --> 33:12.290] the screen because the server and client will be out of sync. In order to avoid that, the screen [33:12.290 --> 33:17.230] should be left as closely as possible to its original arrangement when control is removed. [33:19.390 --> 33:23.850] Hiring a specific server does not scale well during engagements, because it will most likely [33:23.850 --> 33:29.070] redirect intercepted sessions to a server which isn't the one that the client tried to connect to. [33:29.230 --> 33:33.910] Pyrdp supports transparent proxying with the help of a few firewall rules. [33:34.130 --> 33:37.010] Note that this technique only works on Linux and requires [33:37.010 --> 33:40.910] running pyrdp as root to use IP transparent sockets. [33:42.290 --> 33:46.710] Use the firewall rule templates from the documentation directory and modify them to [33:46.710 --> 33:52.790] reflect your environment. Here, we use the address range that we will ARP spoof. Because we're spoofing [33:52.790 --> 33:58.750] the subnet we are in, we exclude our own IP address to prevent packet production loops in IP tables. [33:59.710 --> 34:04.290] Next, create a custom routing table for pyrdp's intercepted connections. [34:04.290 --> 34:07.190] Table ID is a number identifying the table. [34:09.210 --> 34:13.390] Ensure that IP forwarding is enabled and create a pre-routing rule that will [34:13.390 --> 34:18.630] mark all traffic distant to the server range for transparent proxying by pyrdp. [34:35.800 --> 34:41.200] The last firewall rule is used to mark traffic coming back from the servers to the clients for [34:41.200 --> 35:05.870] transparent proxy. The last step is to ensure that marked packets use the pyrdp routing table [35:05.870 --> 35:10.390] created earlier, which will be responsible for delivering the marked packets to pyrdp [35:10.390 --> 35:24.610] through the loopback interface. With the firewall configured, make sure to launch pyrdp as root and [35:24.610 --> 35:38.600] provide the transparent switch to enable transparent proxying. Start vendor cap on your [35:38.600 --> 35:51.770] land facing interface and ARP spoof the subnet to intercept. Here, we set ARP spoof internal to true [35:51.770 --> 35:56.750] because we are spoofing our own subnet. This is not required when spoofing an adjacent subnet. [35:56.750 --> 36:00.230] For the demonstration, we are only spoofing one client. [36:12.260 --> 36:17.080] When the victim attempts to connect to their destination server, they will be intercepted by [36:17.080 --> 36:22.140] pyrdp, which will then establish a connection with the intended server. This technique scales [36:22.140 --> 36:31.890] well for internal engagements and works in combination with other attacks. The last technique [36:31.890 --> 36:37.130] that we will cover is command injection, which automates session hijacking to seamlessly run a [36:37.130 --> 36:42.550] payload for an intercepted connection. Using the same transparent proxy configuration as the previous [36:42.550 --> 36:49.530] technique, start pyrdp with a PowerShell payload that acts as a stager. This stager will query a [36:49.530 --> 36:54.630] web server which hosts the real malicious payload and execute it in the context of the intercepted [36:54.630 --> 37:00.750] session. The payload delay and payload duration parameters are used to control when the payload [37:00.750 --> 37:07.810] should be executed and how long to hijack the session for. The malicious payload consists of [37:07.930 --> 37:13.210] a simple PowerShell reverse shell for demonstration purposes. This shell will connect back to the [37:13.210 --> 37:24.570] pyrdp workstation on port 888. Start Metasploit's multi-handler to cache the reverse shell once it [37:24.570 --> 37:41.250] is established. Next, use Python's built-in web server to host the payload that the stager will [37:41.250 --> 37:52.790] retrieve. Make sure to disable exit on session so that multiple sessions can be intercepted. [38:09.740 --> 38:15.120] Lastly, start armscoping to intercept RDP sessions as they are established. [38:49.500 --> 38:54.220] Once a session is intercepted, everything will proceed as normal from the client's point of view [38:54.220 --> 38:59.840] until the payload delay is reached. After the delay has elapsed, the client session will appear [38:59.840 --> 39:05.520] to freeze while the payload is being delivered and executed. The stager retrieves the code from [39:05.520 --> 39:09.680] the server and executes it, causing the reverse shell to connect to the Metasploit listener [39:09.680 --> 39:13.480] and giving the attacker covert access to the target server. [39:26.320 --> 39:30.980] Even if the client later disconnects from the server, the reverse shell persists. [39:31.540 --> 39:35.900] This technique is powerful and can easily result in multiple sessions when using less [39:35.900 --> 39:48.470] detectable payloads. This concludes our brief tour of pyrdp's features. If you'd like to see [39:48.470 --> 39:54.450] the full feature set or get the source code, make sure to check out the pyrdp GitHub. Lastly, [39:54.450 --> 39:59.370] if you have any war stories to share, we'd be happy to hear about them. Thanks for watching!