kirin framework - virtual machine not virtual machine

Posted by barello at 2020-02-26

Internet of things devices are facing unprecedented threats. The object of malware attack is usually the network device with poor security or improper configuration. Hardware manufacturers and security industry are trying to study all kinds of attacks to make more secure products. "Attacks against Internet of things devices" and "malware analysis" are the two biggest challenges in this process.

At present, "Internet of things devices" and "malware" are running in different operating systems and CPU architectures at the same time. Reverse engineers need to understand all CPU architectures, which greatly reduces the analysis efficiency. At the same time, many analysis tools that can't be updated in time are in short supply in the face of endless new attacks.

At present, many binary analysis tools (system simulation, user mode simulation, binary instrumentation tools and sandbox) are only for a single type of operating system or CPU architecture, and it is almost impossible for these tools to share information or cross reference data. This is the difficulty of reverse engineering.

[1] According to SonicWALL's research, in 2018, malware attacks increased significantly, reaching a record high of 10.52 billion, and cyber criminals used new threat strategies.

Kirin framework aims to change the current situation of Internet of things security research, malware analysis and reverse engineering. Our goal is to build a cross platform, multi architecture analysis framework, not just a reverse tool. Kirin framework has powerful functions, such as code interception and arbitrary code injection before or during binary execution. It can also patch target binaries during execution.

Kirin framework is an open source tool written in Python. Python is a simple programming language commonly used by reverse engineers, which greatly reduces the threshold of secondary development.

Kirin framework is not only a simulation platform or reverse engineering tool. It also combines binary instrumentation with binary simulation. With the Kirin framework, you can:

Kirin framework can simulate:

Kirin framework can run on Linux / MacOS / FreeBSD / windows (WSL) and other operating systems, and is not limited by CPU architecture

Demonstration environment
Demonstrate how to obtain the breaker switch address of wannacry

Kirin framework runs wannacry malware to obtain the switch address of the circuit breaker

Code sample
from qiling import * def stopatkillerswtich(ql): ql.uc.emu_stop() if __name__ == "__main__": ql = Qiling(["rootfs/x86_windows/bin/wannacry.bin"], "rootfs/x86_windows") ql.hook_address(stopatkillerswtich, 0x40819a)
Execution output
0x1333804: __set_app_type(0x2) 0x13337ce: __p__fmode() = 0x500007ec 0x13337c3: __p__commode() = 0x500007f0 0x132f1e1: _controlfp(0x10000, 0x30000) = 0x8001f 0x132d151: _initterm(0x40b00c, 0x40b010) 0x1333bc0: __getmainargs(0xffffdf9c, 0xffffdf8c, 0xffffdf98, 0x0, 0xffffdf90) = 0 0x132d151: _initterm(0x40b000, 0x40b008) 0x1001e10: GetStartupInfo(0xffffdfa0) 0x104d9f3: GetModuleHandleA(0x00) = 400000 0x125b18e: InternetOpenA(0x0, 0x1, 0x0, 0x0, 0x0) 0x126f0f1: InternetOpenUrlA(0x0, "", "", 0x0, 0x84000000, 0x0) from qiling import * def my_sandbox(path, rootfs): ql = Qiling(path, rootfs, stdin = sys.stdin, stdout = sys.stdout, stderr = sys.stderr) # Patch 0x00005930 from br0 to ens33 ql.patch(0x00005930, b'ens33\x00', file_name = b'') ql.root = False if __name__ == "__main__": my_sandbox(["rootfs/tendaac15/bin/httpd"], "rootfs/tendaac15")
Show me hot fix Windows crackme

The Kirin framework hotfix windows crackme program makes it display the "migration" window.

Code sample
from qiling import * def force_call_dialog_func(ql): # get DialogFunc address lpDialogFunc = ql.unpack32(ql.mem_read(ql.sp - 0x8, 4)) # setup stack memory for DialogFunc ql.stack_push(0) ql.stack_push(1001) ql.stack_push(273) ql.stack_push(0) ql.stack_push(0x0401018) # force EIP to DialogFunc ql.pc = lpDialogFunc def my_sandbox(path, rootfs): ql = Qiling(path, rootfs) # NOP out some code ql.patch(0x004010B5, b'\x90\x90') ql.patch(0x004010CD, b'\x90\x90') ql.patch(0x0040110B, b'\x90\x90') ql.patch(0x00401112, b'\x90\x90') # hook at an address with a callback ql.hook_address(0x00401016, force_call_dialog_func) if __name__ == "__main__": my_sandbox(["rootfs/x86_windows/bin/Easy_CrackMe.exe"], "rootfs/x86_windows")
Execution output
0x10cae10: GetStartupInfo(0xffffdf40) 0x1121fa7: GetStdHandle(0xfffffff6) = 0xfffffff6 0x111fbc4: GetFileType(0xfffffff6) = 0x2 0x1121fa7: GetStdHandle(0xfffffff5) = 0xfffffff5 0x111fbc4: GetFileType(0xfffffff5) = 0x2 0x1121fa7: GetStdHandle(0xfffffff4) = 0xfffffff4 0x111fbc4: GetFileType(0xfffffff4) = 0x2 0x1121fd1: SetHandleCount(0x20) = 32 0x1121fbf: GetCommandLineA() = 0x501091b8 0x111fcd4: GetEnvironmentStringsW() = 0x501091e4 0x1117ffa: WideCharToMultiByte(0x0, 0x0, 0x501091e4, 0x1, 0x0, 0x0, 0x0, 0x0) = 2 0x1117ffa: WideCharToMultiByte(0x0, 0x0, 0x501091e4, 0x1, 0x50002098, 0x2, 0x0, 0x0) = 1 0x111fcbc: FreeEnvironmentStringsW(0x501091e4) = 1 0x1116a0b: GetACP() = 437 0x1121f8f: GetCPInfo(0x1b5, 0xffffdf44) = 1 0x1121f8f: GetCPInfo(0x1b5, 0xffffdf1c) = 1 0x111e43e: GetStringTypeW(0x1, 0x40541c, 0x1, 0xffffd9d8) = 0 0x10ffc95: GetStringTypeExA(0x0, 0x1, 0x405418, 0x1, 0xffffd9d8) = 0 0x111e39c: LCMapStringW(0x0, 0x100, 0x40541c, 0x1, 0x0, 0x0) = 0 0x1128a50: LCMapStringA(0x0, 0x100, 0x405418, 0x1, 0x0, 0x0) = 0 0x111e39c: LCMapStringW(0x0, 0x100, 0x40541c, 0x1, 0x0, 0x0) = 0 0x1128a50: LCMapStringA(0x0, 0x100, 0x405418, 0x1, 0x0, 0x0) = 0 0x111685a: GetModuleFileNameA(0x0, 0x40856c, 0x104) = 42 0x10cae10: GetStartupInfo(0xffffdfa0) 0x11169f3: GetModuleHandleA(0x00) = 400000 0x104cf42: DialogBoxParamA(0x400000, 0x65, 0x00, 0x401020, 0x00) = 0 Input DlgItemText : << enter any string or number here >> 0x1063d14: GetDlgItemTextA(0x00, 0x3e8, 0xffffdef4, 0x64) = 3 0x105ea11: MessageBoxA(0x00, "Congratulation !!", "EasyCrackMe", 0x40) = 2 0x1033ba3: EndDialog(0x00, 0x00) = 1 0x1124d12: ExitProcess(0x01)