Jump to content

Nytro

Administrators
  • Posts

    18753
  • Joined

  • Last visited

  • Days Won

    726

Everything posted by Nytro

  1. Reversing ARM Binaries by @bellis1000 In this beginner-friendly tutorial we will take a look at the process of reverse engineering a simple ARM binary and patching it. The specific binary we will look at is named 'patchme1' and is a small program designed specifically for the purpose of this tutorial. Executing the program with zero arguments gives us a short 'usage' message that lets us know that we will need some kind of key in order to use this app. Executing it again, this time with a random key as the first argument, gives us a red error message telling us that we have entered an incorrect key. So where do we go from here? Natural instinct for anyone with any kind of reversing knowlegde would be to scan the binary for strings to see if the key happens to be stored in plain ASCII text. We can do so by opening the patchme1 binary in Hopper disassembler for OS X (or another disassembler tool such as IDA or radare2) and navigating to the 'strings' section. Unfortunately for us, the key is not stored in plain ASCII. The only strings we can see are the 'usage' message, the 'invalid key' message, the path to /bin/sh and a 'You're in!' message. So what now? It is clear that this challenge will not be as simple as finding a string and using it to get through the check. We will need to look deeper into how this program works, and we'll start by disassembling main(). We will start with the first chunk of instructions, up until the point of the first conditional branch. The first few instructions aren't too interesting. These instructions just make up the generic function prologue that contains the standard things you'd see in most ARM assembly functions, such as setting up the stack for later returning. Below that, we have a series of memory access instructions (LDRs and STRs) and then a CMP instruction, comparing the value of R0 to 0x2. This is simply checking the number of arguments the user supplied when executing the program. The BGE (Branch if Greater than or Equal to) instruction following this comparison then determines whether we are given the 'usage' message or whether we proceed to the next part of the program. We don't care too much about the 'usage' thing, so we'll continue on to the next stage of the program. There are some interesting things happening here. Firstly, R0 is being loaded with user-supplied key and then a function 'hash' is BL(Branch with Link)'d to. The BL instruction is the equivalent of a CALL type instruction. It jumps or 'branches' to a new location in memory (in this case the entry point of the hash function) and then it returns to its caller. Following the call to the hash function, there is a comparison between R0 and a very specific value, 0x203623b1. If the two are not equal, we branch to 0xbef0 which displays the 'invalid key' message and then exits. However, if they are equal then we continue to the restricted area of the program which, by looking at the disassembly, gives us a welcome message and then spawns a shell. So how do we get that very specific value into R0? On ARM, function return values are passed in R0. This makes it pretty clear and obvious that the hash function is what is generating this number (if you didn't already guess). Looking at the disassembly for the hash function would likely overwhelm beginners (who of which this post is targetted at) so instead we will cheat and have a sneak peak at the source code instead ;). From the above code snippet we can understand that this 'hash' function takes in an array of chars (data[]) and returns an unsigned integer. The actual body of this function contains a loop that iterates through the characters in the char array an XOR(Exclusive OR)s each of them with the random number 83, adding the result to an integer variable named 'hash' and then multiplying the value of this by another random value, 839286441. So in summary, this function implements a very basic hashing algorithm that generates a hash of the data passed to it and returns this hash to the caller. If you know anything about hashing algorithms, you'll know that even simple ones like this are very tedious to reverse (find some specific data that returns a specific hash) so it would be easier for us to just patch this simple binary instead. There are a few ways we could patch this specific binary, but we'll go with the simplest way which would be to remove or 'NOP out' this instruction: But what is a NOP? NOP stands for No-Operation and it is essentially an instruction that when executed, has no effect on the program or the state of the registers. In other words, it does nothing. We can use this to our advantage by placing a NOP where the conditional branch instruction would be, thus causing execution to automatically follow on to the chunk of code that executes the shell. In the ARMv7 instruction set, there is no dedicated NOP instruction, but we can easily create our own. Something like 'MOV R0, R0' acts as a NOP instruction. It moves the value of R0 into R0, leaving the registers unchanged. So it does nothing. To actually replace the instruction with our NOP we could use Hopper's built-in 'NOP Region' feature, however we will not be able to export the binary on the free version. Instead, I will assume that we don't have access to the full/paid version of Hopper and patch the instruction manually. We first need the encoding of our target instruction. This can be found in the right side bar in Hopper. Now, using your favourite Hex editor application (I'm using iHex), open the patchme1 binary and search for this specific byte combination inside the binary file. Once you've found it you can replace these 4 bytes with the bytes representing your chosen NOP instruction. In my case I will use 'MOV R0, R0' which has the instruction encoding of 00 00 A0 E1. Save the file, and you're done! You've successfully patched the program by replacing a single instruction. To test that the patch works as expected, execute the new patchme1 binary and see what happens. As the above screenshot shows, we are given access to the shell no matter what data we enter for the key. Challenge complete! Hopefully you enjoyed this short tutorial! If you're new to ARM assembly then I highly recommend Azeria's set of tutorials. If you want to learn more on the topic of reverse engineering and exploit development on the ARM platform check out my book as well as my set of 'ARM Exploit Exercises' available on my Github. Thanks for reading! Feel free to tweet me @bellis1000 if you have any questions Copyright (c) 2018 ZygoSec Sursa: https://zygosec.com/post1.html
      • 1
      • Like
  2. Live kernel introspection on iOS by Brandon Azad September 15, 2017 Part of effective security research is having the right tools to analyze vulnerabilities. Apple allows users to develop kernel extensions and debug the kernel on macOS, but neither is supported on iOS. This post explains how I developed memctl, a kernel introspection tool for macOS and iOS that I’ve been using for the past year to analyze the kernel. Memctl uses the kernel task port to reliably read and write kernel memory and to reliably call arbitrary kernel functions with arbitrary arguments on both macOS and iOS. Other useful features are implemented on top of this basic functionality, mostly convenience routines to call kernel functions that would otherwise be difficult to find or call. Memctl’s functionality is provided both as a library (called libmemctl) and as a command-line tool. Coincidentally, Ian Beer described how he developed his own kernel memory debugger in Exception-oriented exploitation on iOS, which was published late into my work on memctl. To me this shows how useful such a tool could be. While I developed memctl primarily for my own use, I am open-sourcing it in case someone else finds my work useful. Table of Contents Kernel debugging on iOS An overview of memctl Basic kernel memory access Finding the kernel slide Generic kernel function calls on iOS and macOS Arbitrary kernel function calls on AArch64 Arbitrary kernel function calls on x86_64 Safe kernel memory access Implementing mach_portal with libmemctl Examples of using memctl Conclusion Kernel debugging on iOS Debuggers make analyzing security vulnerabilities much easier. Unfortunately, outside of Apple, there is no straightforward way to support true kernel debugging on iOS. Memctl is my attempt at the next best thing: creating a framework to provide some of the functionality of a kernel debugger. Unfortunately, memctl does not support breakpoints, which is why I call it a kernel introspection tool rather than a debugger. It might be possible to implement live kernel breakpoints (where the debugger is running on the kernel being debugged), but this seems difficult and error-prone at best, and would certainly need a Kernel Patch Protection bypass. What memctl does support is the memory access part of a debugger.1 Specifically, libmemctl includes functions to safely (or, as safely as possible) read and write kernel memory. All other features, including the ability to call kernel functions, are built on top of this capability. Of course, Apple does not provide a way for user-space programs to directly access kernel memory; we’ll need a way around these restrictions. One way is to use a kernel vulnerability directly. Another way, more common on jailbroken devices, is to access the kernel task through a Mach port. The advantage of using the kernel task port is that the API is consistent: you don’t need to rewrite your memory access functions if you switch to a different vulnerability. Libmemctl uses the kernel task approach. However, this means that in order to get memctl running on a platform, we need an exploit that obtains the kernel task port. Fortunately, many iOS jailbreaks, including mach_portal and yalu102, provide a way for programs to access the kernel task port, meaning memctl can run on top of these jailbreaks. I’ve only tested memctl on those two, but theoretically it should work fine on other jailbreaks as well. An overview of memctl Memctl is divided into two parts: a library called libmemctl that implements kernel introspection, modification, and function calling, and a command-line tool called memctl that allows users to access much of this functionality from the terminal. However, you also need a third part that is separate from memctl: a library called a “core” to get the kernel task port. The purpose of the core is simply to give memctl a consistent API through which it can obtain the kernel task port. On jailbroken devices, the core could be as simple as a call to task_for_pid(0) or host_get_special_port(4).2 However, non-jailbroken devices will need a core that actually exploits a vulnerability to install a send right to the kernel task into the current task. The memctl-physmem-core repository shows how to do this for the physmem vulnerability, although physmem is likely easier to exploit than most modern vulnerabilities. The primary purpose of libmemctl is to provide a safe API to access kernel memory and call kernel functions. In order to do so, libmemctl offers many features: A partial AArch64 disassembler and simulator On-device kernelcache decompression Symbol resolution for exported symbols Special symbol resolution to find certain unexported symbols on AArch64, including vtables Discovery of the kASLR slide Kernel virtual and physical memory read and write, including safe memory scanning Virtual-to-physical address translation Kernel memory allocation Kernel function calling (with up to 8 arguments on AArch64) Process and task modification Privilege escalation The memctl command-line utility packages libmemctl so that it can be used to debug the device on which it is running. Its CLI takes inspiration from radare2. Some of the most useful memctl commands are: r: Read kernel virtual or physical memory w: Write kernel virtual or physical memory f: Find a value in memory (all memory locations containing the given value are printed) fc: Find instances of a C++ class lc: Determine the C++ class from an object pointer kp: Translate a kernel virtual address to a physical address zs: Print the size of a block of memory allocated with zalloc vmm: Show the kernel virtual memory map (like vmmap) a: Print the address of a kernel symbol s: Look up the symbol containing the given kernel virtual address It’s also important to understand what memctl is not. Memctl is not an exploit and it leverages no vulnerabilities, zero-day or otherwise. Such vulnerabilities could be used in a core to allow memctl to run on a certain platform, but memctl itself does not exploit any vulnerabilities. Memctl is also not designed to be a replacement for other reversing tools such as IDA and radare. Memctl is useful for inspecting the kernel as it is running and for facilitating iOS research. Some limited static analysis is performed on-device in order to find kernel symbols, but this analysis is not nearly as sophisticated as that performed by dedicated reversing frameworks. Finally, memctl is not designed to work on all OS versions and platforms. Libmemctl relies on the ability to locate certain kernel symbols, which is not possible on the encrypted kernelcaches prior to iOS 10.3 Additionally, libmemctl currently offers no support for 32-bit versions of macOS and iOS, and no such support is planned. This makes memctl unsuitable for analyzing 32-bit devices like the iPhone 5 or the Apple Watch. I have tested memctl on macOS 10.12.1, macOS 10.12.6, iOS 10.1.1, and iOS 10.2. Because libmemctl relies on many XNU internals, it likely needs significant tweaking to work on other versions and platforms. Moreover, since memctl is primarily a tool for my own research, it is geared for my own use cases and may not be stable. The rest of this post talks about the implementation details of libmemctl and concludes with some examples showing how to use memctl. Basic kernel memory access The most primitive operations supported by libmemctl are unsafe kernel memory reads and writes, provided by the functions kernel_read_unsafe and kernel_write_unsafe, respectively. These functions use the mach_vm_read_overwrite and mach_vm_write Mach traps to read and write memory in the kernel task. Two other useful functions are kernel_read_heap and kernel_write_heap, which are analogous functions that attempt to access kernel memory but fail safely if it is possible that the accessed memory address does not refer to the kernel heap. Unlike the unsafe functions, these functions are (or should be) safe: trying to read a nonexistent kernel address will simply return an error rather than crashing the kernel. The kernel heap can be identified using the mach_vm_region_recurse Mach trap to get the region’s user_tag attribute. Memory addresses allocated with zalloc (used by kalloc for small allocations) will have the user_tag set to VM_KERN_MEMORY_ZONE (12).4 While it might not seem like much, the ability to read kernel memory safely is crucial for implementing the rest of the functionality, because it allows us to scan memory without risk of crashing the system. Finding the kernel slide Using the kernel task and the basic memory read functions, we can find the kASLR slide in a number of different ways, depending on the platform. On macOS, the most straightforward way is to use the symbol _last_kernel_symbol. The macOS kernel is shipped unstripped, meaning we can get the static addresses of all sorts of useful symbols just by parsing the symbol table. In this case, _last_kernel_symbol designates the very last page in the kernel image. For example, on macOS 10.12.4, the kernel might lie somewhere in the following memory region:5 START - END [ VSIZE ] PRT/MAX SHRMOD DEPTH RESIDENT REFCNT TAG ffffff8000000000-ffffff8030152000 [ 769M ] ---/--- NUL 0 0 0 0 By parsing the kernel it is possible to determine that _last_kernel_symbol lives at static (unslid) address 0xffffff8000b51008, which means that the first page after the kernel is 0xffffff8000b52000 (the page size on this platform is 4K). Subtracting this static address from the runtime address 0xffffff8030152000 gives the kernel slide of 0x000000002f600000. This trick does not work on iOS because on iOS the kernel lives at an unknown location (read: not at the end) in a much larger memory region. The simplest approach is to scan every page in the region until we find the one containing the kernel’s Mach-O header. Unfortunately, this does not work in practice because not all pages in this region are mapped, meaning the scan will trigger a panic if it accesses an unmapped page. A safer approach relies on a few implementation details in XNU. There’s at least one memory region in the kernel memory map with depth 0 and user_tag VM_KERN_MEMORY_ZONE. The first word of this region is a pointer to somewhere in the middle of the kernel’s _zone_array symbol. Thus, a pointer into the kernel can be found by locating a memory region with depth 0 and user_tag VM_KERN_MEMORY_ZONE and dereferencing the first pointer in that region. From there, finding the start of the kernel is as simple as scanning memory backwards, since all addresses between the _zone_array symbol and the start of the kernel’s Mach-O header will be mapped. For example, on an iPhone 5s running iOS 10.2, the kernel memory map includes the following regions: START - END [ VSIZE ] PRT/MAX SHRMOD DEPTH RESIDENT REFCNT TAG ffffffe000000000-fffffff000000000 [ 64G ] ---/--- NUL 0 0 0 0 ... fffffff01a825000-fffffff01a827000 [ 8K ] rw-/rwx S/A 0 2 829 12 ... fffffff01b1e2000-fffffff01b1f6000 [ 80K ] rw-/rwx S/A 0 20 829 12 ... fffffff01c800000-fffffff11e000000 [ 4.0G ] ---/--- NUL 0 0 0 0 ... fffffff27fef8000-fffffff27ffff000 [ 1.0M ] ---/--- NUL 0 0 0 0 Reading 8 bytes at 0xfffffff01a825000 yields the pointer 0xfffffff01dd6a720. Checking the memory map confirms that this address lies within a large, 4GB carve-out of virtual memory with no access permissions, a strong indication that the address actually does point to the kernel.6 Scanning backwards from that address, we eventually encounter the value 0x0100000cfeedfacf at address 0xfffffff01d804000, which looks like the start of a 64-bit Mach-O file. Reading the rest of the Mach-O header quickly confirms that this is the start of the kernel’s __TEXT segment. The kernel slide is then computed as 0xfffffff01d804000 - 0xfffffff007004000 = 0x0000000016800000, where 0xfffffff007004000 is the static address of the kernel’s __TEXT segment in the Mach-O file. Generic kernel function calls on iOS and macOS Once we have the basic kernel memory functions and the kernel slide, we can patch parts of the kernel heap in order to create a limited kernel function call capability, which libmemctl provides as the function kernel_call_7. Stefan Esser describes this technique in Tales from iOS 6 Exploitation and iOS 7 Security Changes. The idea is to patch the vtable of an IOUserClient instance in the kernel so that invoking the iokit_user_client_trap Mach trap on the user client causes a controlled function pointer to be called. The iokit_user_client_trap Mach trap is used to invoke external traps, described by the IOExternalTrap struct, on an IOUserClient instance. We can invoke this trap from user space using the IOConnectTrap6 function. The kernel implementation calls the user client’s getTargetAndTrapForIndex method to obtain an IOExternalTrap object and then calls the trap function with the user-supplied arguments. Here’s the code, from IOUserClient.cpp: kern_return_t iokit_user_client_trap(struct iokit_user_client_trap_args *args) { kern_return_t result = kIOReturnBadArgument; IOUserClient *userClient; if ((userClient = OSDynamicCast(IOUserClient, iokit_lookup_connect_ref_current_task((OSObject *)(args->userClientRef))))) { IOExternalTrap *trap; IOService *target = NULL; trap = userClient->getTargetAndTrapForIndex(&target, args->index); if (trap && target) { IOTrap func; func = trap->func; if (func) { result = (target->*func)(args->p1, args->p2, args->p3, args->p4, args->p5, args->p6); } } iokit_remove_connect_reference(userClient); } return result; } If we can control the target and trap returned by getTargetAndTrapForIndex, then we can call any function in the kernel with up to 7 arguments.7 First we need to create an IOUserClient instance at a known address in the kernel so that we can manipulate it. I chose AppleKeyStoreUserClient as the user client class because most applications can access it on both macOS and iOS, reducing the implementation overhead. At this point, our only useful primitive is a kernel heap memory scan, so we will create the user client and then try to find it in memory by inspecting the heap. We’ll need two pieces of information to fully identify the user client: the address of the AppleKeyStoreUserClient vtable and the user client’s registry entry ID. The former we can compute since we already know the kernel slide. We can find the user client’s registry entry ID by recording the IDs of all children of the AppleKeyStore service before and after creating the user client, and then looking for a new child entry.8 We then scan the kernel heap looking for pointers to the AppleKeyStoreUserClient vtable. Each of these locations could be the start of an AppleKeyStoreUserClient instance, but some of these addresses may point to freed objects or random heap garbage. However, we do know that our user client must be in this list. We can figure out which address corresponds to our user client by reading the registry entry ID field of each possible instance using our kernel memory functions: if any potential user client instance has the wrong registry entry ID, we can eliminate it. As long as there is exactly one match (which happens the overwhelming majority of the time), we can be sure that we’ve found the address of the user client to which we have a connection. The next step is to create a fake vtable that will allow us to control the target and trap returned by getTargetAndTrapForIndex. The default implementation of this method calls getExternalTrapForIndex to get the IOExternalTrap, then extracts the target service from the returned object: IOExternalTrap * IOUserClient:: getTargetAndTrapForIndex(IOService ** targetP, UInt32 index) { IOExternalTrap *trap = getExternalTrapForIndex(index); if (trap) { *targetP = trap->object; } return trap; } Thus, in order to control both parameters, the only thing we need to do is override getExternalTrapForIndex with a function that will return a pointer to controlled data. There are many possible candidates, but since we already know the address of the user client’s registry entry ID field, I chose to replace getExternalTrapForIndex with getRegistryEntryID. That way, when getExternalTrapForIndex is called, the user client’s registry entry ID will be returned instead. Of course, the user client’s registry entry ID is not going to be a valid kernel pointer. However, we know the address of our user client’s registry entry ID field, so we can overwrite it with a pointer to a controlled IOExternalTrap object. To create the fake vtable, we simply read the real AppleKeyStoreUserClient vtable from kernel memory and replace the IOUserClient::getExternalTrapForIndex method with IORegistryEntry::getRegistryEntryID. We can then allocate kernel memory with mach_vm_allocate and write the modified vtable into it. Finally, we need to patch the user client so that invoking iokit_user_client_trap will call the function we want. We allocate more kernel memory to store the fake IOExternalTrap object and overwrite the user client’s registry entry ID field with this address. Last of all, we overwrite the user client’s vtable pointer with the address of the fake vtable we copied into the kernel earlier. At this point, when iokit_user_client_trap calls getTargetAndTrapForIndex, the trap that is returned will be the address of our fake IOExternalTrap object. However, the fields of this object need to be initialized for each function call. In order to actually call a kernel function, we must overwrite the IOExternalTrap object so that the func field points to the function we want to call and the object field is the first argument to that function. Then, we can invoke IOConnectTrap6 with the remaining arguments to perform the actual function call. Unfortunately, using iokit_user_client_trap places some restrictions on the arguments and return value of the kernel function call. Because the trap->object pointer is verified as non-NULL before the trap is invoked, the first argument to the called function cannot be 0. Additionally, the return value of iokit_user_client_trap is a kern_return_t, which on 64-bit platforms is a 32-bit integer. Getting around these restrictions is the subject of the next two sections. Arbitrary kernel function calls on AArch64 It’s possible to construct a less restricted kernel function call capability on top of the generic mechanism just described. Libmemctl implements several jump-oriented programs to call arbitrary kernel functions with up to 8 arguments and retrieve the 64-bit return value in user space.9 The specific implementation is chosen based on the gadgets available in the running kernel. Here I’ll briefly describe one such program, which can be used when running iOS 10.1.1 on the iPhone 6s and iPhone 7. A complete listing of the gadgets executed in this payload, including the intermediate register values, is available in the source code. At a high level, we will construct a JOP payload in kernel memory and then use the generic kernel function call method we just established to start executing that payload. The generic function call mechanism supports up to 7 arguments: not enough for all 8 arguments to the target function, but plenty to initialize registers for a JOP payload. The payload will set up the function arguments in registers x0 through x7, jump to the target function, write the return value (stored in x0) into memory, and then return to the caller. The JOP payload has three parts: the JOP stack (called JOP_STACK), the value stack (called VALUE_STACK), and a block of memory to resume JOP execution after running the store gadget (called STORE_RESUME). The JOP_STACK stores the sequence of gadgets to execute, while the VALUE_STACK stores the values that will get loaded into registers. The most important JOP gadget is the dispatcher, called JOP_DISPATCH. For this payload, I am using this wonderful gadget from the com.apple.filesystems.apfs kext: ldp x2, x1, [x1] br x2 This gadget loads the x2 and x1 registers with the two 64-bit words at the address in x1 and then jumps to the address in x2. Because the load overwrites the dereferenced register x1, calling this gadget a second time will perform a different load and jump than before, which makes this gadget suitable as a JOP dispatcher. In fact, if you imagine this gadget being run repeatedly in a loop, you can see that it behaves kind of like a linked-list traversal. Thus, we can implement the JOP_STACK as a linked list, where the first pointer in each node is the gadget to execute and the second pointer is the address of the next node. We can chain the execution of these gadgets as long as each gadget jumps back to JOP_DISPATCH. This is what the JOP_STACK looks like in memory if we place all the nodes sequentially: JOP_STACK 8 10 18 20 28 30 38 +----------+----------+----------+----------+----------+----------+----------+- | gadget 0 | +0x10 | gadget 1 | +0x20 | gadget 2 | +0x30 | gadget 3 | ... +----------+----------+----------+----------+----------+----------+----------+- Once the JOP_STACK is running, we can load values from the VALUE_STACK into registers using the load gadget. The load gadget populates x3 through x6 from x20, which is the register used to store the address of the VALUE_STACK: ldp x3, x4, [x20, #0x20] ldp x5, x6, [x20, #0x30] blr x8 In order to keep running from the JOP_STACK after this gadget, we must set x8 equal to the address of JOP_DISPATCH. However, after the load gadget is run, we won’t be able to load new values until the VALUE_STACK is advanced past the values we just loaded. We can use the following gadget to advance the VALUE_STACK in preparation for another load: add x20, x20, #0x34 br x8 With the right collection of gadgets to shuffle values around the registers, we can perform a sequence of loads and moves to populate all the registers we need for the function call. I ended up using 4 loads with 3 intervening advances in order to populate registers with all the values I needed. Here is the layout of the VALUE_STACK in memory. Each chunk represents a single load, but because the advance gadget only moves the value stack forward by 0x34 bytes each time, the end of each chunk in the diagram overlaps with the beginning of the next one. The load gadget populates x3, x4, x5, and x6 with the contents of each chunk at offset 0x20, 0x28, 0x30, and 0x38, respectively. The result of the function call eventually gets written back to the VALUE_STACK at offset 0x9c. VALUE_STACK 10 20 30 34 40 +---------+---------+---------+---------+---------+---------+----+----+---------+ | ~ STORE_RESUME ~~ | | | gadget | gadget | _______ | STORE_R | >---+ +---------+---------+---------+---------+---------+---------+----+----+---------+ | | +-----------------------------------------------------------------------------------+ | V 34 40 44 54 64 68 74 +----+---------+----+---------+---------+---------+---------+----+----+---------+ ____ | STORE_R | : : : <func> : _______ : <arg7> : _______ : >---+ +----+---------+----+---------+---------+---------+---------+----+----+---------+ | | +-----------------------------------------------------------------------------------+ | V 68 74 78 88 98 9c a8 +----+---------+----+---------+---------+---------+---------+----+----+---------+ g7> : _______ : | | | <arg1> | <arg2> | <arg0> | _______ | >---+ +----+---------+----+---------+---------+---------+---------+----+----+---------+ | | +-----------------------------------------------------------------------------------+ | V 9c a8 ac bc cc d0 dc +----+---------+----+---------+---------+---------+---------+----+----+---------+ g0> | _______ | : JOP_DIS : JOP_STA : <arg3> : <arg4> : <arg5> : <arg6> : +----+---------+----+---------+---------+---------+---------+----+----+---------+ ^^^^^^^^^^^ | result | +---------+ Once all the registers have been populated from the VALUE_STACK, we can perform the function call. The last registers we overwrite will be x1 and x2, since those are used by the JOP_DISPATCH gadget; once they are overwritten we can no longer use the dispatcher. However, this presents a challenge: How do we start executing the JOP payload again after the function call? Fortunately, AArch64 provides a native way to control what code to run after a function call: the return address, stored in register x30. Thus, we need to fill x30 with the address of a gadget that will resume execution from the JOP stack. A quick scan of the available gadgets reveals this candidate: ldp x8, x1, [x20, #0x10] blr x8 We can use this gadget to resume execution by storing the JOP_DISPATCH and JOP_STACK in the VALUE_STACK, at offsets 0x10 and 0x18 of chunk 4. That way, the load will put JOP_DISPATCH in x8, the rest of the JOP_STACK in x1, and jump to JOP_DISPATCH, exactly as we needed. This gadget is also a good choice because it does not clobber x0, the register that contains the return value from the function call. Once we are running code from the JOP_STACK, the next step is to store the return value back into the VALUE_STACK so that we can read it from user space later. In order to store the return value, we need a store gadget. Unfortunately, none of the usable store gadgets I found in the iOS 10.1.1 and 10.2 kernelcaches could be executed directly: they were all stores followed by a C++ virtual method call, and hence needed a fake vtable in order to resume executing from the JOP_STACK. This is where STORE_RESUME comes in. Here’s the gadget I ended up using to store x0 into the VALUE_STACK: str x0, [x20] ldr x8, [x22] ldr x8, [x8, #0x28] mov x0, x22 blr x8 The gadget assumes that x22 is a pointer to some C++ object and performs a virtual method call (index 5) on that object. STORE_RESUME is a fake C++ object, a pointer to which we will store in x22, such that the virtual method call in this gadget will actually end up jumping back to the JOP_DISPATCH gadget and running the rest of the JOP_STACK. In order to continue executing the JOP_STACK, x8 must be JOP_DISPATCH at the final branch. We can use the following layout for STORE_RESUME: STORE_RESUME 8 10 +-----------------------+-----------------------+ | STORE_RESUME+0x8-0x28 | JOP_DISPATCH | +-----------------------+-----------------------+ Finally, after the store gadget writes the target function’s return value into the VALUE_STACK, we can have the JOP program return back to the caller. The caller will eventually return to user space, and from there we can read back the return value from kernel memory. While this strategy works very well on the systems I have tested, a significant limitation is that it may not work on other platforms and builds until an appropriate JOP program has been constructed using the available gadgets. These JOP programs are hard-coded: libmemctl does not have the power to dynamically create JOP payloads from unknown sets of gadgets. I originally tried implementing a limited dynamic payload generator, but it was complicated enough that I didn’t end up completing it. Arbitrary kernel function calls on x86_64 Calling arbitrary kernel functions on x86_64 platforms is a bit simpler than on AArch64. I use the same technique in libmemctl as I used in physmem: add a new system call by overwriting an entry in the system call table. We can overwrite read-only kernel memory by calling a kernel function to write to physical, rather than virtual, memory. Since the technique is described in detail in that post, I refer the interested reader there. Safe kernel memory access Once we can call arbitrary kernel functions, we can build safe mechanisms to read and write kernel memory outside the heap. This is because we can call kernel functions like pmap_find_phys and pmap_cache_attributes to translate a virtual address into a physical address and to determine physical cache attributes associated with an address. The safest access mechanism is kernel_read_safe, which ensures that an address is mapped and not a special I/O region before accessing it. We can check if the virtual address is mapped with pmap_find_phys, since this function will return 0 if a virtual address has no backing page. Determining whether or not an address is a special I/O region is trickier. One way is to check the region’s share mode: in my testing, all special physical memory regions have the share mode of the corresponding virtual region set to SM_EMPTY. Thus, as long as the share mode is not SM_EMPTY, the region is safe to access. However, there’s a big downside to kernel_read_safe: Many interesting and safe-to-access memory regions also have their share mode set to SM_EMPTY, including the kernel carveout (the large virtual memory region containing the kernel image). This means that kernel_read_safe and kernel_write_safe will fail to read or write to the kernel image. Libmemctl offers a way around this restriction with the kernel_read_all access mechanism. The idea is that most special I/O regions (for example, memory-mapped device registers) are located at predictable physical addresses; if we are careful not to access those addresses, we can avoid triggering a panic. Thus, kernel_read_all only forbids access to unmapped pages and static memory regions that are known to be inaccessible. The advantage is that a much larger portion of kernel memory can be accessed. However, because the blacklist of bad regions is static and hardcoded, it’s possible that kernel_read_all will trigger a panic on an untested platform. On some platforms, it’s also possible to safely read physical memory without first knowing the virtual address. The kernel function pmap_cache_attributes returns the physical cache attributes associated with an address. On iOS, all unsafe physical addresses have the VM_MEM_GUARDED bit set in these attributes (although some safe addresses also have that flag set). Libmemctl provides the function physical_read_safe which will only try to read physical addresses for which the VM_MEM_GUARDED bit is cleared. This is useful because it allows us to perform physical memory scans. Unfortunately, I have yet to smooth out a few issues with physical_read_safe: on some platforms (my Macbook Pro), there are unsafe physical addresses with the VM_MEM_GUARDED bit clear, meaning physical_read_safe is not actually safe. Thus, if you want to avoid a panic, don’t use physical_read_safe to scan memory. Implementing mach_portal with libmemctl In order to check libmemctl’s functionality, I reimplemented parts of Ian Beer’s mach_portal exploit using libmemctl APIs. The goal was to replace most of the kernel manipulations after acquiring the kernel task port. The repository is available at mach_portal_memctl. Examples of using memctl Finally, I’ll give a brief overview of how to use memctl. When you run memctl without arguments, it drops into a REPL. You can type commands which memctl will run. These commands are self-documented. To see a list, type ? at the prompt: memctl> ? i Print system information r <address> [length] Read and print formatted memory rb <address> <length> Print raw binary data from memory rs <address> [length] Read a string from memory w <address> <value> Write an integer to memory wd <address> <data> Write arbitrary data to memory ws <address> <string> Write a string to memory f <value> [range] Find an integer in memory fpr <pid> Find the proc struct for a process fc <class> [range] Find instances of a C++ class lc <address> Look up the class of a C++ object kp <address> Translate virtual to physical address kpm <range> Print virtual to physical address map zs <address> Get zalloc memory size pca <address> Show physical cache attributes vt <class> Find the vtable of a C++ class vtl <address> Look up the class name for a vtable vm <address> Show virtual memory information vmm [range] Show virtual memory information for range vma <size> Allocate virtual memory vmd <address> [size] Deallocate virtual memory vmp <protection> <address> [length] Set virtual memory protection ks [address] Kernel slide a <symbol> Find the address of a symbol ap [address] Address permutation s <address> Find the symbol for an address kcd <file> Decompress a kernelcache root Exec a root shell quit Exit the REPL Here, you can see a brief overview of every command supported by memctl. To get additional information about a specific command, type the name of the command (the part before the first space) followed by ?. For example, one of the most commonly used commands is r, which reads kernel memory: memctl> r? r[width] [-d] [-f] [-p] [-x access] <address> [length] Read data from kernel virtual or physical memory and print it with the specified formatting. Options: [width] The width to display each value [-d] Use dump format with ASCII [-f] Force read (unsafe) [-p] Read physical memory [-x access] The memory access width Arguments: <address> The address to read [length] The number of bytes to read Each command consists of a command name, followed by options, followed by arguments. Options are designated in square brackets and start with a dash. Options may take a single argument, such as the -x option above. Arguments to the command are designated in angle brackets. The last few arguments to a command may be optional, in which case they are surrounded by square brackets instead. If an optional argument is not supplied a suitable default value will be used. A command may also have an unnamed option, which is designated by placing it in square brackets directly following the command name. Unnamed options are provided when a particular option is used frequently enough that specifying the option name each time would be a nuisance. In the case of the r command, the unnamed width option indicates the integer width of the value or values to read. Memctl accepts two ways of specifying options to a command: verbose and compact. In the verbose form, each option is written out individually. For example, the following command reads 64 bytes from physical address 0x100, skipping safety checks, with an access width of 4 (that is, the read is performed 4 bytes at a time), and displays the result in dump format with a column width of 2: memctl> r2 -p -f -x 4 -d 100 64 0000000000000100: 0001 0203 0405 0607 0809 0a0b 0c0d 0e0f |................| 0000000000000110: 1011 1213 1415 1617 1819 1a1b 1c1d 1e1f |................| 0000000000000120: 2021 2223 2425 2627 2829 2a2b 2c2d 2e2f | !"#$%&'()*+,-./| 0000000000000130: 3031 3233 3435 3637 3839 3a3b 3c3d 3e3f |0123456789:;<=>?| However, since this command is so long to type, memctl also supports a compact format: any options that take no arguments or simple numeric arguments may be condensed and placed at the end of the command name. The following command is equivalent to the longer form above: memctl> r2pfx4d 100 64 Another useful command is the a (address) command, which takes a (mangled) symbol name and prints the runtime address of the symbol and a guess of the symbol’s size. By default, symbols are assumed to be in the kernel. If the symbol is in a kernel extension, you can place the bundle ID and a colon before the symbol name. To search the kernel and all kernel extensions for the symbol, put a colon before the symbol name but omit the bundle ID. memctl> a _copyout 0xffffff8015dfd700 (48) memctl> a com.apple.driver.AppleMobileFileIntegrity:_csEnforcementDisable 0xffffff7f9692396a (1) memctl> a :_csEnforcementDisable 0xffffff7f9692396a (1) The s command is the inverse of the a command: given an address, it prints information about the symbol corresponding to that address. memctl> s 0xffffff7f9692396b com.apple.driver.AppleMobileFileIntegrity __DATA: _lvEnforceThirdParty (1) Any time a command takes an address, you can also specify a symbol; the symbol will automatically be converted to its virtual address. memctl> vm :_csEnforcementDisable START - END [ VSIZE ] PRT/MAX SHRMOD DEPTH RESIDENT REFCNT TAG ffffff7f96922000-ffffff7f96925000 [ 12K ] rw-/rw- P/A 1 3 3 6 memctl> r1 :_csEnforcementDisable setting up kernel function call... ffffff7f9692396a: 00 memctl> w1 :_csEnforcementDisable 1 memctl> r1 :_csEnforcementDisable ffffff7f9692396a: 01 Other useful commands for inspecting IOKit objects are fc and lc, which find instances of a class and determine the class type of an object: memctl> fc AppleMobileFileIntegrity 0xffffff8035bf9000 memctl> vm 0xffffff8035bf9000 START - END [ VSIZE ] PRT/MAX SHRMOD DEPTH RESIDENT REFCNT TAG ffffff8034c86000-ffffff804538c000 [ 263M ] rw-/rwx S/A 1 67334 214 12 memctl> zs 0xffffff8035bf9000 160 memctl> r 0xffffff8035bf9000 160 ffffff8035bf9000: ffffff7f96922d70 0000000000020003 ffffff8035bf9010: ffffff803547cb00 ffffff8035bf6d00 ffffff8035bf9020: ffffff8035bf6a00 ffffff803547c320 ffffff8035bf9030: ffffff80352b00e0 0000000000000003 ffffff8035bf9040: 0000000000000000 000000000000001e ffffff8035bf9050: 0000000000000000 0000000000006cc7 ffffff8035bf9060: 0000000000000000 0000000000000000 ffffff8035bf9070: 0000000000000000 0000000000000000 ffffff8035bf9080: 0000000000000000 ffff4c85c7ffffff ffffff8035bf9090: bd394c00000000ff deadbeefdeadbeef memctl> lc ffffff803547cb00 error: address 0xffffff8035bf7e40 is not a vtable memctl> lc ffffff8035bf6d00 OSDictionary memctl> lc ffffff8035bf6a00 OSDictionary memctl> lc ffffff803547c320 error: address 0x0000000000000000 is not a vtable memctl> lc ffffff80352b00e0 IOResources Overall, I find memctl a useful aid to understand what’s happening in kernel memory. Conclusion In this post I have introduced memctl, a library and tool to safely access kernel memory and call kernel functions. Memctl is primarily a research tool to aid me in analyzing the macOS/iOS kernel. However, I have open sourced it in the hope that someone else finds either the tool or the techniques useful. Credits Many thanks to Ian Beer, Luca Todesco, Stefan Esser, and Jonathan Levin for their invaluable iOS security and internals research. Footnotes Memctl is facetiously named after sysctl, the system control utility; it is called “memctl” because it controls memory, not the system. ↩ Yalu102 patches the task_for_pid system call to enable it to return the task port for the kernel task. mach_portal stashes the kernel task port in host special port 4. The memctl-tfp0-core core checks for both patches, and is the recommended core for jailbroken iOS devices. ↩ Of course, it is possible to hardcode the addresses of these kernel symbols, but libmemctl tries to avoid hardcoding offsets as much as possible, and always avoids hardcoding addresses. Kernel dumps could also be used on earlier platforms, but these tend to be missing symbol and prelink information as well. Instead, libmemctl tries to rely on the kernel itself (as found on the filesystem) to discover offsets and addresses, making transitions between new OS versions easier. ↩ The user_tag attribute is only useful starting with OS X 10.11 El Capitan. ↩ Even though the memory region containing the kernel is marked as non-readable non-writable in the virtual memory map, the actual page-table permissions clearly allow reading and sometimes writing these pages. I am not sure why the memory region containing the kernel image has these strange permissions. ↩ On the iPhone 7, the virtual memory carveout that contains the kernel looks different: START - END [ VSIZE ] PRT/MAX SHRMOD DEPTH RESIDENT REFCNT TAG ffffffe000000000-ffffffe0000e0000 [ 896K ] rw-/rwx PRV 0 56 1 79 ... ffffffe02a2d0000-ffffffe02a2e8000 [ 96K ] rw-/rwx S/A 0 6 180 12 ... fffffff000000000-fffffff27fffc000 [ 10G ] ---/--- NUL 0 0 0 0 The kernel lies somewhere in the very last region, which starts at address 0xfffffff000000000. ↩ The reason why we control 7 arguments and not 6 is that func is treated as a C++ method being invoked on the target object, which means target will be passed as the implicit first parameter to func. ↩ Despite searching far and wide, I could not find an official API to retrieve the registry entry ID associated with an io_connect_t object returned by IOServiceOpen. This was the simplest and most flexible workaround I could find. ↩ It would have been possible to do the same using a return-oriented program instead, but JOP has the advantage of preserving the kernel stack, making clean-up easier. ↩ Sursa: https://bazad.github.io/2017/09/live-kernel-introspection-ios/
      • 1
      • Upvote
  3. CVE-2017-13868: A fun XNU infoleak by Brandon Azad March 2, 2018 Way back in October of 2017, I discovered CVE-2017-13868, a kernel information leak in XNU that was quite fun to analyze and exploit. While browsing the XNU source code, I noticed that the function ctl_ctloutput didn’t check the return value of a call to sooptcopyin. This immediately caught my attention because error checking in the kernel is very important: poor error checking is a frequent source of security bugs. In this case, failing to check the return value opened a race window that could allow a privileged process to read an arbitrary amount of uninitialized kernel heap data. Finding the vulnerability One of the most effective ways I have for finding vulnerabilities is simply reading through the source code of areas of the kernel that seem relevant to security. I’ve found more bugs by source code auditing and reverse engineering than by any other technique, including fuzzing and, my favorite, stumbling onto a security flaw by accident (it happens surprisingly often). I started looking for iOS bugs again around mid September of last year. Around that time I noticed that there seemed to be an uptick in the number of race conditions reported in Apple’s security notes for macOS and iOS. Because of that, I figured it would be good to keep parallelism in mind while auditing. I had decided to look at indirect calls to copyout to see if I could discover any obvious information leaks. Information leaks are a category of vulnerability where the kernel discloses information that it shouldn’t. For example, disclosing kernel pointers to userspace may allow a local attacker to defeat the kernel’s address space randomization (kASLR) exploit mitigation. Exploit techniques like ROP depend on knowing the location of the kernel’s executable code in memory, which means kernel pointer disclosures have become a key component of modern macOS and iOS kernel exploitation. The copyout function is responsible for copying data from the kernel’s address space into the address space of usermode processes. Most kernel infoleaks will pass the leaked data through copyout, which makes call sites to this function promising areas to look for bugs. However, it’s not just this one function: there are many wrappers around copyout that are also worth investigating. For example, one such wrapper is sooptcopyout, which is used to copy out socket options data for the getsockopt system call. It was while looking through calls to this function that the following code, from the ctl_ctloutput function in the file bsd/kern/kern_control.c, caught my eye: if (sopt->sopt_valsize && sopt->sopt_val) { MALLOC(data, void *, sopt->sopt_valsize, M_TEMP, // (a) data is allocated M_WAITOK); // without M_ZERO. if (data == NULL) return (ENOMEM); /* * 4108337 - copy user data in case the * kernel control needs it */ error = sooptcopyin(sopt, data, // (b) sooptcopyin() is sopt->sopt_valsize, sopt->sopt_valsize); // called to fill the } // buffer; the return len = sopt->sopt_valsize; // value is ignored. socket_unlock(so, 0); error = (*kctl->getopt)(kctl->kctlref, kcb->unit, // (c) The getsockopt() kcb->userdata, sopt->sopt_name, // implementation is data, &len); // called to process if (data != NULL && len > sopt->sopt_valsize) // the buffer. panic_plain("ctl_ctloutput: ctl %s returned " "len (%lu) > sopt_valsize (%lu)\n", kcb->kctl->name, len, sopt->sopt_valsize); socket_lock(so, 0); if (error == 0) { if (data != NULL) error = sooptcopyout(sopt, data, len); // (d) If (c) succeeded, else // then the data buffer sopt->sopt_valsize = len; // is copied out to } // userspace. The ctl_ctloutput function is responsible for handling the getsockopt system call on kernel control sockets (that is, sockets created with domain PF_SYSTEM and protocol SYSPROTO_CONTROL). The code does the following: It allocates a kernel heap buffer for the data parameter to getsockopt. Because the M_ZERO flag is not specified, the allocation is not zeroed out. It copies in the getsockopt data from userspace using sooptcopyin, filling the data buffer just allocated. This copyin should completely overwrite the allocated data, which is why the M_ZERO flag was not needed. The return value is not checked. It then calls kctl->getopt, the real getsockopt implementation for this kernel control socket. This implementation will process the input buffer, possibly modifying it and shortening it, and return a result code. Finally, if the real getsockopt implementation doesn’t return an error, ctl_ctloutput calls sooptcopyout to copy the data buffer back to user space. The issue is that the return value from sooptcopyin is not checked. This begs the question: what could happen if sooptcopyin fails that wouldn’t be possible if the return value were checked? Analyzing exploitability The function sooptcopyin is responsible for copying in the getsockopt options data from userspace into the allocated buffer. If sooptcopyin fails, perhaps because the socket options data address is invalid, then the kernel data buffer which should have contained the options data will be uninitialized. And because the data buffer was allocated without the M_ZERO flag, that means that it will contain uninitialized kernel heap data, possibly rife with useful kernel pointers. So, the lack of error checking means that the data buffer passed to kctl->getopt could actually contain uninitialized kernel heap data, even though the code as written seems to expect the contents of the data buffer to always be initialized before the call to kctl->getopt. Is there a way to get that uninitialized memory to flow to a call to copyout? The obvious candidate for copyout is the call to sooptcopyout just after kctl->getopt. But there’s a problem: sooptcopyout is passed the same sopt structure that was supplied to sooptcopyin, which means it will try to write the uninitialized data to the same address from which sooptcopyin tried to read the socket options earlier. And in order to force sooptcopyin to fail we supplied it with an invalid address. So how do we make sooptcopyout succeed where sooptcopyin failed? At this point I remembered to consider parallelism. Would it be possible to make the memory address valid in between the calls to sooptcopyin and sooptcopyout? To do that, we’d need to call getsockopt with an unmapped address, and while getsockopt is running in the kernel, call mach_vm_allocate on another thread to map that address. That way, the address would be unmapped when sooptcopyin is called, causing it to fail, but mapped when sooptcopyout is called, allowing the copyout of uninitialized kernel heap data to succeed. However, there’s one more thing we need to check: does the uninitialized heap data actually make it all the way to the call to sooptcopyout? There’s an intervening call to kctl->getopt which could overwrite the uninitialized data or change the length of the data to copy out to userspace. The actual implementation of kctl->getopt is determined by what type of control socket we’re operating on. Thus, in order to reach sooptcopyout with the uninitialized data intact, we need to find a kernel control socket with a getopt implementation that: does not overwrite the whole data buffer; does not shorten the data buffer; and returns success (that is, 0). Fortunately, it didn’t take much searching to find a candidate: the function necp_ctl_getopt, which is the getopt implementation for NECP kernel control sockets, simply returns 0 without processing the data buffer at all. The primary limitation of this approach is our ability to reallocate the memory address between the calls to sooptcopyin and sooptcopyout. Not a lot of work happens between those calls, meaning the race window could be pretty tight. If the race window is too tight, it might take a large number of tries to actually win the race. An alternative approach (that did not work) While reviewing this bug later, it seemed like it should have been possible to trigger it without any race at all by marking the memory write-only. That way, sooptcopyin would fail with EFAULT (because the memory is not readable) but sooptcopyout would succeed. However, in my testing, this simpler exploit strategy didn’t work: getsockopt would fail with EFAULT. I’m not sure why this happened. The final exploit After figuring out a strategy to trigger the information leak, I implemented the exploit. The high-level strategy is to open an NECP kernel control socket, launch a thread that will repeatedly map and unmap the target memory address, and then repeatedly call getsockopt on the control socket to try and trigger the leak. The complete exploit is available on my GitHub. Amazingly, it turned out that this was a pretty easy race to win. I performed tests on a 2015 Macbook Pro and an iPhone 7, and found that the median number of attempts to win the race on these platforms was 5 and 2, respectively. (The distribution was rather uneven, with the mean number of attempts on the Macbook sometimes rising as high as 600. However, this was primarily due to a few very large outliers, where it would take tens of thousands of attempts to win the race.) What’s great about this infoleak is that it does not depend on a fixed leak size: you can use it to leak data from arbitrary kernel heap zones by specifying different sizes to getsockopt. This makes for a very useful exploit primitive when performing complex attacks on the kernel. The fix I reported this issue to Apple on October 7, 2017, and it was assigned CVE-2017-13868. Apple fixed the bug in macOS 10.13.2 and iOS 11.2. Looking at the new kern_control.c, Apple decided to fix the bug by wrapping the code after the call to sooptcopyin in an if statement that checks whether there has been an error. I believe that this is the correct fix for this issue. Sursa: https://bazad.github.io/2018/03/a-fun-xnu-infoleak/
      • 2
      • Upvote
  4. CrawlBox Easy way to brute-force web directory. Operating Systems Tested MacOSX Kali Linux Usage python crawlbox.py [-h] [-v] [-w WORDLIST] url positional arguments: url specific target url, like domain.com optional arguments: -h, --help show this help message and exit -v, --version show program's version number and exit -w WORDLIST specific path to wordlist file -d DELAY add delay between requests Example web site scan with internal wordlist python crawlbox.py www.domain.com web site scan with external wordlist python crawlbox.py www.domain.com -w wordlist.txt Install (as root) git clone https://github.com/abaykan/crawlbox.git cd crawlbox/ pip install -r requirements.txt python crawlbox.py -h note: tested with python 2.7.6 Media Review Seucurity Training Share : https://securityonline.info/crawlbox-brute-force-web-directory/ PentestTools : https://pentesttoolz.com/2018/03/02/crawlbox-easy-way-to-brute-force-web-directory/ Sursa: https://github.com/abaykan/crawlbox
      • 1
      • Upvote
  5. By BALAJI N November 26, 2017 ATM Penetration testing, Hackers have found different approaches to hack into the ATM machines. Programmers are not restricting themselves to physical assaults, for example, money/card catching, skimming, and so forth they are investigating better approaches to hack ATM programming. An ATM is a machine that empowers the clients to perform keeping money exchange without setting off to the bank. Utilizing an ATM, a client can pull back or store the money, get to the bank store or credit account, pay the bills, change the stick, redesign the individual data, and so on. Since the ATM machine manages money, it has turned into a high need focus for programmers and burglars. In this article, we will perceive how do an ATM functions, security arrangements used to secure the ATMs, diverse sorts of infiltration testing to break down ATM security and a portion of the security best practices which can be utilized to evade ATM hack. Articol complet: https://gbhackers.com/advanced-atm-penetration-testing-methods/
  6. Added support for Chrome 64 (32 bits) to NetRipper https://github.com/NytroRST/NetRipper
  7. Added support for Chrome 64 (only 64 bits right now).
  8. https://www.blackhat.com/asia-18/presenters/Ionut-Popescu.html
  9. The previous two blog posts describe how a Stack Based Buffer Overflow vulnerability works on x86 (32 bits) Windows. In the first part, you can find a short introduction to x86 Assembly and how the stack works, and on the second part you can understand this vulnerability and find out how to exploit it. This article will present a similar approach in order to understand how it is possible to exploit this vulnerability on x64 (64 bits) Windows. First part will cover the differences in the Assembly code between x86 and x64 and the different function calling convention, and the second part will detail how these vulnerabilities can be exploited. ASM for x64 There are multiple differences in Assembly that need to be understood in order to proceed. Here we will talk about the most important changes between x86 and x64 related to what we are going to do. Articol complet: https://nytrosecurity.com/2018/01/24/stack-based-buffer-overflows-on-x64-windows/
      • 6
      • Upvote
  10. E OK sa ai bac-ul si daca nu vrei sa te angajezi... Nu cred ca e necesar, nu stiu daca o fi cumva obligatoriu din punct de vedere legal, dar in principiu cred ca multe firme cer bac-ul pentru ca e de bun simt sa il ai.
  11. Nu este un forum de gaming... Avem Offtopic unde e plin de porcarii.
  12. E activ, dar nu avem prea mult timp sa ne ocupam de el.
  13. With WPA3, Wi-Fi security is about to get a lot tougher Finally, a security reprieve for open Wi-Fi hotspot users. By Zack Whittaker for Zero Day | January 8, 2018 -- 22:28 GMT (22:28 GMT) | Topic: Security At last, Wi-Fi security -- or lack of -- is about to get its day in the sun. The Wi-Fi Alliance, an industry body made up of device makers including Apple, Microsoft, and Qualcomm, announced Monday its next-generation wireless network security standard, WPA3. The standard will replace WPA2, a near-two decades-old security protocol that's built in to protect almost every wireless device today -- including phones, laptops, and the Internet of Things. SECURITY 101 One of the key improvements in WPA3 will aim to solve a common security problem: open Wi-Fi networks. Seen in coffee shops and airports, open Wi-Fi networks are convenient but unencrypted, allowing anyone on the same network to intercept data sent from other devices. WPA3 employs individualized data encryption, which scramble the connection between each device on the network and the router, ensuring secrets are kept safe and sites that you visit haven't been manipulated. Another key improvement in WPA3 will protect against brute-force dictionary attacks, making it tougher for attackers near your Wi-Fi network to guess a list of possible passwords. The new wireless security protocol will also block an attacker after too many failed password guesses. WPA2, the current incarnation of the wireless security standard since 2004, uses a four-way handshake to securely allows new devices with a pre-shared password to join a network. The newer WPA3 will use a newer kind of handshake, Mathy Vanhoef, a computer security academic, told ZDNet, which will "not be vulnerable to dictionary attacks." A new wireless security standard can't come soon enough. A few months ago Wi-Fi security was under scrutiny amid a security vulnerability in WPA2, discovered by Vanhoef, which put every WPA2-compatible device -- including routers, phones, and computers -- at risk of hijack. The new WPA3 security standard is expected to land in devices later this year. Sursa: http://www.zdnet.com/article/wpa3-wireless-standard-tougher-wifi-security-revealed/
  14. Nytro

    Fun stuff

  15. Cum arată Eveline Cismaru, tânăra care a spart sistemul de securitate al Poliţiei din Washington GALERIE FOTO Publicat: Vineri, 29 Decembrie 2017 19:21 // Actualizat: Vineri, 29 Decembrie 2017 19:26 // Sursa: romaniatv.net Autor: Filip Stan Eveline Cismaru, tânăra care a spart sistemul de securitate al Poliției din Washington, publica poze provocatoare pe Facebook. Ea a fost arestată, alături de Mihai Alexandru Işvanca, pe 15 decembrie, la București, în cadrul unei operațiuni care viza mai mulți hackeri români. Comenteaza PrevNext Mihai Alexandru Işvanca și Eveline Cismaru sunt acuzați de procurorii americani că au piratat sistemul care gestionează camerele de supraveghere din Washington. Tinerii au accesat fraudulos aproape 123 de calculatoare care erau conectate la camerele de supraveghere ale Poliției Metropolitane din Washington. În ianuarie, cei doi hackeri români au reușit să scoată din funcțiune două treimi din numărul camerelor video ale Poliției, notează observator.tv. Secret Service a informat că un număr de computere conectate la camere de supraveghere ale Departamentului Poliției Metropolitane au fost afectate în perioada 9-12 ianuarie de virușii de tip ransomware "cerber" şi "dharma". Incidentul a avut loc chiar înaintea ceremoniei de învestire în funcție a președintelui Donald Trump, iar autoritățile americane au demarat imediat o investigație. Mihai Alexandru Işvanca și Eveline Cismaru ar fi vrut să obțină o sumă de bani pentru a debloca sistemul. În prezent, Mihai Alexandru Işvanca se află în arest preventiv, iar femeia în arest la domiciliu, în vederea extrădării. Curtea de Apel Bucureşti a judecat în 16 decembrie cazul lor, acordând termen 11 ianuarie 2018 pentru judecarea cererii de extrădare. Citeste mai mult pe RTV.NET: http://www.romaniatv.net/cum-arata-eveline-cismaru-tanara-care-a-spart-sistemul-de-securitate-al-politiei-din-washington_395508.html#ixzz533E5F9P9
  16. https://github.com/hfiref0x/VBoxHardenedLoader
  17. Stack Based Buffer Overflows on x86 (Windows) – Part II In the first part of this article, we discussed about the basics that we need to have in order to properly understand this type of vulnerability. As we went through how the compiling process works, how assembly looks like and how the stack works, we can go further and explore how a Stack Based Buffer Overflow vulnerability can be exploited. Introduction We previously discussed that the stack (during a function call) contains the following (in the below order, where the “local variables” are stored at the “smallest address” and “function parameters” are stored at the highest address): Local variables of the function (for example 20 bytes) Previous EBP value (to create the stack frame, saved with PUSH EBP) Return address (placed on the stack by the CALL instruction) Parameters of the function (placed on the stack using PUSH instructions) Sursa: https://nytrosecurity.com/2017/12/20/stack-based-buffer-overflows-on-x86-windows-part-ii/
      • 3
      • Upvote
  18. Da, vazusem la un moment dat, o sa il scot. L-am pus in Apache si probabil in genereaza si IPBoard.
  19. Am facut update la server. Aveti acum si HTTP 2.0. Sa imi ziceti daca sunt probleme.
  20. A reinceput sa creasca Bitcoin.
  21. O descriere oficiala puteti gasi aici: https://www.bestjobs.eu/ro/loc-de-munca/working-student-application-security-internship Daca aveti intrebari, astept un mesaj privat.
  22. Salut, 1&1 cauta persoane interesate de securitatea aplicatiilor web. Se cauta si pentru penetration testing si pentru dezvoltarea unor aplicatii legate de acest lucru. Daca e cineva interesat, astept un mesaj privat si va pot oferi mai multe detalii.
×
×
  • Create New...