MEMLABS - LAB05

Writeup du cinquième lab MEMLABS


Cinquième writeup, cinquième challenge MEMLABS … allons-y pour l’intro :

We received this memory dump from our client recently. Someone accessed his system when he was not there and he found some rather strange files being accessed. Find those files and they might be useful. I quote his exact statement,

The names were not readable. They were composed of alphabets and numbers but I wasn’t able to make out what exactly it was. Also, he noticed his most loved application that he always used crashed every time he ran it. Was it a virus?

  • Note-1: This challenge is composed of 3 flags. If you think 2nd flag is the end, it isn’t!! :P
  • Note-2: There was a small mistake when making this challenge. If you find any string which has the string “L4B_3_D0n3!!” in it, please change it to “L4B_5_D0n3!!” and then proceed.
  • Note-3: You’ll get the stage 2 flag only when you have the stage 1 flag.

Process

Comme d’habitude, on commence par un pslist. J’ai noté ici les process intéressants :

Process PID PPID
WinRAR.exe 2924 1580
notepad.exe 2744 1580
NOTEPAD.EXE 2724 1580
WerFault.exe 2716 2632
NOTEPAD.EXE 1388 1580
WerFault.exe 780 2632
NOTEPAD.EXE 2056 1580
WerFault.exe 2168 2632

Winrar, plusieurs instances du bloc-notes dont certaines en majuscule, et trois instances de WerFault.exe, qui est le process lancé par Windows quand une application crash. Ca fait déjà beaucoup de choses à analyser, allons-y pas à pas !

WerFault

Je n’avais jamais vu le process WerFault avant, et après une petite recherche, je tombe sur cet article qui nous explique tout ce qui se passe lorsque une application crash et que l’OS lance WerFault. Visiblement, deux instances de WerFaut sont lancées, l’une par SYSTEM et l’autre par le process qui a crashé. On nous dit aussi que l’instance lancée par le process ayant crashé est démarrée avec les arguments -u (user-mode) et -p pour le PID du process en question.

Faisons donc un cmdlines sur les WerFault pour y voir plus clair :

┌──(kali㉿kali)-[~/Documents/ctf/MEMLABS]
└─$ python ~/volatility/volatility-2.6.1/vol.py -f MemoryDump_Lab5.raw --profile=Win7SP1x64 cmdline -p 2716,780,2168
Volatility Foundation Volatility Framework 2.6.1
************************************************************************
WerFault.exe pid:   2716
Command line : C:\Windows\SysWOW64\WerFault.exe -u -p 2724 -s 156
************************************************************************
WerFault.exe pid:    780
Command line : C:\Windows\SysWOW64\WerFault.exe -u -p 1388 -s 156
************************************************************************
WerFault.exe pid:   2168

Visiblement rien pour 2168, en revanche 2716 et 780 on respectivement pour l’argument -p 2724 et 1388, soit les deux NOTEPAD.EXE chelou en majuscule. J’ai l’impression que cette version de notepad n’est pas vraiment légitime, wait and see… En tout cas, j’imagine qu’on a trouvé la fameuse application qui crash au démarrage.

Notepad - premier flag

Très bien, regardons maintenant les process notepad. De la même manière, on va essayer de regarder avec quels arguments les instances ont été ouvertes :

┌──(kali㉿kali)-[~/Documents/ctf/MEMLABS]
└─$ python ~/volatility/volatility-2.6.1/vol.py -f MemoryDump_Lab5.raw --profile=Win7SP1x64 cmdline -p 2744,2724,1388,2056
Volatility Foundation Volatility Framework 2.6.1
************************************************************************
notepad.exe pid:   2744
Command line : "C:\Windows\system32\notepad.exe" 
************************************************************************
NOTEPAD.EXE pid:   2724
Command line : "C:\Users\SmartNet\Videos\NOTEPAD.EXE" 
************************************************************************
NOTEPAD.EXE pid:   1388
************************************************************************
NOTEPAD.EXE pid:   2056

Tiens, le NOTEPAD.EXE chelou a été lancé depuis C:\Users\SmartNet\Videos\, à priori un exe n’a rien à faire là-dedans ! Ca confirme bien l’impression que ce process n’est pas légitime, on va essayer de le dumper et de faire un strings dessus pour y voir plus clair :

┌──(kali㉿kali)-[~/Documents/ctf/MEMLABS]
└─$ python ~/volatility/volatility-2.6.1/vol.py -f MemoryDump_Lab5.raw --profile=Win7SP1x64 procdump -p 2724 -D .
Volatility Foundation Volatility Framework 2.6.1
Process(V)         ImageBase          Name                 Result
------------------ ------------------ -------------------- ------
0xfffffa800108cb30 0x0000000001000000 NOTEPAD.EXE          OK: executable.2724.exe

Ok, strings ne donne rien d’intéressant, en revanche VirusTotal flag bien le fichier comme malicieux.

A ce stade, j’ai essayé tout ce qui me passait par la tête : regarder les shellbags, la MFT, un memdump sur NOTEPAD.EXE malicieux, mais rien d’intéressant.

J’ai essayé le plugin screenshot, qui donne un wireframe des fenêtres ouvertes au moment du dump, et là quelque chose d’intéressant est apparu : une fenêtre du photo viewer était ouverte, avec un nom de fichier à rallonge !

Je suppose qu’il s’agit d’une string en base64, et en commençant à la recopier dans Cyberchef, les premières lettres donnent l’output flag … on est bien en présence d’un flag !

Comme j’avais la flemme de recopier la string à la main, j’ai cherché les premiers caractères dans un dump de la MFT que j’avais fait plus tôt, on trouve bien ZmxhZ3shIV93M0xMX2QwbjNfU3Q0ZzMtMV8wZl9MNEJfM19EMG4zXyEhfQ, ce qui dans Cyberchef nous donne flag{!!_w3LL_d0n3_St4g3-1_0f_L4B_3_D0n3_!!}. L’intro disait qu’il y avait une faute dans la string, on remplace donc L4B_3 par L4B_5.

A ce stade, on ne sait toujours pas vraiment à quoi servait ce NOTEPAD vérolé, mais on a notre flag !

WinRAR - second flag

Une fois encore, un cmdline pour voir ce qui s’est passé côté Winrar :

┌──(kali㉿kali)-[~/Documents/ctf/MEMLABS]
└─$ python ~/volatility/volatility-2.6.1/vol.py -f MemoryDump_Lab5.raw --profile=Win7SP1x64 cmdline -p 2924
Volatility Foundation Volatility Framework 2.6.1
************************************************************************
WinRAR.exe pid:   2924
Command line : "C:\Program Files\WinRAR\WinRAR.exe" "C:\Users\SmartNet\Documents\SW1wb3J0YW50.rar"

Tiens, un nom en apparence random, ça correspond avec ce que nous disait l’intro. Essayons de le récupérer :

┌──(kali㉿kali)-[~/Documents/ctf/MEMLABS]
└─$ python ~/volatility/volatility-2.6.1/vol.py -f MemoryDump_Lab5.raw --profile=Win7SP1x64 filescan | grep "SW1wb3J0YW50"       
Volatility Foundation Volatility Framework 2.6.1
0x000000003eed56f0      1      0 R--r-- \Device\HarddiskVolume2\Users\SmartNet\Documents\SW1wb3J0YW50.rar
                                                                                                                                         
┌──(kali㉿kali)-[~/Documents/ctf/MEMLABS]
└─$ python ~/volatility/volatility-2.6.1/vol.py -f MemoryDump_Lab5.raw --profile=Win7SP1x64 dumpfiles -Q 0x000000003eed56f0 -D .
Volatility Foundation Volatility Framework 2.6.1
DataSectionObject 0x3eed56f0   None   \Device\HarddiskVolume2\Users\SmartNet\Documents\SW1wb3J0YW50.rar

Ok, au moment de décompresser l’archive, on voit qu’elle contient un fichier qui s’appelle Stage2.png, mais elle est bien sûr protégée par mot de passe. L’intro disait qu’il fallait nécessairement le premier flag pour trouver le second, on va donc l’essayer comme mot de passe : ça fonctionne ! On obtient l’image suivante :

Ceci dit, l’intro nous disait que le challenge était composé de trois flags …

Le bloc note malicieux - dernier flag

J’ai pas envie de lâcher l’affaire avec ce process. J’ai commencé (mais jamais terminé …) une room sur radare2 sur TryHackMe, on va donc voir si on peut désassembler le binaire…

Quelque commandes plus tard, on arrive ici :

┌──(kali㉿kali)-[~/Documents/ctf/MEMLABS/malicious_notepad_procdump]
└─$ r2 NOTEPAD.EXE
[0x0100739d]> aa
[x] Analyze all flags starting with sym. and entry0 (aa)
[0x0100739d]> afl
0x0100739d   15 518  -> 463  entry0
0x010012b4    5 28   -> 31   sym.imp.WINSPOOL.DRV_GetPrinterDriverW
[0x0100739d]> pdf @entry0
            ;-- eip:
┌ 463: entry0 ();
│           ; var int32_t var_38h_2 @ ebp-0x38
│           ; var int32_t var_34h_2 @ ebp-0x34
│           ; var int32_t var_30h_2 @ ebp-0x30
│           ; var int32_t var_2ch_2 @ ebp-0x2c
│           ; var int32_t var_24h_2 @ ebp-0x24
│           ; var int32_t var_20h_2 @ ebp-0x20
│           ; var int32_t var_1ch_2 @ ebp-0x1c
│           ; var int32_t var_18h @ ebp-0x18
│           ; var int32_t var_bp_10h @ ebp-0x10
│           ; var int32_t var_8h_2 @ ebp-0x8
│           ; var int32_t var_4h_2 @ ebp-0x4
│           ; var int32_t var_8h @ ebp+0x14
│           ; var int32_t var_38h @ ebp+0x34
│           ; var int32_t var_34h @ ebp+0x38
│           ; var int32_t var_30h @ ebp+0x3c
│           ; var int32_t var_2ch @ ebp+0x40
│           ; var int32_t var_24h @ ebp+0x48
│           ; var int32_t var_20h @ ebp+0x4c
│           ; var int32_t var_1ch @ ebp+0x50
│           ; var int32_t var_4h @ ebp+0x68
│           ; var int32_t var_10h @ esp+0x20
│           0x0100739d      6a70           push 0x70                   ; 'p' ; 112
│           0x0100739f      6898180001     push 0x1001898
│           0x010073a4      e8bf010000     call 0x1007568
│           0x010073a9      33db           xor ebx, ebx
│           0x010073ab      53             push ebx
│           0x010073ac      8b3dcc100001   mov edi, dword [sym.imp.KERNEL32.dll_GetModuleHandleA] ; [0x10010cc:4]=0x756a1245 reloc.KERNEL32.dll_GetModuleHandleA ; "E\x12ju"
│           0x010073b2      ffd7           call edi
│           0x010073b4      6681384d5a     cmp word [eax], 0x5a4d
│       ┌─< 0x010073b9      751f           jne 0x10073da
│       │   0x010073bb      8b483c         mov ecx, dword [eax + 0x3c]
│       │   0x010073be      03c8           add ecx, eax
│       │   0x010073c0      813950450000   cmp dword [ecx], 0x4550
│      ┌──< 0x010073c6      7512           jne 0x10073da
│      ││   0x010073c8      0fb74118       movzx eax, word [ecx + 0x18]
│      ││   0x010073cc      3d0b010000     cmp eax, 0x10b              ; 267
│     ┌───< 0x010073d1      741f           je 0x10073f2
│     │││   0x010073d3      3d0b020000     cmp eax, 0x20b              ; 523
│    ┌────< 0x010073d8      7405           je 0x10073df
│  ┌┌──└└─> 0x010073da      895de4         mov dword [var_1ch], ebx
│  ╎╎││ ┌─< 0x010073dd      eb27           jmp 0x1007406
│  ╎╎└────> 0x010073df      83b984000000.  cmp dword [ecx + 0x84], 0xe
│  └──────< 0x010073e6      76f2           jbe 0x10073da
│   ╎ │ │   0x010073e8      33c0           xor eax, eax
│   ╎ │ │   0x010073ea      3999f8000000   cmp dword [ecx + 0xf8], ebx
│   ╎ │┌──< 0x010073f0      eb0e           jmp 0x1007400
│   ╎ └───> 0x010073f2      8379740e       cmp dword [ecx + 0x74], 0xe
│   └─────< 0x010073f6      76e2           jbe 0x10073da
│      ││   0x010073f8      33c0           xor eax, eax
│      ││   0x010073fa      3999e8000000   cmp dword [ecx + 0xe8], ebx
│      ││   ; CODE XREF from entry0 @ 0x10073f0
│      └──> 0x01007400      0f95c0         setne al
│       │   0x01007403      8945e4         mov dword [var_1ch_2], eax
│       │   ; CODE XREF from entry0 @ 0x10073dd
│       └─> 0x01007406      895dfc         mov dword [var_4h], ebx
│           0x01007409      6a02           push 2                      ; 2
│           0x0100740b      ff1538130001   call dword [sym.imp.msvcrt.dll___set_app_type] ; 0x1001338
│           0x01007411      59             pop ecx
│           0x01007412      830d9cab0001.  or dword [0x100ab9c], 0xffffffff ; [0x100ab9c:4]=0
│           0x01007419      830da0ab0001.  or dword [0x100aba0], 0xffffffff ; [0x100aba0:4]=0
│           0x01007420      ff1534130001   call dword [sym.imp.msvcrt.dll___p__fmode] ; 0x1001334
│           0x01007426      8b0db89a0001   mov ecx, dword [0x1009ab8]  ; [0x1009ab8:4]=0
│           0x0100742c      8908           mov dword [eax], ecx
│           0x0100742e      ff1530130001   call dword [sym.imp.msvcrt.dll___p__commode] ; 0x1001330
│           0x01007434      8b0db49a0001   mov ecx, dword [0x1009ab4]  ; [0x1009ab4:4]=0
│           0x0100743a      8908           mov dword [eax], ecx
│           0x0100743c      a12c130001     mov eax, dword [sym.imp.msvcrt.dll__adjust_fdiv] ; [0x100132c:4]=0x753732ec reloc.msvcrt.dll__adjust_fdiv
│           0x01007441      8b00           mov eax, dword [eax]
│           0x01007443      a3a4ab0001     mov dword [0x100aba4], eax  ; [0x100aba4:4]=0
│           0x01007448      e8a7010000     call 0x10075f4
│           0x0100744d      391d08960001   cmp dword [0x1009608], ebx  ; [0x1009608:4]=1
│       ┌─< 0x01007453      750c           jne 0x1007461
│       │   0x01007455      68f4750001     push 0x10075f4
│       │   0x0100745a      ff1528130001   call dword [sym.imp.msvcrt.dll___setusermatherr] ; 0x1001328
│       │   0x01007460      59             pop ecx
│       └─> 0x01007461      e877010000     call 0x10075dd
│           0x01007466      6810900001     push 0x1009010
│           0x0100746b      680c900001     push 0x100900c
│           0x01007470      e85d010000     call 0x10075d2
│           0x01007475      a1b09a0001     mov eax, dword [0x1009ab0]  ; [0x1009ab0:4]=0
│           0x0100747a      8945dc         mov dword [var_24h], eax
│           0x0100747d      8d45dc         lea eax, [var_24h]
│           0x01007480      50             push eax
│           0x01007481      ff35ac9a0001   push dword [0x1009aac]
│           0x01007487      8d45d4         lea eax, [var_2ch]
│           0x0100748a      50             push eax
│           0x0100748b      8d45d0         lea eax, [var_30h]
│           0x0100748e      50             push eax
│           0x0100748f      8d45cc         lea eax, [var_34h]
│           0x01007492      50             push eax
│           0x01007493      ff1520130001   call dword [sym.imp.msvcrt.dll___getmainargs] ; 0x1001320
│           0x01007499      8945c8         mov dword [var_38h], eax
│           0x0100749c      6808900001     push 0x1009008
│           0x010074a1      6800900001     push section..data          ; 0x1009000
│           0x010074a6      e827010000     call 0x10075d2
│           0x010074ab      83c424         add esp, 0x24
│           0x010074ae      a11c130001     mov eax, dword [sym.imp.msvcrt.dll__acmdln] ; [0x100131c:4]=0x753704d8 reloc.msvcrt.dll__acmdln
│           0x010074b3      8b30           mov esi, dword [eax]
│           0x010074b5      8975e0         mov dword [var_20h], esi
│           0x010074b8      803e22         cmp byte [esi], 0x22
│           0x010074bb      b862000000     mov eax, 0x62               ; 'b' ; 98
│           0x010074c0      50             push eax
│           0x010074c1      b869000000     mov eax, 0x69               ; 'i' ; 105
│           0x010074c6      50             push eax
│           0x010074c7      b830000000     mov eax, 0x30               ; '0' ; 48
│           0x010074cc      50             push eax
│           0x010074cd      b873000000     mov eax, 0x73               ; 's' ; 115
│           0x010074d2      50             push eax
│           0x010074d3      bb7b000000     mov ebx, 0x7b               ; '{' ; 123
│           0x010074d8      53             push ebx
│           0x010074d9      b94d000000     mov ecx, 0x4d               ; 'M' ; 77
│           0x010074de      51             push ecx
│           0x010074df      bb33000000     mov ebx, 0x33               ; '3' ; 51
│           0x010074e4      53             push ebx
│           0x010074e5      b86d000000     mov eax, 0x6d               ; 'm' ; 109
│           0x010074ea      50             push eax
│           0x010074eb      b85f000000     mov eax, 0x5f               ; '_' ; 95
│           0x010074f0      50             push eax
│           0x010074f1      b86c000000     mov eax, 0x6c               ; 'l' ; 108
│           0x010074f6      50             push eax
│           0x010074f7      b834000000     mov eax, 0x34               ; '4' ; 52
│           0x010074fc      50             push eax
│           0x010074fd      b842000000     mov eax, 0x42               ; 'B' ; 66
│           0x01007502      50             push eax
│           0x01007503      b835000000     mov eax, 0x35               ; '5' ; 53
│           0x01007508      50             push eax
│           0x01007509      b85f000000     mov eax, 0x5f               ; '_' ; 95
│           0x0100750e      50             push eax
│           0x0100750f      b84f000000     mov eax, 0x4f               ; 'O' ; 79
│           0x01007514      50             push eax
│           0x01007515      b856000000     mov eax, 0x56               ; 'V' ; 86
│           0x0100751a      50             push eax
│           0x0100751b      b865000000     mov eax, 0x65               ; 'e' ; 101
│           0x01007520      50             push eax
│           0x01007521      bb52000000     mov ebx, 0x52               ; 'R' ; 82
│           0x01007526      53             push ebx
│           0x01007527      b85f000000     mov eax, 0x5f               ; '_' ; 95
│           0x0100752c      50             push eax
│           0x0100752d      b821000000     mov eax, 0x21               ; '!' ; 33
│           0x01007532      50             push eax
│           0x01007533      b87d000000     mov eax, 0x7d               ; '}' ; 125
│           0x01007538      50             push eax
│       ┌─< 0x01007539      753a           jne 0x1007575
│       │   0x0100753b      59             pop ecx
│       │   0x0100753c      59             pop ecx
│       │   0x0100753d      c3             ret
..
        │   ; CALL XREF from entry0 @ 0x10073a4
│       └─> 0x01007575      44             inc esp
│           0x01007576      2410           and al, 0x10                ; 16
│           0x01007578      896c2410       mov dword [var_10h], ebp
│           0x0100757c      8d6c2410       lea ebp, [var_10h]
│           0x01007580      2be0           sub esp, eax
│           0x01007582      53             push ebx
│           0x01007583      56             push esi
│           0x01007584      57             push edi
│           0x01007585      8b45f8         mov eax, dword [var_8h]
│           0x01007588      8965e8         mov dword [var_18h], esp
│           0x0100758b      50             push eax
│           0x0100758c      8b45fc         mov eax, dword [var_4h_2]
│           0x0100758f      c745fcffffff.  mov dword [var_4h_2], 0xffffffff ; -1
│           0x01007596      8945f8         mov dword [var_8h_2], eax
│           0x01007599      8d45f0         lea eax, [var_bp_10h]
│           0x0100759c      64a300000000   mov dword fs:[0], eax
└           0x010075a2      c3             ret
[0x0100739d]> 

On dirait bien qu’un flag se cache là-dedans !

bi0s{M3m_l4B5_0VeR_!} est donc notre dernier flag !

Conclusion

Lab intéressant, j’ai pu apprendre pas mal de choses sur le fonctionnement de WerFault, et l’aspect pseudo-RE de la fin était marrant ! Ceci-dit, je trouve les indications un peu contre-intuitives, on s’atend à devoir chercher plusieurs fichiers, alors qu’en fait il n’en est rien.