Powered By Blogger

Monday, June 25, 2018

Recon 2018 day 1

Recon the con ! 

Recon is a very famous Reverse engineering oriented conference held  in Montreal. This year I had the opportunity to attend this year Bruce Dang training training and the conference.
My first feedback is that this conference is an amazing one for those interested by computer security in general and in reverse engineering in special. And Let me tell you that this year the conference materials was extremely mind blowing !

Before I go for a summary of the main notes that I took, here are the best talks in my point of view. I put them following their  given slot in the the conference:
  • Day 1 
    • Reverse Engineering Windows Defender Part II (Alexei Bulazel)
    • PreVice: Static Detection of Hooking Capabilities in Machine Code (Andy Wortman,Claudiu Teodorescu,Derek Soeder)
    • Meet Salinas, the first ever SMS-commanded Car Infotainment RAT (Daniel Regalado,Ken Hsu, Gerardo Iglesias)
    • Pwning Intel PIN(Julian Kirsch,Zhechko Zhechev)
  • Day 2 
    • Static instrumentation based on executable file formats (Romain Thomas)
    • Discovering the iOS Instruments Server (Troy Bowman)
    • Exploiting User-land vulnerabilities to Get Rogue App Installed Remotely on iOS 11 (Liang Chen, Marco Grassi)
    • Unknown Known DLLs and other Code Integrity Trust Violations (Alex Ionescu, James Forshaw)
  • Day 3 
    • Analyzing TRISIS - the first Safety Instrumented System malware (K. Reid Wightman, Jimmy Wylie)
    • SiliVaccine: North Korea's weapon of Mass Detection (Mark Lechtik, Michael Kajiloti)
    • PWN Flash with Reflection and HashTables (Tao Yan, Bo Qu)

Reverse Engineering Windows Defender Part II
You might go and start following this guy on Twitter, his talk is one of the best that I can recommend.  His previous studies concern inner working of antivirus engines. The talk, which can be considered a second part of a fist talk.

The speaker explains in his talk the methodology that he adopted to reverse Windows Defender Antivirus engine and sheds light on all the challenges where he struggled during his analysis. The cool thing that I appreciate in his talk is the fact that he went through the talk smoothly by insisting on the process itself and not throwing technical details ont the face of the attendees. 

Windows defender is a the builtin Windows antivirus engine, that run with SYSTEM privileges in an unsandboxed process. Alexei's research focuses this time on reing the binary emulator in charge to scan malicious code.
The Antivirus engine is an emulator (not virtualization) that loads an unknown binary, run it from its entrypoint and collect observations basing on various heuristics. For that the emulator has to manage to emulate the cpu, OS, OS Api and the environnement (filesystem, processes, settings,etc).
Alexei's used his previous works about antivirus engine that allowed him to develop techniques for introspecting the antivirus engine and leaking his internal structures and functions. 

The main targets of the research are:
  • Microsoft Malware Protection Engine: mpam-fe.exe 
  • Microsoft Malware Protection: mpengine.dll
  • Signature Update Stub: MPSigStub.exe
  • Signature databases
    • mpasbase.vdm
    • mpasdlta.vdm
    • mpavbase.vdm
    • mpavdlta.vdm 
The analysis process as for each reing project consisted in :
  • Static analysis phase : using IDa pro, public MS Pdbs and bindiffs basing on Google Project 0 findings. Some other tools were used especially for code coverage as Lighthouse IDA plugin  and Taviso's Coverage tool.
  • Dynamic phase: this one seemed to be complicated knowing the defender components run in a protected Windows process and the scanning process may not be triggered on demand and that could reduce the code reachability.  That where Taviso's tool comes in hand, LoadLibrary and especially mpclient.exe allows load Defender engine and exposes its interfaces. Alexei's demoed this tool the main workflow was : mpclient.exe Eicar.com --> WinApi emulation --> _rsignal(Defender engine interface)  --> Engine emulator. 
Reing the engine components allowed to make some observations: When a malware is getting emulated, _rsignal (main entrypoint) function is called, it takes a buffer as an argument. The emulation initialization step starts then to allocate memory, init various objects, load the binary, init emulated DLLs and start recording heuristics. The cpu emulation consists in a dynamic translation of instructions (IL lifting : IL-tox-86 Jit translation). 

For emulator instrumentation task, the idea was writing a custom malware that can install a hook in an internal engine structure called g_syscalls (Winexec). And for mapping emulator adresses a hook has been installed on OutputDebugStringA. However, a binary might not be emulated if it has some characteristics(low entropy, linking against unknown DLLs).
Alexei's then explained how he dumped the virtual file system and virtual processes (apparently using the same trick as OutputDebugStringA).

Windows API emulation seems to be based on two DLL types: 
  • Emulated ones : VDLL, that stay inside the emulator, and complex ones are coded to return hard coded valus
  • Normal ones: triggers a syscall outside the emulator.
The UM-KM emulator communication is carried out using an internal emulator instraction function called api_call that takes as arguments : crc32(Dll_name) ^ crc32(dll_function). The disaseembky of api_call still a challenge and may be presented in a future GTFO || POC paper. 
api_call links emulator Apis to the outside world.

Kernel emulator functions are embedded in native code. This kernel has its own Object manager but the managed objects are fewer than a normal kernel, there are aonly : File, Thread, Event, Mutant and semaphore objects (dt mpengine!objectmanager.FileObject). Objects are stored in a map 

Last but not least, Alexei exposes some intersing Defender engine functions : MpaddToScanqueue, MpCreateMemeryEngine and MpReportEvent.

Finally, Alexei pointed out that mpengine.dll embeds also other components as unpackers, parsers, scanning engines,etc. And It might be interesting to bootstrap a research project on that. Main developed code will be published at BH.

NB: Emulator IL was not dumped but it can be doable.

Cloudy With a Chance of Malware
I was not very excited by talk may be because I'm not interested by Threat Intelligence field. However, I'll try to stay partial when writing my notes.

Marika Chauvin presented a comparison between two malwares KasperAgent and  Cloudy in order to highlight their differences and similarities.
The story begins with KasperAgent which seemed linked to Micropsia Android malware. The first campaign was in May 2017, one of the main indicator related to this malware was the use of a specific User Agent : OPAER. This malware targeted Palestinian authorities using fake administrative documents. Some pdb strings seem to be used by this malware.
The analysis of KasperAgent allowed to spot a second variety called Cloudy, however the attack vector used by this malware consisted in fake document used to be exchanged between inter-nation relation states.
At the opposite of KasperAgent, Cloudy malware target other countries as : Israel, India and UAE.
Both malware were attributed UAE.

SiliVaccine: North Korea's weapon of Mass Detection 
That was an interesting talk where the speakers shed light on some shady zones inside a north Korean antivirus known as Silivaccine.

First of all, Checkpoint resarchers said that they obtained the antivirus from Martyn Wiliams who's a journalist specialized in North Korea.
After its installation, the speakers presented the general picture of the antivirus architecture. The antivirus components can be splitted into:

  • UM components: SVshell.dll, SVkernel.dll (file scanning engine), SVregsrv.dll, SV2Tray.exe, SVupdate.exe, SVDiffUpd.exe (integrity checker), SVMain.exe and SVdealer.exe
  • KM components: SVhook.sys, SVstdi2.sys (supposed to hook tcp communication but it does nothing), SVFiltmsg.sys

During their investigation, the researcher stumbled from surprise to surprise. Looking at the strings, allows them to spot a DLL name (vspai32.dll) which belongs to Trend Micro Antivirus. In addition to that the bindiffing between Silivaccine and Trend Micro dlls resulted in 100% match and similar call graphs. The only differences concern inlining some functions in Sillivaccine (that might let suppose that Silivvacine has access to some source code) .

As Silivaccine has potentially the same antivirus engine as TrendMicro, Checkpoint researchers wondered if it has the same database signature format.  Hence, they find that Silivaccine has added an encryption layer to Trend Micro signature databases (using "Pattern Encryption" as an encryption key in Korean keyboard). Moreover, Silivaccine authors modified the naming convention of the virus  and malwares that can be identified (TM : MAL_NUCRP_5 becomes mal.nucrp.f in SV) . By the way they discovered that this malware is white-listed by SV even this specimen is a generic one. They did not come across about the reason of this exception.

 Regarding KM drivers, it seems that they were packed using an old Russian packer (simple xor with 0x42):

  • SVFilter is loaded by SVdealer.exe and it's in charge of real time scanning and protection of SV binaries
  • SVhook.sys: loaded by SVMain.exe and only query kernel objects without any hooking techniques and contains a lot of code that is never used.

Some coding styles made the analysis funnier. For example, the researchers spotted that in a UM component the length of a buffer can be set to a fixed value (0x12) and when the KM module receives the buffer it checks its length as : if ( len(buffer) == 0x12 return ERROR). Maybe the two modules were written by two different person who does not communicate.
Another joke concerns the use of  debugging message with IDA pro names : Dbgprint (" sub_xxxx bah"), which may indicate that SV authors dumped a lot of code from their TrendMicro reversing sessions.

The last part of the talk  focused on Silivaccine origins. Different hypothesis were emitted here (STS tech service: a ghost company, a collaboration with a Japanese company).
In all cases, it seems that Silivaccine is distributed with a MS patch signed by Kaspersky and that latter corresponds to Jaku malware first stage (may be because it targeted Martyn Wiliams).


Building a Damned Good Watch
Actually, this field is not my cup of tea. However  Travis Goodspeed is a passionate security researcher and he's able to communicate his passion. So let's see if I picked up something or not !

So yeah Travis one day dreamed about "a nifty wristwatch. It would have years of battery life, with an MSP430 microcontroller and RPN calculator. It would be able to receive and transmit on amateur radio frequencies, in a variety of digital modes. It would look spiffy."

I suspect that you guess it, it's better for you to go to his blog and read the article, either I'll confuse with my notes.


PreVice: Static Detection of Hooking Capabilities in Machine Code
The main idea if PreVice tool is to detect hooking capabilities in Windows PE before it happens. The speakers began their talk by a demo of the tool. Then the went through a brief introduction of the different hooking (Unsanctioned interception of execution, unofficial, no contract) techniques. They distinguished between:

  • Code hooking (detours): export and import table
  • System Call  : SYSCALL, SYSENTER, MSR, IDT and SSDT

Before presenting the internals of PreVice tool, the speakers gave an overview of existent tools:


The static analysis approach exposed by the speaker consists in considering a program as a set of functions that gives a state instead of taking it as state that changes during the execution. The main challenges that they fixed are performance and accuracy.

So, Previce inner working includes:

  • Code machine to instructions translation 
  • Constraint propagation 
  • Symbolic execution
  • Type information propagation  
  • Static Single Assignment (SSA)  

Having a code view of the code they can apply a set of signature to identify potential hooking regions  (ex: FS → TEB → PEB → ImageBase → ImortTable).

Meet Salinas, the first ever SMS-commanded Car Infotainment RAT
This talk was just amazing, the speakers were very enthusiastic and engaged in their explanations.
The idea here is to find a way to compromise a car infotainment system by targeting the car driver (especially his phone) instead of the car directly.

The first challenge that they had to overcome was to find an Infotainment system and its wiring diagram. Moreover, the infotainment ideally has to be an ARM architecture with a bluetooth stack, a CAN bus, USB and ethernet  plug.

The first step that they achieve, once they got their Infotainment system (201B 0920-201B) is they got a shell access (after a port scan that pops up a SSH access and a password brute force attack).

To have a persistant access to the Infotainment system, the researchers exploited similar to Windows Service management (SCM) based on a configuration file (sm.conf) to add a new service after remounting system partition in read/write. This service will be used a component in the RAT design.

Before introducing how the RAT actually was developed, it is interesting to know that some Infotainment internal architecture. This latter is organized around the MMUI -Multi Medi User Interface (an opera browser + local webserver + websocket) . The MMUI is linked to other components (Service manager, Radio, GPS, Bluetooth stack, CAN bus,etc) over DBUS.

To interact with these different component, the speakers discovered a test application left by the vendor that can be configured using a xml file to trigger specific tests. Thus reversing this application allowed them to understand how to communicate with these components. By the way they crashed at this stage their infotainment 3 weeks before recon CFP closing. Hopefully they got a second access through an UART port.

Analyzing the communication between MMUI and a linked phone via Bluetooth, it was possible for them to understand how a SMS is handled by the Infotainment system.

Infotainment --> MMUI --> MSG interface/DBUS --> BDS (Bluetooth Developer Studio) --> Phone

  • Receiving a SMS triggers an event in BDS 
  • BDS sends a notification over DBUSto MSG interface (service)
  • At the other hand  the MMUI usi MSG interface apis to to respond to an incoming SMS 
  • The SMS is stored then in a local sqlite DB (not encrypted)
The last that they have to resolve before completing the RAT is to identify the phone number linked to the car. For that they opted to sniffing DBUS communication (use dbus_monitor and dbus_send).

Finally, the attack demo consisted in:
  • connecting a USB key with Salinas RAT to be installed on the Infotainment system
  • Disconnecting the paired phone 
  • Intercepting the new pairing session 
  • grab the phone number by sniffing DBUS communication 
  • send SMS commands to the paired phone that will transfer it to the RAT.
I hope that I did  not missed a point ! 




Monday, July 21, 2014

Challenge SSTIC 2014

[ En mode Draft ... relecture en cours]
Introduction:

Cette année j'ai pu me pencher sur le challenge SSTIC (http://communaute.sstic.org/ChallengeSSTIC2014) et ce dernier n'a pas failli à sa réputation ...Merci à l'équipe QuarksLab pour cette souffrance :)

Etape1: usbmon

La première partie correspond à une capture USB apparemment réalisée entre un device 'Android' et une machine utilisant le protocole ADB.

Pour avoir une idée sur le contenu de ce fichier l'outil usb-analyzer a été utilisé.Un autre outil (voir "usbmon_helper.py") permet de visualiser le contenu d'une capture usbmon en HTML.

Une première analyse a vite révélé que la capture contient un transfert de fichier entre le device Android et une machine cible.

Le protocole ADB indique que pour un transfert de fichier les commandes suivantes doivent être enchaînées selon le format suivant:

Send → AdbMessage(A_OPEN, local_id, 0, "sync:");
Receive ← AdbMessage(A_OKAY, remote_id, local_id, NULL);
Query File Attributes. If file exists, then proceed.
Send → AdbMessage(A_WRTE, local_id, remote_id, "RECVnnnn");
Receive ← AdbMessage(A_OKAY, remote_id, local_id, NULL);
Send → AdbMessage(A_WRTE, local_id, remote_id, "remote file name");
Receive ← AdbMessage(A_OKAY, remote_id, local_id, NULL);
Receive ← AdbMessage(A_WRTE, remote_id, local_id, "DATAnnnn......");
Send → AdbMessage(A_OKAY, local_id, remote_id, NULL);
Receive ← AdbMessage(A_WRTE, remote_id, local_id, data);
Send → AdbMessage(A_OKAY, local_id, remote_id, NULL);
...
Receive ← AdbMessage(A_WRTE, remote_id, local_id, "DONEnnnn");
Send → AdbMessage(A_WRTE, local_id, remote_id, "QUITnnnn");
Receive ← AdbMessage(A_CLSE, remote_id, local_id, NULL);
Send → AdbMessage(A_CLSE, local_id, remote_id, NULL);

L'outil "usbmon_helper.py" a été légèrement modifié pour récupérer le contenu binaire du fichier transféré par le protocole ADB (voire stage1.bin)

Le fichier idb produit est stage1.i64


Etape 2: premier binaire ARM 64 bit

Environnement de travail
Afin d'avoir un environnement d'analyse les composants suivants ont été utilisés:


  • Une machine virtuelle basée sur l'outil "Foundation Model v8" qui offre un environnement de virtualisation d'un cpu ARMv8 et qui pemet de démarrer un système Linux.
  • Un système Linux (ubuntu) pour ARM 64 bits.


Donc en gros on dispose d'une machine virtuelle ubuntu ARM 64 bits. Cela permet de compiler les outils nécessaires à l'analyse de notre binaire.

L'idée est d'analyser le binaire récupéré de l'étape précédente en combinant une analyse dynamique avec gdb et une analyse statique avec IDA.

Pour coller les deux morceaux, l'outil Qbsync de QuarksLab a été utilisé, ce dernier permet de visualiser les étapes de débogage sur IDA d'ou la nécessité d'avoir un gdb compilé avec python (possible avec la machine virtuelle):

L’exécution du binaire permet de comprendre l'objectif de cette étape, ce dernier demande la saisie d'une clé permettant de récupérer un fichier nommé 'payload.bin'.

(Pour plus de détails sur l'analyse suivante, s’appuyer le fichier idb)

En déboguant pas à pas le binaire, on arrive à identifier le flux suivant:
Au niveau du point d'entrée, on retrouve un appel vers sub_1010C:

loc_102E0               ; Store Pair
FD 7B BF A9                                  STP             X29, X30, [SP,#var_10]!
FD 03 00 91                                  MOV             X29, SP ; Rd = Op2
89 FF FF 97                                  BL              sub_1010C ; Branch with Link
01 7C 40 93                                  SBFM            X1, X0, #0, #0x1F ; Signed Bitfield Move
E0 03 01 AA                                  MOV             X0, X1  ; Rd = Op2
C8 0B 80 D2                                  MOV             X8, #0x5E ; Rd = Op2
01 00 00 D4                                  SVC             0       ; Supervisor Call
E1 03 00 AA                                  MOV             X1, X0


Après plusieurs itérations, le binaire arrive à la section du code suivante:

.text:00000000000102A8                 LDRSW           X24, [X29,#arg_58] ; Load from Memory
.text:00000000000102AC                 LDR             X1, [X29,#arg_50] ; Load from Memory
.text:00000000000102B0                 MOV             SP, X25 ; Rd = Op2
.text:00000000000102B4                 SUB             SP, SP, #8 ; Rd = Op1 - Op2
.text:00000000000102B8                 STR             X24, [SP,#0x68+var_68] ; Store to Memory
.text:00000000000102BC                 MOV             X2, X1  ; Rd = Op2
.text:00000000000102C0                 BLR             X2      ; x2             0x400514 4195604
.text:00000000000102C4                 MOV             X23, X0 ; Rd = Op2
.text:00000000000102C8                 B               loc_10198 ; Branch
.text:00000000000102C8 ; End of function sub_1010C
.text:00000000000102C8

La suite d'itérations réalisées avant d'arriver à ce stade correspondent à la décompression d'une nouvelle section.
L'instruction BLR x2 permet à la première section du binaire de sauter vers une section nouvellement créée.

Ensuite avec gdb il est possible de dumper cette section (0x4000) quand peut aussi voir avec  la commande "cat /proc/mem/pid".

.text:00000000000102A8                 LDRSW           X24, [X29,#arg_58] ; Load from Memory
.text:00000000000102AC                 LDR             X1, [X29,#arg_50] ; Load from Memory
.text:00000000000102B0                 MOV             SP, X25 ; Rd = Op2
.text:00000000000102B4                 SUB             SP, SP, #8 ; Rd = Op1 - Op2
.text:00000000000102B8                 STR             X24, [SP,#0x68+var_68] ; Store to Memory
.text:00000000000102BC                 MOV             X2, X1  ; Rd = Op2
.text:00000000000102C0                 BLR             X2      ; x2             0x400514 4195604
.text:00000000000102C4                 MOV             X23, X0 ; Rd = Op2
.text:00000000000102C8                 B               loc_10198 ; Branch
.text:00000000000102C8 ; End of function sub_1010C
.text:00000000000102C8


Une fois cette section dumpée, il a été possible de l'ajouter au niveau de l'idb (IDA) courant afin de faciliter la suite de l'analyse. une attention a été portée sur l'ajout de la section au niveau de l'idb d'IDA afin que le mapping dynamique correspond au sections statique.

On continue l'analyse dynamique/statique avec la combinaison gdb/qbsync/IDA.
Cette deuxième partie du binaire est 'obfusquée' en utilisant une machine virtuelle. Par conséquence, l'objectif de cette étape consiste à comprendre le fonctionnement de la machine virtuelle. Pour cela il faut:
+ Identifier et récupérer le byte code de la machine virtuelle
+ Identifier l'ensemble des instruction de la machine virtuelle
+ Identifier la mémoire, la pile et les registres utilisés par la mémoire virtuelle.

Une fois l'ensemble de ces élements, un décodeur sera écrit afin de désassembler le Byte code de la VM. Pour cela l'outil AMOCO a été utilisé.

(une lecture du chapitre obfuscation par la virtualisation Practical Reverse Engineering a aidé à connaitre la notion de VM Hanlder/Dispatcher, fonction de récupération de registre, fonction de récupération de valeur de registres, boucle principale).
La partie suivante essayera de mettre en évidence ces élements (même si je ne me rapelle plus de l'ordre que j'ai suivi pour mettre en évidence ces élements)

Une fois décompressée, le binaire saute à la section 0x400000 (à l'adresse 0x400514), il enchaîne l’exécution de plusieurs instructions(brève description) :

1. Appel de la fonction 0x4000524:
text:0000000000400524                 B               Call_svc_exit_group ; Branch

2.Appel de la fonction 0x04004F8 que je qualifie de VM Main Entry:

             X2, X2, #unk_510018@PAGEOFF ; x2             0x510018
             STR             X3, [X2] ; Store to Memory
            BL              Main_Entry ; Branch with Link                                        SBFM            X1, X0, #0, #0x1F

3.Appel de la fonction 0x04000C8 que je que qualifie de 'VM set context' car elle permet de mettre en place les composants de la VM (sections mémoires, context crypto):

.text:00000000004000C0                 ADD             X0, X0, #unk_500000@PAGEOFF ; Rd = Op1 + Op2
.text:00000000004000C4                 ADD             X2, X29, #0x10 ; Rd = Op1 + Op2
.text:00000000004000C8                 BL              VM_set_context ; x0             0x500000 5242880
.text:00000000004000C8                                         ; x1             0x10000  65536
.text:00000000004000C8                                         ; x2    

En effet le syscall présents au niveau de cette fonction  permettent de répérer les sections mémoires utilisé par la VM.

La section 0x500000 attire notre attention, aprés avoir dumpé le contenu de cette dernière, elle semble obfusquée (voir vm_bytecode.bin) .


Toutefois en arrivant à la section du code suivant:
.text:0000000000402A88                 BL              Func_Ecrypt_init ; Branch with Link
.text:0000000000402A8C                 ADD             X22, X19, #0x10 ; Rd = Op1 + Op2
.text:0000000000402A90                 ADRP            X1, #unk_510000@PAGE ; x1             0x510000 5308416
.text:0000000000402A94                 MOV             X0, X22 ; Rd = Op2
.text:0000000000402A98                 ADD             X1, X1, #unk_510000@PAGEOFF ; Rd = Op1 + Op2
.text:0000000000402A9C                 MOV             W2, #128 ; le parametere kbits
.text:0000000000402AA0                 MOV             W3, #0  ; Rd = Op2
.text:0000000000402AA4                 BL              Func_KEy_setup ; void ECRYPT_keysetup(ECRYPT_ctx *x,const u8 *k,u32 kbits,u32 ivbits)
.text:0000000000402AA8                 ADRP            X1, #unk_510020@PAGE ; Address of Page
.text:0000000000402AAC                 MOV             X0, X22 ; Rd = Op2
.text:0000000000402AB0                 ADD             X1, X1, #unk_510020@PAGEOFF ; x1             0x510020 5308448
.text:0000000000402AB4                 BL              func_Ecrypt_ivsetup ; Branch with Link
.text:0000000000402AB8                 LDRB            W0, [X19] ; Load from Memory

En inspectant le contenu de la mémoire , on retrouve la chaine ""expand 16-byte k" qui en recherchant sur Internet permet de d'identifier en premier lieu l'algorithme de chiffrement Salsa puis dans un deuxième temps sa version Chacha.

En comparant le code C des différentes fonctions de cet algorithme, comme
void ECRYPT_ivsetup(ECRYPT_ctx *x,const u8 *iv)
{
  int i = 0 ;
  x->input[12] = 0;
  x->input[13] = 0;
  x->input[14] = U8TO32_LITTLE(iv + 0);
  x->input[15] = U8TO32_LITTLE(iv + 4);
  //Printing the context
  printf("[ECRYPT_ivsetup] The Chacha context:\n");
   for (i=0; i<16 i="" p="">     printf("0x%x\n", x->input[i]);
}

et le code assembleur à l'offset 0x402AB4 on retrouve rapidement des similitudes.

La comparaison a permis de s'orienter plutôt vers la variante chacha que salsa. Ce qui est intéressant à ce satade est d'identifier la clé utilisée par cet algorithme. Cette information peut être obtenue en mettant un breakpoint à l'appel de la fonction 'ECRYPT_keysetup' qui reçoit en second paramètre la clé de chiffrement.


- Chiffrement Salsa/Chacha
-------------------------------------

Il se trouve que la section 0x500000 est chiffré avec l'algorithme de chiffrement chacha. le code chacha_test.c a permis de récupérer le contenu de cette section en clair
(voir VM_bytecode_dec.bin).

A ce stade on dispose du Byte code de la VM:

00000030   00 00 00 00  00 20 00 00  00 00 00 00  40 00 00 00  ..... ......@...
00000040   00 01 00 00  01 21 00 00  00 02 00 00  01 12 00 00  .....!..........
00000050   00 03 00 00  01 E3 32 00  00 04 00 00  01 44 02 00  ......2......D..
00000060   1D 00 00 01  00 00 01 11  00 00 0A 22  00 03 00 00  .

la fin du byte code contient les chaines de carctères affichés lors de l'exécution de notre binaire
20 50 6C 65  61 73 65 20  65 6E 74 65  72 20 74 68   Please enter th
00000340   65 20 64 65  63 72 79 70  74 69 6F 6E  20 6B 65 79  e decryption key
00000350   3A 20 00 00  3A 3A 20 54  72 79 69 6E  67 20 74 6F  : ..:: Trying to
00000360   20 64 65 63  72 79 70 74  20 70 61 79  6C 6F 61 64   decrypt payload
00000370   2E 2E 2E 0A  20 20 20 57  72 6F 6E 67  20 6B 65 79  ....   Wrong key
00000380   20 66 6F 72  6D 61 74 2E  0A 00 20 20  20 49 6E 76   format...   Inv
00000390   61 6C 69 64  20 70 61 64  64 69 6E 67  2E 0A 00 00  alid padding....
000003A0   20 20 20 43  61 6E 6E 6F  74 20 6F 70  65 6E 20 66     Cannot open f
000003B0   69 6C 65 20  70 61 79 6C  6F 61 64 2E  62 69 6E 2E  ile payload.bin.
000003C0   0A 00 3A 3A  20 44 65 63  72 79 70 74  65 64 20 70  ..:: Decrypted p
000003D0   61 79 6C 6F  61 64 20 77  72 69 74 74  65 6E 20 74  ayload written t
000003E0   6F 20 70 61  79 6C 6F 61  64 2E 62 69  6E 2E 0A 00  o payload.bin...
000003F0   70 61 79 6C  6F 61 64 2E  62 69 6E 00  58 58 58 58  payload.bin.XXXX


Ce qui permet de valider notre hypothèse sur le chiffrement utilisé.

- Le VM Dispatcher
----------------------------

L'analyse dynamique du code a révelé la présence du code suivant:
(La copie d'IDA n'est pas propre):
                                     MOV  X0, X19 ; param1
.text:0000000000402844                 BL              VM_Dispatcher ; x0             0x7fb7ffe000 --> la table des handlers + context (encryption key)
.text:0000000000402844                                         ; x1             0x3c 60
.text:0000000000402844                                         ; x2             0x7ffffff6f0
.text:0000000000402844                                         ; x/40xw $x2
.text:0000000000402844                                         ; 0x7ffffff6f0:0x00000048 0x00000000 0x00002101 0x00000001
.text:0000000000402844                                         ;
.text:0000000000402844                                         ; x3             0x4  4
.text:0000000000402848                 LDRB            W0, [X29,#0x5C] ; Load from Memory
.text:000000000040284C                 LDR             W1, [X29,#0x58] ; Load from Memory
.text:0000000000402850                 ADD             X0, X0, #0x6C ; x0             0x6d 109
.text:0000000000402854                 LDR             X2, [X19,X0,LSL#3] ; Load from Memory
.text:0000000000402858                 MOV             X0, X19 ; Rd = Op2
.text:000000000040285C                 BLR             X2      ; à la sortie du 9ème appel
.text:000000000040285C                                         ; x2 0x401490
.text:000000000040285C                                         ;
.text:000000000040285C                                         ; 0x400d9c
.text:000000000040285C                                         ; 0x401580
.text:000000000040285C                                         ;
.text:000000000040285C                                         ; après le message Wrong Key
.text:000000000040285C                                         ; 0x401794
.text:000000000040285C                                         ; 0x4005fc

Ce qu'il faut reteir ici à ce stade, est que cette fonction est appelée à l'exécution de chaque instruction de la VM. Cette dernière reçoit l'instruction de la VM àéxecuter et retourne l'adresse du 'Handler" qui permet de traduire le code de la VM vers le code de l'architecture arm 64 bits.


Les VM Handlers
----------------------------
(Par manque de temps je n'arriverai pas à détailler tout les handler voir l'idb IDA pour l'ensemble, je présente ici un seul mais la méthode reste la même)

exemple pour le Handler ADD
text:0000000000400934                 ORR             X19, X0, X0 ; Rd = Op1 | Op2
.text:0000000000400938                 BL              Fetch_Register_value ; Branch with Link
.text:000000000040093C                 MOV             W22, W0 ; Rd = Op2
.text:0000000000400940                 MVN             X0, X19 ; Rd = ~Op2
.text:0000000000400944                 UBFM            X1, X21, #0xC, #0xF ; Unsigned Bitfield Move
.text:0000000000400948                 MVN             X0, X0  ; param1
.text:000000000040094C                 BL              Fetch_Register_value ; Branch with Link
.text:0000000000400950                 ADD             W2, W0, W22 ; Rd = Op1 + Op2
.text:0000000000400954                 EOR             X0, X0, X19 ; Rd = Op1 ^ Op2
.text:0000000000400958                 MOV             W1, W20 ; Rd = Op2
.text:000000000040095C                 EOR             X19, X19, X0 ; Rd = Op1 ^ Op2
.text:0000000000400960                 EOR             X0, X19, X0 ; Rd = Op1 ^ Op2
.text:0000000000400964                 LDP             X21, X22, [SP,#0x20+var_s0] ; Load Pair
.text:0000000000400968                 ORR             X19, X0, X0 ; Rd = Op1 | Op2
.text:000000000040096C                 LDP             X19, X20, [SP,#0x20+var_10] ; Load Pair
.text:0000000000400970                 LDP             X29, X30, [SP+0x20+var_20],#0x30 ; Load Pair
.text:0000000000400974                 B               VM_update_register ; Branch

Pour l'opération ADD, la fonction nommée Fetch_Resgister récupère la valeur du premier registre dans W0 puis le deuxième appel de cette même fonction permet de récupérer la deuxième valeur. à l'offset .0000000000400950 indique la nature de l'opéreation (ADD). Enfin l'appel à la fonction VM_update_register permet de mettre à jour le registre résultat. On sait alors que l'instruction ADD a besoin d'un registre résultat  et deux registre opérandes.

Il est à noter que le début de chaque handler des opération de shift (UBFM à l'offset 400944) permettent à chaque fois de récupérer l'opcode de l'instruction puis les opérandes.

Les registres
------------------

L'analyse dynamique et l'étude la fonction précédente met en évidence l'utilisation de l'adresse mémoire 0x7fb7fed000. En effet cette dernière correpond au premier registre de la VM (nommé dans le decodeur reg0).


Pour déboguer la VM, un petit script gdb aidant à afficher le contenu des registres de la VM à chaque exécution:

define vv
cont
printf "Instruction --> %0.8x\n", *(0x7ffffff6f8)
printf "----------\n"
printf "Registers:\n"
printf "----------\n"
printf "reg1 : 0x%x ,  \t" , *(0x7fb7fed000)
printf "reg2 : 0x%x ,  \t" , *(0x7fb7fed004)
printf "reg3 : 0x%x ,  \t" , *(0x7fb7fed008)
printf "reg4 : 0x%x ,  \n" , *(0x7fb7fed00c)
printf "reg5 : 0x%x ,  \t" , *(0x7fb7fed010)
printf "reg6 : 0x%x ,  \t" , *(0x7fb7fed014)
printf "reg7 : 0x%x ,  \t" , *(0x7fb7fed018)


Ce qui donne comme sortie à chaque passage par le VM Dispatcher:

Registers:
----------
reg1 : 0x14 ,   reg2 : 0x2 ,    reg3 : 0x38a ,          reg4 : 0x14 ,
reg5 : 0x46 ,   reg6 : 0x0 ,    reg7 : 0x9fff ,         reg8 : 0x0 ,
reg9 : 0x8 ,    regA : 0x0 ,    regB : 0x80 ,   regC : 0x1fff ,
regD : 0x8000 ,         regE : 0x40c ,          regF : 0x0 ,    regF/PC : 2b4 ,
(gdb)

Breakpoint 5, 0x0000000000402860 in ?? ()
Instruction --> 0000001c
----------
Registers:
----------
reg1 : 0x14 ,   reg2 : 0x2 ,    reg3 : 0x38a ,          reg4 : 0x14 ,
reg5 : 0x46 ,   reg6 : 0x0 ,    reg7 : 0x9fff ,         reg8 : 0x0 ,
reg9 : 0x8 ,    regA : 0x0 ,    regB : 0x80 ,   regC : 0x1fff ,
regD : 0x8000 ,         regE : 0x40c ,          regF : 0x0 ,    regF/PC : 2b4 ,
[Inferior 1 (process 478) exited normally]
[sync] exit, sync finished


Le désassemblage du code de la VM
------------------------------------------------

Disposant des handlers(et implicitement les instructions) , le nombre des registres il est possible de s'attaquer au décodeur.
En utilisant l'outil AMOCO il a été possible de décoder le Byte code de la VM. Cet outil permet en autre de définir une nouvelle architecture. Dans le répertoire arch de l'outil amoco, on peut décrire l'architecture de la VM (voir vm.zip):

Le fichier env.py permet de décrire les registre de notre VM:
reg0   = reg('reg0',32)
reg1   = reg('reg1',32)
reg2   = reg('reg2',32)
reg3   = reg('reg3',32)
reg4   = reg('reg4',32)
reg5   = reg('reg5',32)
reg6   = reg('reg6',32)
reg7   = reg('reg7',32)
reg8   = reg('reg8',32)
reg9   = reg('reg9',32)

...

Le fichier spec_vm.py permet de décrire le décodage des instructions, ci-dessous le décodage des instructions nommées MOVh et MOVl:


@ispec("32[ IMM(20)  REG(4) {00} ]", mnemonic="MOVh")
@ispec("32[ IMM(20)  REG(4) {01} ]", mnemonic="MOVl")
def VM_MOV(obj,IMM,REG):
    src = env.cst(IMM,20)
    dst = env.R[REG]
    obj.operands = [dst,src]
    obj.type = type_data_processing

Et enfin le fichier "asm.py" permet de décrire le comportement de l'instruction, exemple pour 'MOVh':

def i_MOVh(i,fmap):
  fmap[pc] = fmap[pc]+i.length
  dst,src = i.operands
  fmap[dst[16:32]] = fmap(src)



Il est à noter que la taille des instructions des VMs est de 16 et 32 bits.
le fichier (test_vmbytecode.py) permet de décoder le byte code de la VM. le fichier (VM_disassembly.txt) correspond au fichier sortie.

- Analyse du code de la VM
--------------------------------------

On retrouve des informations cohérentes comme le code qui demande d'entrer la clé:
[0x40] 00 01 00 00  : MOVh reg1,0x0                                                
[0x44] 01 21 00 00  : MOVl reg1,0x2 //syscall number 2
[0x48] 00 02 00 00  : MOVh reg2,0x0
[0x4c] 01 12 00 00  : MOVl reg2,0x1 //file descriptor
[0x50] 00 03 00 00  : MOVh reg3,0x0
[0x54] 01 e3 32 00  : MOVl reg3,0x32e //(32e offset of str: : Please enter the decryption key: ) (len 0x24)

La vérification de la taille:
[0x7e] 02 05 00 00  : LDR reg5,0x0,0x0 // get value at @adr+disp (len of buffer read)
[0x82] 00 03 00 00  : MOVh reg3,0x0
[0x86] 01 03 01 00  : MOVl reg3,0x10
[0x88] 13 35        : SUB reg5,reg3 // compare len of buffer read with 0x10
[0x8c] 08 6a b4 02  : JMPNE reg5,reg3,0x2b4 // Jump at offset 0x2B4 if reg5 != reg3 @dispaly Wrong key format
la clé doit faire 16 caractères.

Le code suivant permet de verifier que la clé ne contient que les caractères hexadécimlmaux:
[0x90] 00 0f 00 00  : MOVh regF,0x0
[0x94] 01 0f 01 00  : MOVl regF,0x10 //16 len of the key
[0x98] 00 0e 00 00  : MOVh regE,0x0
[0x9c] 01 ce 3f 00  : MOVl regE,0x3fc //offset of str: XXXXXXXXXXXXXXXX)len :0x10
[0xa0] 00 0d 00 00  : MOVh regD,0x0
[0xa4] 01 6d 32 00  : MOVl regD,0x326
[0xa6] 17 0d        : DEC regD
[0xaa] 00 02 00 00  : MOVh reg2,0x0
[0xae] 01 02 03 00  : MOVl reg2,0x30 '0'
[0xb2] 00 03 00 00  : MOVh reg3,0x0
[0xb6] 01 93 03 00  : MOVl reg3,0x39 '9'
[0xba] 00 04 00 00  : MOVh reg4,0x0
[0xbe] 01 14 04 00  : MOVl reg4,0x41 'A'
[0xc2] 00 05 00 00  : MOVh reg5,0x0
[0xc6] 01 65 04 00  : MOVl reg5,0x46 'F'
[0xca] 04 ec 00 00  : LOADB regC, [regE] //RegC vaut 0x41,0x31,0x32 //c'est plutôt un load
[0xce] 02 01 2c 00  : LDR reg1,0x2c,0x0 //Load character by charcter


[0xd2] 13 21        : SUB reg1,reg2 '0'
[0xd4] 08 82 b4 02  : JMPL reg1,reg4,0x2b4 //Display Wrong key format
......
et  la partie suivante est la partie la plus intéressante car elle permet de déchiffrer le payload.bin avec la clé fourni (juste après le syswrite:

[0x15e] 1d 00        : INT 0x0 (sys_write)

:: Trying to decrypt payload..
-------------------------------------

[0x160] 00 01 00 00  : MOVh reg1,0x0
[0x164] 01 61 32 00  : MOVl reg1,0x326 //806
[0x168] 02 1a 00 00  : LDR regA,0x0,
.........
L'approche adoptée à ce stade pour comprendre ce code de prime à bord illisible et de produire un code équivalent mais dans un langage plus lisible (python c'est bon!):
(lfsr_crypto.py)
while (payload_len != 0):
    #print"key_part1 : 0x%x - key_part2 0x%x"%(key_part1,key_part2)
    #LFSR PRNG
    tmp1 = key_part1 & 0xb0000000
    tmp2 = key_part2 & 0x1
    tmp1 = tmp1 ^ tmp2

    print "tmp1 is %x"%tmp1  
    parity = Parity(tmp1)
    print"Parity is %x"%parity

    #Right Rotate
    tmp1 = (key_part1 & 0x1) << 0x1f
    key_part2 = (key_part2 >> 0x1) | tmp1

    tmp1 = key_part1  >> 0x1
    parity  = parity << 0x1f
    key_part1 = tmp1 | parity

    print"Keypart %x%x"%(key_part2,key_part1)
 
    compteur = compteur -1
    #print"Compteur is %x"%compteur
    tmp = (key_part2 & 0x1) << compteur
    #print"key_part2 :  %x "%tmp
    x  = x | tmp

puis une optimisation pour un registre 64 bits:
(voir lfsr_crypto_64.py)
while (payload_len != 0):
    #print"key_part1 : 0x%x - key_part2 0x%x"%(key_part1,key_part2)
    #LFSR PRNG
    tmp1 = key_part & 0xb000000000000001
    #tmp1  =  (tmp1 | (tmp1 >> 32)) & 0xffffffff
    print"tmp1 is %x"%tmp1
    parity = Parity(tmp1)
    print"Parity is %x"%parity
    #Left Rotate
    #tmp1 = (key_part & 0x1) << 0x3f
    #key_part = (key_part >> 0x1) | tmp1
    key_part = key_part >> 0x1
    parity  = parity << 0x3f
    key_part = key_part | parity
    print "Keypart %x"%key_part
    compteur = compteur -1
    #print"Compteur is %x"%compteur



Cette vue macro nous indique l’utilisation d'un algo de type LFSR à un seul état. Pour récupérer la clé de chiffrement il suffit de partir de l'état finale (récupéré depuis la section mémoire, retrouvé à la fin, déchiffré précedement à l'aide de l'algo chahcha).

le fichier lfsr_crypto_64_inverse.py permet de réaliser cette opération et récupérer la clé de chiffrement 0BADB10515DEAD11


Etape 3

A ce niveau on dispose d'un fichier upload.py qui permet d'envoyer un firmware (fw.hex) vers un microcontrôleur à distance.

Le format du microcontrôleur fournit correspond au format Intel Hex.

Sachant que le code du microcontrôleur n'a pas été fourni avec une documentation, il est souhaitable à ce stade de produire le décodeur qui permet de désassembler le code du firmware.
Cette analyse s'est déroulée en boite noire en utilisant la démarche suivante.
Modifier un octet du firmware et l'envoyer au serveur. Ce dernier retourne à chaque fois le message d'erreur suivant:

-- Exception occurred at 07D4: Invalid instruction.\n   r0:07D4     r1:0000    r2:0100    r3:00D4\n   r4:0700     r5:0000    r6:0000    r7:0000\n   r8:0000     r9:0000   r10:0000   r11:0000\n  r12:0000    r13:EFFE   r14:0000   r15:FD1C\n   pc:07D4 fault_addr:0000 [S:0 Z:0] Mode:kernel\nCLOSING: Invalid instruction.\n'

Le message est très clair permet d’identifier le nombre de registre (15 + le program counter).

En utilisant AMOCO, il a été possible de produire un décodeur (voir decodeur_fw.py).

Ci-dessous, un extrait du code désassemble (voir fw.code pour la totalité du code):
: [0x0000] 21 00  : movh r1,0x0
2: [0x0002] 11 1b  : movl r1,0x1b //
4: [0x0004] 20 01  : movh r0,0x1
6: [0x0006] 10 8c  : movl r0,0x8c //0x18C Firmware v1.33.7 starting.
8: [0x0008] c0 d2  : jmpl [ 0x8 + 0x0d2 + 2 : 0x dc] // jmp to syscall print

une attention à l’instruction jmpl (pour laquelle j'mis du temps à comprendre) comme certain contrôleur c'st un jmp link qui permet de stocker l’instruction de retour dans le regsitre r15.
Le code ci-dessus fait un apppel à la section du code 0xdc:
220: [0x00 dc ] c8 02  : jmpl 0x2,0x8 //syscall print
222: [0x00de] d0 0f  : Ret (jmp r15)

Les différents tests ont démontré que l'appel c8 02 correspond au syscall print (hypothèse) qui sera confirmée avec l'analyse du code kernel.

D'autre syscall vont être identifiées (comme le syscall exit et syscall write).

Pour le moment intéressons nous au syscall sys read. Des tests ont été effectués en remplaçant le code firmware correspondant au code désassemblé (ci-dessus) par les adresses et la taille des différents sections mémoires (Firmware, ummapped, RAM, secret memory HW registers et le kernel.

Ce test a permis de déterminer que toutes les sections sont en lecture sauf la section ummaped (ce qui est normal) et la secret memory.
Cependant, on dispose du code kernel (kernel.hex). En réutilisant le décodeur (écrit avec AMOCO) on arrive à désassembler le code du kernel (kernel.code).

La première vulnérabilité permet d'accéder en lecture à toutes les sections mémoires sauf la mémoire secrète:

Lorsqu'on demande la lecture de la mémoire secrète, on reçoit le message suivant:
x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00[ERROR] Printing at unallowed address. CPU halted.\n'
Traceback (most recent call last):
  File "upload.py", line 56, in
    print(resp.decode("utf-8"))
UnicodeDecodeError: 'utf-8' codec can't decode byte 0xaa in position 40: invalid start byte

Le message ci-dessus nous permet de localiser le code kernel produisant ce comportement:
65050: [0xfe1a] 21 00  : movh r1,0x0
65052: [0xfe1c] 11 33  : movl r1,0x33 //len of str
65054: [0xfe1e] 20 fe  : movh r0,0xfe
65056: [0xfe20] 10 26  : movl r0,0x26 // adr of str : [ERROR] Printing at unallowed address. CPU halted.\n
65058: [0xfe22] c3 c2  : jmpl 0xc2,0x3 [0xfde6] //fonction de printing
65060: [0xfe24] b3 02  : None

Cette fonction est appelée par une fonction un peu plus haut:
65018: [0xfdfa] 51 11  : and r1,r1,r1
65020: [0xfdfc] a0 1a  : None
65022: [0xfdfe] 69 e8  : add r9,r14,r8
65024: [0xfe00] 79 9c  : sub r9,r9,r12
65026: [0xfe02] a8 08  : None
65028: [0xfe04] 69 e8  : add r9,r14,r8
65030: [0xfe06] 79 9d  : sub r9,r9,r13
65032: [0xfe08] ac 02  : None
65034: [0xfe0a] b0 0e  : branch [0xfe1a]  if
65036: [0xfe0c] 39 99  : xor r9,r9,r9
65038: [0xfe0e] e9 e8  : loadb r9,r14,r8
65040: [0xfe10] f9 db  : storeb r9,r13,r11 //store dans HW registers
65042: [0xfe12] 68 8a  : add r8,r8,r10
65044: [0xfe14] 71 1a  : sub r1,r1,r10
65046: [0xfe16] b3 e2  : branch 0xfdfa if not zero
65048: [0xfe18] d0 0f  : ret r0

(note: il me reste quelque opcode que je n'ai pas écrit :)).
Le code ci-dessus (correspond au code du syswrite) vérifie à chaque l'adresse source avant de copier son contenu vers un HW registre (FC00), ce qui permet l'affichage.
Si l'adresse vaut F000 un saut vers le message d'erreur est alors enclenché.

Le deuxième syscall est celui du sys write
8: [0x0026] 20 11  : movh r0,0x11
40: [0x0028] 10 00  : movl r0,0x00
42: [0x002a] c0 b4  : jmpl [ 0x2a  + 0x0b4 + 2 : 0x e0] //syscall 03 syswrite
            //syswrite écrite 2093 (8339 cpu cycles) à l'adresse donnée
44: [0x002c] c0 b6  : jmpl [  0x2c + 0x0b6 + 2 : 0x e4]

Des tests visant à modifier l'adresse passée en paramètre à cette fonction permet d'avoir des erreurs indiquant des valeurs du pc différentes à chaque fois.

En analysant le code kernel de cette fonction elle s'est avéré qu'elle se charge d'écrire la valeur 0x2093 (8339) qui est le nombre de cycles d’exécution

Donc, la deuxième vulnérabilité quant à elle permet de rediriger le flux d’exécution du code kernel en contrôlant le paramètre en entrée du syscall 'write'

En manipulant le code du firmware on arrive à réduire le nombre de cycles


0\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00-- Exception occurred at 07D4: Invalid instruction.\n   r0:07D4     r1:0000    r2:0100    r3:00D4\n   r4:0700     r5:0000    r6:0000    r7:0000\n   r8:0000     r9:0000   r10:0000   r11:0000\n  r12:0000    r13:EFFE   r14:0000   r15:FD1C\n   pc:07D4 fault_addr:0000 [S:0 Z:0] Mode:kernel\nCLOSING: Invalid instruction.\n'
Traceback (most recent call last):
  File "change_fw.py", line 75, in
    print(resp.decode("utf-8"))
UnicodeDecodeError: 'utf-8' codec can't decode byte 0xfc in position 46: invalid start byte

Le code suivant permet ansi de récupérer le contenu de la mémoire secrète
(voir fw_vuln.hex)

:1007C000AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA89
:1007D000AAAAAAAA210B11FF20F010002DFC1D00CF
:1007E0002CF02A001A013BBB388859885111E908BE
:1007F000F9DB688A711AB3F4000000000000000001

 VERY CHALLENGING\n\xe2\x94\x80\xe2\x96\x8c\xe2\x96\x80\xe2\x96\x90\xe2\x96\x84\xe2\x96\x88\xe2\x96\x84\xe2\x96\x88\xe2\x96\x8c\xe2\x96\x84\xe2\x96\x92\xe2\x96\x80\xe2\x96\x92\xe2\x96\x92\xe2\x96\x92\xe2\x96\x92\xe2\x96\x92\xe2\x96\x92\xe2\x96\x91\xe2\x96\x91\xe2\x96\x91\xe2\x96\x91\xe2\x96\x91\xe2\x96\x91\xe2\x96\x92\xe2\x96\x92\xe2\x96\x92\xe2\x96\x90\n\xe2\x96\x90\xe2\x96\x92\xe2\x96\x80\xe2\x96\x90\xe2\x96\x80\xe2\x96\x90\xe2\x96\x80\xe2\x96\x92\xe2\x96\x92\xe2\x96\x84\xe2\x96\x84\xe2\x96\x92\xe2\x96\x84\xe2\x96\x92\xe2\x96\x92\xe2\x96\x92\xe2\x96\x92\xe2\x96\x92\xe2\x96\x91\xe2\x96\x91\xe2\x96\x91\xe2\x96\x91\xe2\x96\x91\xe2\x96\x91\xe2\x96\x92\xe2\x96\x92\xe2\x96\x92\xe2\x96\x92\xe2\x96\x8c   SO OPERATIONAL\n\xe2\x96\x90\xe2\x96\x92\xe2\x96\x92\xe2\x96\x92\xe2\x96\x80\xe2\x96\x80\xe2\x96\x84\xe2\x96\x84\xe2\x96\x92



\x96\x92\xe2\x96\x92\xe2\x96\x92\xe2\x96\x92\xe2\x96\x92\xe2\x96\x92\xe2\x96\x92\xe2\x96\x92\xe2\x96\x92\xe2\x96\x92\xe2\x96\x92\xe2\x96\x92\xe2\x96\x92\xe2\x96\x92\xe2\x96\x92\xe2\x96\x92\xe2\x96\x84\xe2\x96\x92\xe2\x96\x92\xe2\x96\x92\xe2\x96\x92\xe2\x96\x8c <66a65dc050ec0c84cf1dd5b3bbb75c8c challenge.sstic.org="">\n\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x96\x80\xe2\x96\x84\xe2\x96\x92\xe2\x96\x92\xe2\x96\x92\xe2\x96\x92\xe2\x96\x92\xe2\x96\x92\xe2\x96\x92\xe2



Game over

Sunday, April 15, 2012

HES 2012 the end !



Really, HES was just awesome, very technical with hot topics ...thanks a lot to the crew :) 

For those who want to see the video stream you can get it from here

Just get a glance time to time on HES web site to download the slides.

A french summary has been submitted by my team at this address:
http://www.devoteamblog.com/

HES 2012 day 3



Sorry, but I missed the keynote of the 3rd day. You can get the slides directly from HES web site.

Easy local Windows Kernel exploitation  by Cesar Cerrudo.


The goal of this presentation as expressed by Cerrudo is to show some simple tricks for windows exploitation vulnerability.
     
Before that, Cerrudo underlines that Windows exploitation still a dark art and there still few and good reliable kernel exploitation techniques.
Generally, for a specific vulnerability it can be possible to choose a specific value to write at a specific controlled kernel address.However, few techniques are generic and work across Windows Versions. 
Cerrudo pointed out that running code on kernel mode looking for and elevation of privilege could generates errors that cannot be caught for further analysis.

The current work of Cerrudo was inspired form  J00ru's paper "GDT and LDT In Windows Kernel".  This paper sheds lights on the following Windows API:
NtQuerySystemInformation (used by explorer to get information about process) allows to get the Kernel address of KPROCESS and returns  the 
struct_SYSTEM_HANDLE_TABLE_ENTRY_INFO {
   USHORT ProcessId
   ....

   PVOID Object // Kernel address
   } 
In Some wayss this structure helps to get Kernel information on any Windows in order to to execute an exploit. So what could be done then:

What if we can remove ACLs of almost Windows Object ?
What if we can set any privilges on a process token ? 
What if we can replace a process token ?

In all these cases, it is possible to do any of te above action with just one write. Indeed, Cerrudo stress on the fact that attackers are always looking for a system shell.
However, we don't need system shell for privilege escalation exploitation and that makes the exploitation easier.

The different techniques presented by Cerrudo could be summarized as below:
#1: Windows Object ACL 
kd> dt nt!_Object_HEADER
    0x000 PoinbterCount : INT 4B
     .....
    0x014 SecurityDescriptor : Prt32 information about the ACL (if you null out the field the object has no ACL any more )
    0x018 Body 
For that:
Get the target object (process....) kernel address using NtQuerySystemInformation 
Write NULL to [Object adr -0x14]
Manipulate the target object    

#2:Token privileges (Windows >Vista)
Typdef struct_TOKEN
 {
    typedef strruct_SEP_TOKEN_PRIVILEGES
  {
     UINT64 Present  
     UINT64 ENABLED; // all ones -- all privileges enabled 


...

#3:Token privileges (Windows XP et WINodws 2003) 
k>dt_TOKEN
+0x000 TokenSource      : _TOKEN_SOURCE

   +0x010 TokenId          : _LUID
   ...

If we can modify the Token it is possible to get powerful privileges as:
  • Debug programs
  • Take onwbership
  • Restore files and dir
  • Impersonate a client after auth
  • Load ad drivers
  • Create a token object
  • Act as part of the OS

    
So for Enabling privileges:
  • Get process primary token and then search its kernel address using NTquerySystemInormation
  • Write 0xFFFFFFFF (or the wanted value for the corresponding privileges) to TOKEN at +0x48 (0x14 Win XP)


to illustrate this technique, Cerrudo uses the exploit for Tarjei Mandt Kernel vulnerability(use after free) as below: 
dec dword ptr [eax +4]
    
if we can control only eax then is to hard to exploit , However in:
Windows XP  the default value is : TOKEN +0x48 == 0x80000000  
Win7 ==> 1000000000000 only one privilges i enabled by def SeChangeNotifyPrivileges

0x8000000-0x1 == 0x7FFFFFF ==> 1111111111111b lots of privileges 

#4:Process primary token
Typdef struct_EPROCESS (Win 7)
      { 
             Struct_EX_FAST_REF Token;

 kd>dt nt!_Object_HEADER

+x000 PointerCont   : Int4B

The goal here is to Replace  the process token by the system identity token by hooking NtOpenThreadToken and calling MsiInstallProduct then get the object kernel address using NtQuerySystemInfdo.
If multiple writes 
Increase reference count with first write to PinterCount [_TOKEN -0X18] (on 32) and the second write to replace Token on _EPROCESS with system token.
If one write
replace TOKEN on _EPROCESS, and after elevation and before exploit finishes duplicate the system token.

Conclusions
Exploiting some kernel vulnerabilities are made more easier using NTquerySystemInformation 
this API helps to build more reliable exploits
You don't need system shells to elevate our privileges

Just awesome ! thanks Cerrudo for this presentation ... 

Follow Cerrudo at @cesarcer



Yo Dawg I heard you like reversing by Aaron Portnoy & Brandon Edwards



All I could say concerning this talk is : ZDI team are just amazing. Indeed, in this talk they presented to us their IDA Toolbag.
So I won't give technical details about the tools for the simple reason that this latter contains a lot of features...


The speakers pointed out that during their job at ZDI they face a lot of problems due to some limitations in IDA Pro.
In consequence they decides to develop a  tool to mitigate these problems. For that, their tool include features into the following IDA modules: 


Data storage
Querying 
Navigation
Collaboration
...  




A demo of the ToolBag has been introduced by the speakers.


I suggest you to go and get a glance on the project : http://thunkers.net/~deft/code/toolbag/

Friday, April 13, 2012

HES 2012 day 2



Keynote by Fyodor Yarochkin : How evolution shapes the infosec


Fyodor Y. presentation covers his past experience and mainly focus on computer crime research. Actually, Fyodor Y. experience covers : Snort/IDS ,Honeypot and Intrusion detection. 

Fyodor Y. starts by underlining that malicious activities are linked to financial gain on Internet (China and Russia), that joins Raul Chieasa's Keynote on HES 2011. 

Fyodor Y. pointed various observations:
The fact is most security researchers focus on finding vulnerability and computers crime focus on how to gain money by exploting human vulnerabilities (SE) than deep and complex vulnerability
  
double-click mailing --> companies discussing malicious behaviour on the Net.
  
An example was given by F. of a malicious company that fakes a real advertisement company, making a flash file ad.

The crime engineer are developing attacks depending on the location of the victim kind a of customization. 
  
Glottalization of the crime scene (localisation does not matter)
  
Volumes of micro-transactions --> Stealing a 1 $USD from 1,000,000 still makes a $1, 000, 000 

There are other means of taking control over wealth than cash
  
F. points the new payment technologies as those based on phone to pay duties. Mobile payments are not supervised by the government in consequence a  parallel market is growing up (Android mobile are more and more targeted by attacks that makes mobile payment). Indeed an Android application seems to be clean at the first verification, bypassing the control of google market. But once the application is installed it triggers an update that get the malicious payload.
  
To conclude Fyodor stress the fact  Human vulnerability could not be fixed 
  
Fyodor Y. end his keynote by presenting his "Honeypot project"
Motivation: What is the risk of Taiwan networks being owned now"
  • Identify regional threats 
  • Cooperation with CERT
  •    Real-time exposure ....         . 

Hacking the NFC credit card for fun and debit . by Renaud Lifchitz


Firstly, I want to thank Renaud L. for the quality of its presentation because he was able to demonstrate a serious 
vulnerabilities regarding NFC systems basing on simple techniques and tools.

Renaud L. starts his presentation by introducing the following terms:
Contactless payment : daily payment with no need for card insertion and pin. Two main systems are present in the market: Visa Paywave and MatserCard Paypass 
     
NFC card could be recognized by a specific logo printed on them.
These card are developed using EMV standards (specification for data storage and security protocol .ISO 7816 standards) 
The card memory is a real filesystem with a root directory (MF)and folders (DF). BER TLV (very near to ASN.1) is used for 
data encoding (emvlab.org/tlvutils  for decoding tools).
                    
Card Commands requests are structured as : Class (targeted application), Instruction (read/write...), parameter, data length, data and the length of expected response.
The response contains mainly data and SWA/SW errors. 

After this refresher,  Renaud L. introduce the goal of his research. Indeed, his idea is to compare the security of NFC card with other security models as those of Passports or NAVIGO cards(used in France for public transportation).
Actually, Navigo card presents a good security level as no personal data are stored in them, use of good encryption and authentication mechanisms.

Regarding NFC cards, the first observation pointed out by Renaud L. is the lack of authentication and encryption                 
As a proof of concept, Renaud L. presented the necessary information and ingredients:

NFC frequencies: HF (13,56 Mhz) and LF (125-134 Khz) usages )
NFC readers: USB readers SCM SCLL3711 (40 euros) ACS ACR120U/ACR
Tools : scriptor (ISO 7816), Libnfc ,pn53x-tamashell          

The POC allows   Renaud L. to demonstrate that is possible to get remotely the following  data :
Confirmed : Cardholder (gender, first name and last name), PAN, Expiration data ,Magnetic strip data (for cloning card), transaction history 
Probably :no CVV (just one time-CVV possibly can be used for online payment
                   
To conclude  Renaud L. listed some possible attacks :
  1. Read victm data and us it in commerce web site CVV is not alwas asked
  2. Remote DOS attack
  3. Create a magnetic strip dump
  4. User tracking
For his demo  Renaud L. follows these steps:            
  1. Wake up the card : list passive target
  2. select banking application (AID) --> look at receipt 
  3. Read specific EMV record
However  Renaud L. notices the the distance still a limitation to the attack. That could be mitigated using an USRP and telescoping antenna.


Secure Password Managers" and "Military-Grade Encryption" on Smartphones: Oh Really by Andrey Belenko & Dmitry Sklyarov



This presentation aims to give an overview on security mechanisms used (or not) by password managers on Smartphones.

For that, the speakers firstly tried  to underline the difference between 
the capabilities (TPM, biometrics...) offered by a PC password manager and those (passwords and passcode) that exists on smartphones 

Moreover, on smartphones password managers have various handicap:
Pasword typing : it is hard to type long and complex password
Relatively slow CPU : Complex password-token transforms will impact the usability so handling passwords is more complex than PC

Before going deeper into the study results, speakers made as threat model based on the following assumptions:
The Attacker has physical access to the device, backup of the device and to the paswords manager database file. the attacker tries then to recover the master passwords.
Generally, the physical access is quite easy  (think of fake charging station) 

The device backup on : 
Apple IOS 
  • Needs device passwode or iTunes pairing (optional encryption PBKDF-2 SHA 1 with  10 0000 iterations).

Balckberry 
  • Needs device password (Optional encryption -not enforced-).

          
The database files could be retreieved  
Appple iOS
  • via afc  (need passcode) 
  • via ssh   (jailbroken device)
  • via (physical imaging)      

Blackberry 
  • Needs device password 

       
The analysis presented by the speakers was based on a top 10 of Apple and blackberry applications (free and paid applications)        
(Sorry but I wont give the analysis of all applications but you can refer to speakers's slides ).

As examples : 
BlackBerry Wallet  1.0
  • Stores sha-256 password
  • Password verification requires 2x sha256
  • No salt --> rainbow tables       


iOS password managers 
Free Tools : 
  • Store passwords is Doucments/Password_keeper.sqlite
  • Master password is always 4 digits
  • No data encryption 
  • Master password is stored in clear : SELECT ZPASSWORD from ....  

Paid tools 
  • Master key is encrypted with master password 
  • Use of iOS keychain 

                    
To conclude, speakers stated that Paid apps are not necessarily more secure than free ones.
              

All Your Calls Are Still Belong to Us - How We Compromised the Cisco VoIP Crypto Ecosystem by Daniel Mende and Enno Rey 


The speaker starts his presentation , before detailing the technical side, by a little refresher of what he calls the "7 sisters".
  • Access control   
  • Isolation 
  • Restriction
  • Encryption
  • Entity protection
  • Secure management 
  • Visibility

These 7 principals are the basics for securing infrastructure regardless the technology used. These principals can be broken down to a checklist. 

The speaker listed then different case studies to demonstrate that globally the above principal es. for example:   
Case study scope: Call center 1500 Voip 
Presence of MS08-67 , Weak password , use of the same passwords on different components
No access Layer protection in place (abusing STP/DTP/OSPF/...)
Globally, the speaker feels according to his experience that regarding Voip equipment no body feels responsible to patch this boxes which implies security vulnerabilities .
                  
The second part of the presentation aimed to explain Cisco mechanism for Voip encryption. Hence, a refresher of the use of certificates and their implications has been presented. 

Indeed in Cisco World lots of certificate are used in a complex manner:
CUCM : needs a certificate itself of tftp signing firmware 
CAPF:(CA) needs a certificate 
Phone: use a certificate generated by the CAPF used for the communication between the phone and the call manager
CTL: The Certificate Trust List (CTL) is the root of the whole trust chain used in the crypto system of the CUCM. The CTL contains a server certificate, public key, serial number, signature, issuer name, subject name, server function, DNS name and the IP address for each server in the Unified Communication environment.
  
The CTL file must be created by an administrator in order to activate the “Mixed Mode” of the CUCM. The CTL file itself is signed by the private key stored on the security token (aladin etoken)        

Cisco IP Phones are using two different certificate types :
Manufacture-installed certificate (MIC):
Locally significant certificate (LSC):     
        
Actually, the weak point of the whole CUCM Security Model is the Certificate Trust List, which can potentially be subverted.        
         
To understand how communications are encrypted between and Iphone and a call managern, it is necessary to understand How a phone gets its certificate: 
  1. Phone boots get the context CUCM
  2. CUCM sends an initial CTL file
  3. Phone checks if LSC is installed (local)
  4. If not contact CUCM to get a partial config file 
  5. CUCM sends a partial onfig 
  6. The Phone generate public/private key
  7. Send the public key to CUCM
  8. Signed 
  9. get it back 
  10. installed as certificate    

The speaker pointed out also some the following behaviour when playing with CTL :
  1. if validation fails reject CTL but old one get lost and we re back to initial provisioning state
  2. just accept the new one 

In other way, If this process is intercepted, by a Man-in-the-Middle attack, it is possible to replace the original
Certificate Trust List with a modified one.
                      
The attack scenario consists in:
  1. Traffic redirection between CUMC and phone
  2. Provide TFTP server
  3. Phone has to reboot  (SYN flood 30-50 sec ), any port can be used 
  4. Use this FTP server to provide CTL file
  5. Fake CTL main properties 
  6. Replace public key of CTLs own Signing Certificate 
  7. Replace public keys of matching CUCM certificate 

                  
Once the phone disposes of modified certs of its main communication partners, the attacker can: 
  1. Access the phone private key associated with LSC
  2. Read the encrypted config
  3. MITM SIP-TLS traffic
  4. Get user credentials
  5. Replace key materials
  6. Plus all the nice things that can be done with SIP protocol

                          
The demo is based on a Python script: ctl_proxy.py 
This small python script implements an TFTP server to serve modified CTL files and signed files to cisco
VoIP Hard- and Softphones. The tool is transparent from an TFTP view, so if a phone requests a special
file, this file is fetched from the CUCM TFTP server and served to the phone afterwards.

The tool is planned to be released on ERNW blog.