Writeup: FlareOn 2020: 002 - garbage

Task description

1. TLDR

garbage graph

2. Dane wejściowe

Plik z zadaniem znajduje się tutaj. Hasło: flare.

Jedyną rzeczą jaką otrzymałem na początku tego zadania był plik garbage.exe

3. Inspekcja pliku garbage.exe

Zweryfikowałem plik narzędziem file:

$ file garbage.exe
garbage.exe: PE32 executable (console) Intel 80386, for MS Windows, UPX compressed

Plik był spakowany narzędziem UPX. Spróbowałem odpakować plik:

$ upx -d -o upx_removed.exe garbage.exe
                       Ultimate Packer for eXecutables
                          Copyright (C) 1996 - 2020
UPX git-d7ba31+ Markus Oberhumer, Laszlo Molnar & John Reiser   Jan 23rd 2020

        File size         Ratio      Format      Name
   --------------------   ------   -----------   -----------
upx: garbage.exe: OverlayException: invalid overlay size; file is possibly corrupt

Unpacked 1 file: 0 ok, 1 error.

No tak, w treści zadania, była uwaga, że plik jest uszkodzony.

Podejrzałem plik w narzędziu xxd:

$ xxd garbage.exe| less

...
00009e50: 0000 0000 0000 0000 6050 0100 3c3f 786d  ........`P..<?xm
00009e60: 6c20 7665 7273 696f 6e3d 2731 2e30 2720  l version='1.0' 
00009e70: 656e 636f 6469 6e67 3d27 5554 462d 3827  encoding='UTF-8'
00009e80: 2073 7461 6e64 616c 6f6e 653d 2779 6573   standalone='yes
00009e90: 273f 3e0d 0a3c 6173 7365 6d62 6c79 2078  '?>..<assembly x
00009ea0: 6d6c 6e73 3d27 7572 6e3a 7363 6865 6d61  mlns='urn:schema
00009eb0: 732d 6d69 6372 6f73 6f66 742d 636f 6d3a  s-microsoft-com:
00009ec0: 6173 6d2e 7631 2720 6d61 6e69 6665 7374  asm.v1' manifest
00009ed0: 5665 7273 696f 6e3d 2731 2e30 273e 0d0a  Version='1.0'>..
00009ee0: 2020 3c74 7275 7374 496e 666f 2078 6d6c    <trustInfo xml
00009ef0: 6e73 3d22 7572 6e3a 7363 6865 6d61 732d  ns="urn:schemas-
00009f00: 6d69 6372 6f73 6f66 742d 636f 6d3a 6173  microsoft-com:as
00009f10: 6d2e 7633 223e 0d0a 2020 2020 3c73 6563  m.v3">..    <sec
00009f20: 7572 6974                                urit

Brakowało kompletnego końca pliku - fragmentu manifestu.

Z tego powodu postanowiłem jeszcze sprawdzić czy nie brakuje jeszcze innych elementów lub czy istnieją takie, które są uszkodzone. Wykonałem zatem inspekcję pliku w narzędziu PE-bear:

Rsrc raw size

Co się jeszcze nie zgadzało? Rozmiar pliku garbage.exe wynosił 0x9F20 bajtów. Offset, w którym zaczyna się ostatnia sekcja (.rsrc), to 0x9E00. Deklarowany rozmiar tej sekcji to 0x400 bajtów. Zatem plik garbage.exe powinien mieć 0x9E00 + 0x400 = 0xA200 bajtów.

4. Naprawa pliku garbage.exe

Przystąpiłem do naprawy pliku. Zacząłem od zwiększenia rozmiaru pliku do 0xa200 bajtów poprzez dodanie zerowych bajtów na koniec pliku:

Null bytes

Następnie korzystając z narzędzia 010 Editor naprawiłem manifest do prawdopodobnej postaci:

<?xml version='1.0' encoding='UTF-8' standalone='yes'?>
<assembly xmlns='urn:schemas-microsoft-com:asm.v1' manifestVersion='1.0'>
  <trustInfo xmlns="urn:schemas-microsoft-com:asm.v3">
    <security>
      <requestedPrivileges xmlns="urn:schemas-microsoft-com:asm.v3">  
        <requestedExecutionLevel level="asInvoker"/>  
      </requestedPrivileges>  
    </security>  
  </trustInfo>  
</assembly>

Rozpakowałem następnie plik:

74wny0wl@whitehatlab-win C:\Users\74wny0wl\Desktop\2_-_garbage
# C:\tools\_Static\UniversalExtractor\bin\upx.exe -d "garbage - extended - manifest.exe" -o unpacked.exe
                       Ultimate Packer for eXecutables
                          Copyright (C) 1996 - 2010
UPX 3.05w       Markus Oberhumer, Laszlo Molnar & John Reiser   Apr 27th 2010

        File size         Ratio      Format      Name
   --------------------   ------   -----------   -----------
     79360 <-     41472   52.26%    win32/pe     unpacked.exe

Unpacked 1 file.

Próba uruchomienia rozpakowanego programu zakończyła się błędem:

74wny0wl@whitehatlab-win C:\Users\74wny0wl\Desktop\2_-_garbage
# .\unpacked.exe
The application has failed to start because its side-by-side configuration is incorrect. Please see the application event log or use the command-line sxstrace.exe tool for more detail.

5. Inspekcja pliku unpacked.exe

Otworzyłem plik w narzędziu PE-bear. Zauważyłem, że co najmniej uszkodzona jest tablica importów:

Broken IAT

Licząc na znalezienie pomocnych informacji, podejrzałem plik korzystając z narzędzia PEView:

Dostrzegłem cztery istotne fakty:

  1. W sekcji .rdata istniała IAT, znajdowały się w niej wpisy o importowanych funkcjach:

Imports

  1. Istniały adresy, pod którymi powinny znajdować się nazwy bibliotek:

Imports directory

  1. Pod adresami nazw bibliotek, nie znajdowały się żadne dane:

No dlls

  1. Ponownie brakowało części manifestu:

Broken manifest

6. Naprawa pliku unpacked.exe

Przystąpiłem do naprawy tablicy importów.

Pierwsze nazwy importowanych funkcji znajdujące się w IAT, pozwoliły na identyfikację wykorzystywanych bibliotek:

Wykonując skrypt w pythonie, obliczyłem offsety w pliku unpacked.exe, pod którymi powinny znajdować się nazwy bibliotek:

def cast_rva_to_file_offset(rva, section_rva, section_file_offset):
    return hex(rva - section_rva + section_file_offset)

rdata_rva = 0xD000
rdata_file_offset = 0xC200
kernel32_rva = 0x12434
shell32_rva = 0x12452

kernel32_file_offset = cast_rva_to_file_offset(kernel32_rva, rdata_rva, rdata_file_offset)
print(kernel32_file_offset)
shell32_file_offset = cast_rva_to_file_offset(shell32_rva, rdata_rva, rdata_file_offset)
print(shell32_file_offset)

Odczytałem wynik ze standardowego wyjścia:

0x11634
0x11652

Obie wartości były mniejsze od adresu kolejnej sekcji .data (0x11C00), więc mieściły się w dopuszczalnym zakresie.

Korzystając z 010 Editor naprawiłem wpisy dotyczące wykorzystywanych bibliotek:

Dll names inserted

Zweryfikowałem poprawność wykonanej naprawy w narzędziu PE-bear:

Repaired IAT

Następnie, korzystając z narzędzia Resource Hacker, ponownie wstawiłem poprawny manifest:

Resource Hacker Manifest

7. Odczytanie flagi

Pozostało uruchomić naprawiony program i odczytać flagę:

Flag