feldo: function event listing and dynamic observing for detecting and preventing crypto ransomware
TRANSCRIPT
HITCON CMT 2016
FèlDo Function Event Listing and Dynamic Observing
Tzung-Bi Shih <[email protected]>
- for Detecting and Preventing Crypto Ransomware
HITCON CMT 2016
“Most of us are misunderstanding when mentioning ransomware.”
2
HITCON CMT 2016
Introduction Ransomware[1][2]
• DoS victims from accessing their system
• "claim" something has been kidnapped and tell victims need to pay for retaining the kidnapee
• anonymity of the transaction is the most difficult
• cryptocurrency, voucher, Tor
• no one can guarantee the kidnapee will be back after paid
3
HITCON CMT 2016
Introduction Example: DoS from Accessing Vehicles
4
ransom hardware
HITCON CMT 2016
Background Types of Ransomware
• misleading application[3][4]
• free vs. non-free
• e.g. performance optimizer, fake AV
• police ransomware
• fake local law enforcement
• crypto ransomware
5
HITCON CMT 2016
Background History of Ransomware on OS X[5]
• July 2013, FBI ransomware[6][7]
• June 2014, FileCoder[8]
• Sep 2015, Gopher[9]
• Nov 2015, Mabouia[10]
• Feb 2016, GinX[11]
• Mar 2016, KeRanger[12] (see Appendix A)
6
HITCON CMT 2016
Related Works• Toward Generic (Crypto) Ransomware Detection[5]
• monitoring file I/O events
• determining if a file is encrypted
• determining if a process is untrusted
• RansomWhere?[13]
➡sniffer mode limitation: still sacrificed a few files
7
HITCON CMT 2016
FèlDo Overview
• an inline mode solution for detecting and preventing crypto ransomware
• detection: correlating function calls
• crypto ransomware is relatively simple (at least for now)
• it is possible to detect them via observing function calling sequence
• within a short time frame
• prevention: hooking APIs
• deferring unlink request
8
HITCON CMT 2016
FèlDo Correlating Function Calls (1/2)
9
observation on dtruss output
HITCON CMT 2016
FèlDo Correlating Function Calls (2/2)
10
open_nocancel("/Users/tester/.CFUserTextEncoding\0", 0x0, 0x1B6) = 6 0 open_nocancel("/Users/tester/.CFUserTextEncoding.encrypted\0", 0x601, 0x1B6) = 7 0 close_nocancel(0x6) = 0 0 close_nocancel(0x7) = 0 0 unlink("/Users/tester/.CFUserTextEncoding\0", 0x7FFF5FBFDE00, 0x154) = 0 0
If frequency of two-pair greater than thresholdA, the corresponding process is likely a crypto ransomware.
in-place vs. not-in-place encryption
HITCON CMT 2016
FèlDo Hooking APIs
• acknowledged whenever a process request to unlink
• put the request into a deferred queue
• the queue purges in two criteria: space and time limit
• if queue length is greater than thresholdB
• if a request has deferred for thresholdC seconds
• satisfies remaining requests while the process terminating
11
even non-existent
HITCON CMT 2016
Implementation OS X
• userland solution
• supports from dynamic linker "dyld"
• DYLD_INSERT_LIBRARIES
• DYLD_FORCE_FLAT_NAMESPACE
• kernel extension solution
• replace entries of system call table
12
application
library
system call
kernel
userland solution
kext solution
HITCON CMT 2016
Simple Evaluation
13
unit (second)
original userland solution kext solutionround 1 round 2 round 3 average round 1 round 2 round 3 average round 1 round 2 round 3 average
test1.sh 49.66 50.97 50.17 50.27 136.80 140.66 137.13 138.20 51.08 50.27 51.03 50.79test2.sh 34.67 33.83 32.78 33.76 107.30 105.41 107.00 106.57 34.08 34.88 33.15 34.04test3.sh 32.73 31.37 32.11 32.07 142.27 142.25 144.37 142.96 32.52 32.35 31.92 32.26
$ cat test1.shfor i in $(seq 1 10000)do
touch $irm $i
done
$ cat test2.shfor i in $(seq 1 4)do
(for k in $(seq 1 3000)do
touch ${i}_${k}rm ${i}_${k}
done) &
donewait
$ cat test3.shcd yarash build.sh >/dev/null 2>&1
userland solution: too many performance penalties (2x~4x slower) kext solution: almost transparent
HITCON CMT 2016
Summary• ransomware is variable
• crypto ransomware is just one kind of them
• IMHO, a product for crypto ransomware should be
• kernel mode and leverage existing mechanisms, e.g. KAuth
• multiple detection criteria
• white listing
14
HITCON CMT 2016
Reference
15
[1]: http://www.trendmicro.com/vinfo/us/security/definition/ransomware [2]: http://www.symantec.com/content/en/us/enterprise/media/security_response/whitepapers/the-evolution-of-ransomware.pdf [3]: http://securityresponse.symantec.com/norton/theme.jsp?themeid=mislead [4]: https://www.symantec.com/security_response/writeup.jsp?docid=2007-101013-0757-99 [5]: https://objective-see.com/blog/blog_0x0F.html [6]: https://blog.malwarebytes.org/threat-analysis/2013/07/fbi-ransomware-now-targeting-apples-mac-os-x-users/ [7]: http://www.makeuseof.com/tag/mac-user-ransomware-easily-remove-malware-threat/ [8]: https://securelist.com/blog/research/66760/unfinished-ransomware-for-macos-x/ [9]: https://github.com/gdbinit/gopher [10]: http://securityaffairs.co/wordpress/41755/cyber-crime/mabouia-ransomware-mac-os-x.html [11]: http://www.infosecisland.com/blogview/24699-OSX-Ransomware-Offered-for-Sale-in-the-Underground.html [12]: http://researchcenter.paloaltonetworks.com/2016/03/new-os-x-ransomware-keranger-infected-transmission-bittorrent-client-installer/ [13]: https://objective-see.com/products/ransomwhere.html
HITCON CMT 2016
Appendix A Case Study: OSX.KeRanger
- Introduction - Analysis - Fake C2 Server - Experiment - Rescue
HITCON CMT 2016
OSX.KeRanger (1/14) Introduction
17
HITCON CMT 2016
OSX.KeRanger (2/14) Attach the DMG
18
$ hdiutil attach OSX.KeRangerChecksumming Protective Master Boot Record (MBR : 0)…Protective Master Boot Record (MBR :: verified CRC32 $C0C6CB47Checksumming GPT Header (Primary GPT Header : 1)… GPT Header (Primary GPT Header : 1): verified CRC32 $933E6577Checksumming GPT Partition Data (Primary GPT Table : 2)…GPT Partition Data (Primary GPT Tabl: verified CRC32 $0AE534AAChecksumming (Apple_Free : 3)… (Apple_Free : 3): verified CRC32 $00000000Checksumming disk image (Apple_HFS : 4)…............................................................................... disk image (Apple_HFS : 4): verified CRC32 $4D10DABFChecksumming (Apple_Free : 5)… (Apple_Free : 5): verified CRC32 $00000000Checksumming GPT Partition Data (Backup GPT Table : 6)…GPT Partition Data (Backup GPT Table: verified CRC32 $0AE534AAChecksumming GPT Header (Backup GPT Header : 7)… GPT Header (Backup GPT Header : 7): verified CRC32 $D2F721FAverified CRC32 $BC3C912F/dev/disk1 GUID_partition_scheme/dev/disk1s1 Apple_HFS /Volumes/Transmission
$ file /Volumes/Transmission/Transmission.app/Contents/MacOS/Transmission/Volumes/Transmission/Transmission.app/Contents/MacOS/Transmission: Mach-O 64-bit executable x86_64
sha256(OSX.KeRanger) = d1ac55a4e610380f0ab239fcc1c5f5a42722e8ee1554cba8074bbae4a5f6dbe1
HITCON CMT 2016
OSX.KeRanger (3/14) Drop File
19
fork, exec, wait
copy General.rtf to kernel_service
There will be a process named "kernel_service".
HITCON CMT 2016
OSX.KeRanger (4/14) UPX Packed
20
sha256(General.rtf) = 31b6adb633cff2a0f34cefd2a218097f3a9a8176c9363cc70fe41fe02af810b9
$ hexdump -C General.rtf | grep -i upx000002c0 1c 03 f2 dc 55 50 58 21 a7 06 0d 22 00 00 00 00 |....UPX!..."....|00020ff0 ff 00 00 00 00 55 50 58 21 00 00 00 00 00 00 00 |.....UPX!.......|00021150 6b 65 72 20 68 74 74 70 3a 2f 2f 75 70 78 2e 73 |ker http://upx.s|00021190 68 65 20 55 50 58 20 54 65 61 6d 2e 20 41 6c 6c |he UPX Team. All|00021330 14 14 85 d2 ef ba db ff 75 15 81 fe 55 50 58 21 |........u...UPX!|000216a0 69 c3 00 00 00 00 00 00 00 90 ff 55 50 58 21 0d |i..........UPX!.|
HITCON CMT 2016
OSX.KeRanger (5/14) Unlink Itself
21
sha256(General.rtf.unpacked) = 84a60c8bb2cdf454fdb593318e7c26ba93cc48ba3058530998c8886050981f11
to hide itself
HITCON CMT 2016
OSX.KeRanger (6/14) Daemonlize and Wait
22
fork, setsid, chdir
sleep 300 seconds until 3 days has elapsed
its parent "Transmission" can keep going
done flag
HITCON CMT 2016
OSX.KeRanger (7/14) Generate UUID and Query String
23
$ sysctl hw.modelhw.model: MacBookPro11,1
$ sysctl -a | grep 'hw\.model'$ sysctl hw.modelhw.model: VMware7,1
HITCON CMT 2016
OSX.KeRanger (8/14) C2 Communication (1/2)
24
• gethostbyname • connect • send • recv
HITCON CMT 2016
OSX.KeRanger (9/14) C2 Communication (2/2)
25
• server will respond 2 lines (base64-encoded) • 1st line
• RSA public key • 2nd line
• ransom statement
HITCON CMT 2016
OSX.KeRanger (10/14) File Encryption (1/4)
26
encrypt files excepts: • *.encrypted • README_FOR_DECRYPT.txt • .kernel_complete • .kernel_time • .kernel_pid
HITCON CMT 2016
OSX.KeRanger (11/14) File Encryption (2/4)
27
encrypt files if in the list of filename extensions
HITCON CMT 2016
OSX.KeRanger (12/14) File Encryption (3/4)
28
target filename extensions:
.3dm .3ds .3g2 .3gp .7z .ab4 .accdb .accde .accdr .accdt .ach .acr .act .adb
.ads .ai .ait .al .apj .arw .asf .asm .asp .asx .avi .back .backup .bak
.bank .bay .bdb .bgt .bik .bkf .bkp .blend .bpw .c .cdb .cdf .cdr .cdx
.ce1 .ce2 .cer .cfp .cgm .class .cls .cmt .cnv .cpi .cpp .cr2 .craw .crt
.crw .cs .csh .csl .csv .dac .db .db3 .dbf .dbr .dbs .dc2 .dcr .dcs
.dcx .ddd .ddoc .dds .der .des .design .dgc .djvu .dng .doc .docm .docx .dot
.dotm .dotx .drf .drw .dtd .dwg .dxb .dxf .dxg .ebd .edb .eml .eps .erf
.exf .fdb .ffd .fff .fh .fhd .fla .flac .flv .fm .fp7 .fpx .fxg .gdb
.gray .grey .grw .gry .h .hbk .hpp .ibd .idx .iif .indd .java .jpe .jpeg
.jpg .kdbx .kdc .key .laccdb .lua .m .m4v .maf .mam .maq .mar .maw .max
.mdb .mdc .mde .mdf .mdt .mef .mfw .mmw .mos .mov .mp3 .mp4 .mpg .mpp
.mrw .mso .myd .ndd .nef .nk2 .nrw .ns2 .ns3 .ns4 .nsd .nsf .nsg .nsh
.nwb .nx1 .nx2 .nyf .obj .odb .odc .odf .odg .odm .odp .ods .odt .oil
.one .orf .otg .oth .otp .ots .ott .p12 .p7b .p7c .pages .pas .pat .pbo
.pcd .pct .pdb .pdd .pdf .pef .pem .pfx .php .pip .pl .plc .pot .potm
.potx .ppam .pps .ppsm .ppsx .ppt .pptm .pptx .prf .ps .psafe3 .psd .pspimage .ptx
.pub .puz .py .qba .qbb .qbm .qbw .qbx .r3d .raf .rar .rat .raw .rdb
.rm .rtf .rwz .sas7bdat .say .sd0 .sda .sdf .snp .sql .sr2 .srf .srt .srw
.st4 .st5 .st6 .st7 .st8 .stc .std .sti .stw .stx .svg .swf .sxc .sxd
.sxg .sxi .sxm .sxw .tex .tga .thm .tlg .txt .vob .vsd .vsx .vtx .wav
.wb2 .wbk .wdb .wll .wmv .wpd .wps .x11 .x3f .xla .xlam .xlb .xlc .xlk
.xll .xlm .xlr .xls .xlsb .xlsm .xlsx .xlt .xltm .xltx .xlw .xpp .xsn .yuv
.zip .tar .tgz .gzip .tib .sparsebundle
HITCON CMT 2016
OSX.KeRanger (13/14) File Encryption (4/4)
29
drop ransom statement
HITCON CMT 2016
OSX.KeRanger (14/14) Finalize
30
Be honest! Don't touch this; or it will encrypt your files again in some day ...
HITCON CMT 2016
Fake C2 Server (1/3) Modify /etc/hosts
31
# cat /etc/hosts127.0.0.1 lclebb6kvohlkcml.onion.link127.0.0.1 lclebb6kvohlkcml.onion.nu127.0.0.1 bmacyzmea723xyaz.onion.link127.0.0.1 bmacyzmea723xyaz.onion.nu127.0.0.1 nejdtkok7oz5kjoc.onion.link127.0.0.1 nejdtkok7oz5kjoc.onion.nu
HITCON CMT 2016
Fake C2 Server (2/3) Generate Private and Public Key
32
# openssl genrsa -out private.pem 2048Generating RSA private key, 2048 bit long modulus....................................................+++...............................................+++e is 65537 (0x10001)
# openssl rsa -in private.pem -pubout -outform PEM -out public.pemwriting RSA key
# printf "\x00" >> public.pem
# base64 public.pemLS0tLS1CRUdJTiBQVUJMSUMgS0VZLS0tLS0KTUlJQklqQU5CZ2txaGtpRzl3MEJBUUVGQUFPQ0FROEFNSUlCQ2dLQ0FRRUE3eGdTWW9MVWljNWxadnBiaXZ3NApXZzJFNUJpdk4vcW9vUmVTUEl4Z3lvYzZNMGdXR01pUUZmdVlMQjVxS2hXR2hmQjViWVh5K2hrakhYWC84Z2l1CmJCa0szYU9RdmdlUmtKemR4NVFvbG5XNWxqRzVFUU9hZ0pCRk1RSHFIaHFqbXJDY0dFTis3c0N4YngrMGdYUGMKVURJUEE1VXhLdjlneGFhMHQweHVoeWovUVhNMjF3V25mUkVxclU5MmdMSHIwdEpqR0E5Y2FPZ1cxbXVZM2U4UwpjQno5K3NJaWxvRVBNSVNqa3N3dGR5OE96Q2FQYS9LU1J2T1lleXhsVGlCNDJrbEV2WmpyVkJ2ODZza09uQ0xNCkdSaWpCRkNyVnkwVVNKTDh4WHRRMEJJNjZWTzB1b21oOXV4cC9Na1pLWk4yNmhraDNUSEVXL2xUdnBnYXlPSW8KbFFJREFRQUIKLS0tLS1FTkQgUFVCTElDIEtFWS0tLS0tCgA=
un-usual practice
HITCON CMT 2016
Fake C2 Server (3/3) Dummy Web Application
33
# cat dummy.pyfrom flask import Flaskfrom flask import request
web_app = Flask('dummy')@web_app.route('/osx/ping', methods=['GET'])def dummy():
r = list()
r.append('LS0tLS1CRUdJTiBQVUJMSUMgS0VZLS0tLS0KTUlJQklqQU5CZ2txaGtpRzl3MEJBUUVGQUFPQ0FROEFNSUlCQ2dLQ0FRRUE3eGdTWW9MVWljNWxadnBiaXZ3NApXZzJFNUJpdk4vcW9vUmVTUEl4Z3lvYzZNMGdXR01pUUZmdVlMQjVxS2hXR2hmQjViWVh5K2hrakhYWC84Z2l1CmJCa0szYU9RdmdlUmtKemR4NVFvbG5XNWxqRzVFUU9hZ0pCRk1RSHFIaHFqbXJDY0dFTis3c0N4YngrMGdYUGMKVURJUEE1VXhLdjlneGFhMHQweHVoeWovUVhNMjF3V25mUkVxclU5MmdMSHIwdEpqR0E5Y2FPZ1cxbXVZM2U4UwpjQno5K3NJaWxvRVBNSVNqa3N3dGR5OE96Q2FQYS9LU1J2T1lleXhsVGlCNDJrbEV2WmpyVkJ2ODZza09uQ0xNCkdSaWpCRkNyVnkwVVNKTDh4WHRRMEJJNjZWTzB1b21oOXV4cC9Na1pLWk4yNmhraDNUSEVXL2xUdnBnYXlPSW8KbFFJREFRQUIKLS0tLS1FTkQgUFVCTElDIEtFWS0tLS0tCgA=')
r.append('c29tZSByYW5zb20gc3RhdGVtZW50Li4uCg==')return '\n'.join(r)
web_app.run(host='0.0.0.0', port=80)
indented; don't be confused
HITCON CMT 2016
Experiment (1/2) Cheat the Malware
34
$ cp General.rtf AAAA
$ ./AAAA
$ killall AAAA
$ ls -a Library/.kernel*Library/.kernel_pidLibrary/.kernel_time
$ echo 0 > Library/.kernel_time
will be unlinked
will be detached
cheat the malware 3+ days has elapsed
HITCON CMT 2016
Experiment (2/2) Hook Sleep Function
35
$ cat hook_sleep.cunsigned int sleep(unsigned int seconds){
return 0;}
$ gcc hook_sleep.c -shared -fPIC -o hs.dylib
$ DYLD_FORCE_FLAT_NAMESPACE=1 DYLD_INSERT_LIBRARIES=hs.dylib ./General.rtf
# python dummy.py * Running on http://0.0.0.0:80/ (Press CTRL+C to quit)127.0.0.1 - - [16/Mar/2016 04:06:48] "GET /osx/ping?user_id=general&uuid=4a8832aa8056fceebee520f8eae577ee52b51e5826ee79b75a8f314d3980129&model=VMware7,1 HTTP/1.0 200 -
HITCON CMT 2016
Rescue (1/5) Encrypted File Format
36
XXX.encrypted
len
{seed}pub
IV
cipher text
HMAC
4 bytes
256 bytes
16 bytes
32 bytes
(determined by len)
HITCON CMT 2016
Rescue (2/5) Get Secret Key
37
IV16 bytes
key
md
seed
32 bytes 32 bytes
run over 8 times
message digest
HITCON CMT 2016
Rescue (3/5) Decryption
38
IV
AES
cipher text
key
plain text
16 bytes 32 bytes
32 bytes
32 bytes
IV will be replaced after the first round
HITCON CMT 2016
Rescue (4/5) Trim File Until Matches HMAC
39
plain text
may exist some (garbage) paddings; at most 31 bytes
AES
cipher text
HITCON CMT 2016
Rescue (5/5) Decryption Tool
40
$ cat decrypt_file.c[snip] if (!get_seed(argv[1], encrypted_seed, encrypted_seed_len, seed, &seed_len)) { ERR("failed to get_seed"); goto leave; } dump_binary("seed", seed, seed_len);
if (!get_key(iv, seed, key)) { ERR("failed to get_key"); goto leave; } dump_binary("key", key, 32);
if (!decrypt_file(encrypted_seed_len, iv, key, fin, fout)) { ERR("failed to decrypt_file"); goto leave; } DBG("decrypt_file success");
if (!trim_file(key, hmac, fout)) { ERR("failed to trim_file"); goto leave; } DBG("trim_file success");[snip]