Normal view

There are new articles available, click to refresh the page.
Before yesterdaySolomonSklash.io

Using Syscalls to Inject Shellcode on Windows

1 June 2020 at 15:20

Using Syscalls to Inject Shellcode on Windows

After learning how to write shellcode injectors in C via the Sektor7 Malware Development Essentials course, I wanted to learn how to do the same thing in C#. Writing a simple injector that is similar to the Sektor7 one, using P/Invoke to run similar Win32 API calls, turns out to be pretty easy. The biggest difference I noticed was that there was not a directly equivalent way to obfuscate API calls. After some research and some questions on the BloodHound Slack channel (thanks @TheWover and @NotoriousRebel!), I found there are two main options I could look into. One is using native Windows system calls (AKA syscalls), or using Dynamic Invocation. Each have their pros and cons, and in this case the biggest pro for syscalls was the excellent work explaining and demonstrating them by Jack Halon (here and here) and badBounty. Most of this post and POC is drawn from their fantastic work on the subject. I know TheWover and Ruben Boonen are doing some work on D/Invoke, and I plan on digging into that next.

I want to mention that a main goal of this post is to serve as documentation for this proof of concept and to clarify my own understanding. So while I’ve done my best to ensure the information here is accurate, it’s not guaranteed to be 100%. But hey, at least the code works.

Said working code is available here

Native APIs and Win32 APIs

To begin, I want to cover why we would want to use syscalls in the first place. The answer is API hooking, performed by AV/EDR products. This is a technique defensive products use to inspect Win32 API calls before they are executed, determine if they are suspicious/malicious, and either block or allow the call to proceed. This is done by slightly the changing the assembly of commonly abused API calls to jump to AV/EDR controlled code, where it is then inspected, and assuming the call is allowed, jumping back to the code of the original API call. For example, the CreateThread and CreateRemoteThread Win32 APIs are often used when injecting shellcode into a local or remote process. In fact I will use CreateThread shortly in a demo of injection using strictly Win32 APIs. These APIs are defined in Windows DLL files, in this case MSDN tells us in Kernel32.dll. These are user-mode DLLs, which mean they are accessible to running user applications, and they do not actually interact directly with the operating system or CPU. Win32 APIs are essentially a layer of abstraction over the Windows native API. This API is considered kernel-mode, in that these APIs are closer to the operating system and underlying hardware. There are technically lower levels than this that actually perform kernel-mode functionality, but these are not exposed directly. The native API is the lowest level that is still exposed and accessible by user applications, and it functions as a kind of bridge or glue layer between user code and the operating system. Here’s a good diagram of how it looks:

Windows Architecture

You can see how Kernell32.dll, despite the misleading name, sits at a higher level than ntdll.dll, which is right at the boundary between user-mode and kernel-mode.

So why does the Win32 API exist? A big reason it exists is to call native APIs. When you call a Win32 API, it in turn calls a native API function, which then crosses the boundary into kernel-mode. User-mode code never directly touches hardware or the operating system. So the way it is able to access lower-level functionality is through native PIs. But if the native APIs still have to call yet lower level APIs, why not got straight to native APIs and cut out an extra step? One answer is so that Microsoft can make changes to the native APIs with out affecting user-mode application code. In fact, the specific functions in the native API often do change between Windows versions, yet the changes don’t affect user-mode code because the Win32 APIs remain the same.

So why do all these layers and levels and APIs matter to us if we just want to inject some shellcode? The main difference for our purposes between Win32 APIs and native APIs is that AV/EDR products can hook Win32 calls, but not native ones. This is because native calls are considered kernel-mode, and user code can’t make changes to it. There are some exceptions to this, like drivers, but they aren’t applicable for this post. The big takeaway is defenders can’t hook native API calls, while we are still allowed to call them ourselves. This way we can achieve the same functionality without the same visibility by defensive products. This is the fundamental value of system calls.

System Calls

Another name for native API calls is system calls. Similar to Linux, each system call has a specific number that represents it. This number represents an entry in the System Service Dispatch Table (SSDT), which is a table in the kernel that holds various references to various kernel-level functions. Each named native API has a matching syscall number, which has a corresponding SSDT entry. In order to make use of a syscall, it’s not enough to know the name of the API, such as NtCreateThread. We have to know its syscall number as well. We also need to know which version of Windows our code will run on, as the syscall numbers can and likely will change between versions. There are two ways to find these numbers, one easy, and one involving the dreaded debugger.

The first and easist way is to use the handy Windows system call table created by Mateusz “j00ru” Jurczyk. This makes it dead simple to find the syscall number you’re looking for, assuming you already know which API you’re looking for (more on that later).

WinDbg

The second method of finding syscall numbers is to look them up directly at the source: ntdll.dll. The first syscall we need for our injector is NtAllocateVirtualMemory. So we can fire up WinDbg and look for the NtAllocateVirtualMemory function in ntdll.dll. This is much easier than it sounds. First I open a target process to debug. It doesn’t matter which process, as basically all processes will map ntdll.dll. In this case I used good old notepad.

Opening Notepad in WinDbg

We attach to the notepad process and in the command prompt enter x ntdll!NtAllocateVirtualMemory. This lets us examine the NtAllocateVirtualMemory function within the ntdll.dll DLL. It returns a memory location for the function, which we examine, or unassemble, with the u command:

NtAllocateVirtualMemory Unassembled

Now we can see the exact assembly language instructions for calling NtAllocateVirtualMemory. Calling syscalls in assembly tends to follow a pattern, in that some arguments are setup on the stack, seen with the mov r10,rcx statement, followed by moving the syscall number into the eax register, shown here as mov eax,18h. eax is the register the syscall instruction uses for every syscall. So now we know the syscall number of NtAllocateVirtualMemory is 18 in hex, which happens to be the same value listed on in Mateusz’s table! So far so good. We repeat this two more times, once for NtCreateThreadEx and once for NtWaitForSingleObject.

Finding the syscall number for NtCreateThreadEx Finding the syscall number for NtWaitForSingleObject

Where are you getting these native functions?

So far the process of finding the syscall numbers for our native API calls has been pretty easy. But there’s a key piece of information I’ve left out thus far: how do I know which syscalls I need? The way I did this was to take a basic functioning shellcode injector in C# that uses Win32 API calls (named Win32Injector, included in the Github repository for this post) and found the corresponding syscalls for each Win32 API call. Here is the code for Win32Injector:

Win32Injector

This is a barebones shellcode injector that executes some shellcode to display a popup box:

Hello world from Win32Injector

As you can see from the code, the three main Win32 API calls used via P/Invoke are VirtualAlloc, CreateThread, and WaitForSingleObject, which allocate memory for our shellcode, create a thread that points to our shellcode, and start the thread, respectively. As these are normal Win32 APIs, they each have comprehensive documentation on MSDN. But as native APIs are considered undocumented, we may have to look elsewhere. There is no one source of truth for API documentation that I could find, but with some searching I was able to find everything I needed.

In the case of VirtualAlloc, some simple searching showed that the underlying native API was NtAllocateVirtualMemory, which was in fact documented on MSDN. One down, two to go.

Unfortunately, there was no MSDN documentation for NtCreateThreadEx, which is the native API for CreateThread. Luckily, badBounty’s directInjectorPOC has the function definition available, and already in C# as well. This project was a huge help, so kudos to badBounty!

Lastly, I needed to find documentation for NtWaitForSingleObject, which as you might guess, is the native API called by WaitForSingleObject. You’ll notice a theme where many native API calls are prefaced with “Nt”, which makes mapping them from Win32 calls easier. You may also see the prefix “Zw”, which is also a native API call, but normally called from the kernel. These are sometimes identical, which you will see if you do x ntdll!ZwWaitForSingleObject and x ntdll!NtWaitForSingleObject in WinDbg. Again we get lucky with this API, as ZwWaitForSingleObject is documented on MSDN.

I want to point out a few other good sources of information for mapping Win32 to native API calls. First is the source code for ReactOS, which is an open source reimplementation of Windows. The Github mirror of their codebase has lots of syscalls you can search for. Next is SysWhispers, by jthuraisamy. It’s a project designed to help you find and implement syscalls. Really good stuff here. Lastly, the tool API Monitor. You can run a process and watch what APIs are called, their arguments, and a whole lot more. I didn’t use this a ton, as I only needed 3 syscalls and it was faster to find existing documentation, but I can see how useful this tool would be in larger projects. I believe ProcMon from Sysinternals has similar functionality, but I didn’t test it out much.

Ok, so we have our Win32 APIs mapped to our syscalls. Let’s write some C#!

But these docs are all for C/C++! And isn’t that assembly over there…

Wait a minute, these docs all have C/C++ implementations. How do we translate them into C#? The answer is marshaling. This is the essence of what P/Invoke does. Marshaling is a way of making use of unmanaged code, e.g. C/C++, and using in a managed context, that is, in C#. This is easily done for Win32 APIs via P/Invoke. Just import the DLL, specify the function definition with the help of pinvoke.net, and you’re off to the races. You can see this in the demo code of Win32Injector. But since syscalls are undocumented, Microsoft does not provide such an easy way to interface with them. But it is indeed possible, through the magic of delegates. Jack Halon covers delegates really well here and here, so I won’t go too in depth in this post. I would suggest reading those posts to get a good handle on them, and the process of using syscalls in general. But for completeness, delegates are essentially function pointers, which allow us to pass functions as parameters to other functions. The way we use them here is to define a delegate whose return type and function signature matches that of the syscall we want to use. We use marshaling to make sure the C/C++ data types are compatible with C#, define a function that implements the syscall, including all of its parameters and return type, and there you have it!

Not quite. We can’t actually call a native API, since the only implementation of it we have is in assembly! We know its function definition and parameters, but we can’t actually call it directly the same way we do a Win32 API. The assembly will work just fine for us though. Once again, it’s rather simple to execute assembly in C/C++, but C# is a little harder. Luckily we have a way to do it, and we already have the assembly from our WinDbg adventures. And don’t worry, you don’t really need to know assembly to make use of syscalls. Here is the assembly for the NtAllocateVirtualMemory syscall:

NtAllocateVirtualMemory Assembly

As you can see from the comments, we’re setting up some arguments on the stack, moving our syscall number into the eax register, and using the magic syscall operator. At a low enough level, this is just a function call. And remember how delegates are just function pointers? Hopefully it’s starting to make sense how this is fitting together. We need to get a function pointer that points to this assembly, along with some arguments in a C/C++ compatible format, in order to call a native API.

Putting it all together

So we’re almost done now. We have our syscalls, their numbers, the assembly to call them, and a way to call them in delegates. Let’s see how it actually looks in C#:

NtAllocateVirtualMemory Code

Starting from the top, we can see the C/C++ definition of NtAllocateVirtualMemory, as well as the assembly for the syscall itself. Starting at line 38, we have the C# definition of NtAllocateVirtualMemory. Note that it can take some trial and error to get each type in C# to match up with the unmanaged type. We create a pointer to our assembly inside an unsafe block. This allows us to perform operations in C#, like operate on raw memory, that are normally not safe in managed code. We also use the fixed keyword to make sure the C# garbage collector does not inadvertently move our memory around and change our pointers. Once we have a raw pointer to the memory location of our shellcode, we need to change its memory protection to executable so it can be run directly, as it will be a function pointer and not just data. Note that I am using the Win32 API VirtualProtectEx to change the memory protection. I’m not aware of a way to do this via syscall, as it’s kind of a chicken and the egg problem of getting the memory executable in order to run a syscall. If anyone knows how to do this in C#, please reach out! Another thing to note here is that setting memory to RWX is generally somewhat suspicious, but as this is a POC, I’m not too worried about that at this point. We’re concerned with hooking right now, not memory scanning!

Now comes the magic. This is the struct where our delegates are declared:

Delegates Struct

Note that a delegate definition is just a function signature and return type. The implementation is up to us, as long as it matches the delegate definition, and it’s what we’re implementing here in the C# NtAllocateVirtualMemory function. At line 65 above, we create a delegate named assembledFunction, which takes advantage of the special marshaling function Marshal.GetDelegateForFunctionPointer. This method allows us to get a delegate from a function pointer. In this case, our function pointer is the pointer to the syscall assembly called memoryAddress. assembledFunction is now a function pointer to an assembly language function, which means we’re now able to execute our syscall! We can call assembledFunction delegate like any normal function, complete with arguments, and we will get the results of the NtAllocateVirtualMemory syscall. So in our return statement we call assembledFunction with the arguments that were passed in and return the result. Let’s look at where we actually call this function in Program.cs:

Calling NtAllocateMemory

Here you can see we make a call to NtAllocateMemory instead of the Win32 API VirtualAlloc that Win32Injector uses. We setup the function call with all the needed arguments (lines 43-48) and make the call to NtAllocateMemory. This returns a block of memory for our shellcode, just like VirtualAlloc would!

The remaining steps are similar:

Remaining Syscalls

We copy our shellcode into our newly-allocated memory, and then create a thread within our current process pointing to that memory via another syscall, NtCreateThreadEx, in place of CreateThread. Finally, we start the thread with a call to the syscall NtWaitForSingleObject, instead of WaitForSingleObject. Here’s the final result:

Hello World Shellcode

Hello world via syscall! Assuming this was some sort of payload running on a system with API hooking enabled, we would have bypassed it and successfully run our payload.

A note on native code

Some key parts of this puzzle I’ve not mentioned yet are all of the native structs, enumerations, and definitions needed for the syscalls to function properly. If you look at the screenshots above, you will see types that don’t have implementations in C#, like the NTSTATUS return type for all the syscalls, or the AllocationType and ACCESS_MASK bitmasks. These types are normally declared in various Windows headers and DLLs, but to use syscalls we need to implement them ourselves. The process I followed to find them was to look for any non-simple type and try to find a definition for it. Pinvoke.net was massively helpful for this task. Between it and other resources like MSDN and the ReactOS source code, I was able to find and add everything I needed. You can find that code in the Native.cs class of the solution here.

Wrapup

Syscalls are fun! It’s not every day you get to combine 3 different languages, managed and unmanaged code, and several levels of Windows APIs in one small program. That said, there are some clear difficulties with syscalls. They require a fair bit of boilerplate code to use, and that boilerplate is scattered all around for you to find like a little undocumented treasure hunt. Debugging can also be tricky with the transition between managed and unmanaged code. Finally, syscall numbers change frequently and have to be customized for the platform you’re targeting. D/Invoke seems to handle several of these issues rather elegantly, so I’m excited to dig into those more soon.

Rubeus to Ccache

17 May 2020 at 15:20

Rubeus to Ccache

I wrote a new little tool called RubeusToCcache recently to handle a use case I come across often: converting the Rubeus output of Base64-encoded Kerberos tickets into .ccache files for use with Impacket.

Background

If you’ve done any network penetration testing, red teaming, or Hack The Box/CTFs, you’ve probably come across Rubeus. It’s a fantastic tool for all things Kerebos, especially when it comes to tickets and Pass The Ticket/Overpass The Hash attacks. One of the most commonly used features of Rubeus is the ability to request/dump TGTs and use them in different contexts in Rubeus or with other tools. Normally Rubeus outputs the tickets in Base64-encoded .kirbi format, .kirbi being the type of file commonly used by Mimikatz. The Base64 encoding make it very easy to copy and paste and generally make use of the TGT in different ways.

You can also use acquired tickets with another excellent toolset, Impacket. Many of the Impacket tools can use Kerberos authentication via a TGT, which is incredibly useful in a lot of different contexts, such as pivoting through a compromised host so you can Stay Off the Land. Only one problem: Impacket tools use the .ccache file format to represent Kerberos tickets. Not to worry though, because Zer1t0 wrote ticket_converter.py (included with Impacket), which allows you to convert .kirbi files directly into .ccache files. Problem solved, right?

Rubeus To Ccache

Mostly solved, because there’s still the fact that Rubeus spits out .kirbi files Base64 encoded. Is it hard or time-consuming to do a simple little [System.Text.Encoding]::UTF8.GetString([System.Convert]::FromBase64String($base64RubeusTGT)) to get a .kirbi and then use ticket_converter.py? Not at all, but it’s still an extra step that gets repeated over and over, making it ripe for a little automation. Hence Rubeus to Ccache.

You pass it the Base64-encoded blob Rubeus gives you, along with a file name for a .kirbi file and a .ccache file, and you get a fresh ticket in both formats, ready for Impacket. To use the .ccache file, make sure to set the appropriate environment variable: export KRB5CCNAME=shiny_new_ticket.ccache. Then you can use most Impacket tools like this: wmiexec.py domain/[email protected] -k -no-pass, where the -k flag indicates the use of Kerberos tickets for authentication.

Usage

╦═╗┬ ┬┌┐ ┌─┐┬ ┬┌─┐  ┌┬┐┌─┐  ╔═╗┌─┐┌─┐┌─┐┬ ┬┌─┐
╠╦╝│ │├┴┐├┤ │ │└─┐   │ │ │  ║  │  ├─┤│  ├─┤├┤
╩╚═└─┘└─┘└─┘└─┘└─┘   ┴ └─┘  ╚═╝└─┘┴ ┴└─┘┴ ┴└─┘
              By Solomon Sklash
          github.com/SolomonSklash
   Inspired by Zer1t0's ticket_converter.py

usage: rubeustoccache.py [-h] base64_input kirbi ccache

positional arguments:
  base64_input  The Base64-encoded .kirbi, sucha as from Rubeus.
  kirbi         The name of the output file for the decoded .kirbi file.
  ccache        The name of the output file for the ccache file.

optional arguments:
  -h, --help    show this help message and exit

Thanks

Thanks to Zer1t0 and the Impacket project for doing most of the havy lifting.

A Review of the Sektor7 RED TEAM Operator: Malware Development Essentials Course

24 March 2020 at 15:20

A Review of the Sektor7 RED TEAM Operator: Malware Development Essentials Course

Introduction

I recently discovered the Sektor7 RED TEAM Operator: Malware Development Essentials course on 0x00sec and it instantly grabbed my interest. Lately I’ve been working on improving my programming skills, especially in C, on Windows, and in the context of red teaming. This course checked all those boxes, and was on sale for $95 to boot. So I broke out the credit card and purchased the course.

Custom code can be a huge benefit during pentesting and red team operations, and I’ve been trying to level up in that area. I’m a pentester by trade, with a little red teaming thrown in, so this course was right in my wheelhouse. My C is slightly rusty, not having done much with it since college, and almost exclusively on Linux rather than Windows. I wasn’t sure how prepared I would be for the course, but I was willing to try harder and do as much research as I needed to get through it.

Course Overview

The course description reads like this:

It will teach you how to develop your own custom malware for latest Microsoft Windows 10. And by custom malware we mean building a dropper for any payload you want (Metasploit meterpreter, Empire or Cobalt Strike beacons, etc.), injecting your shellcodes into remote processes, creating trojan horses (backdooring existing software) and bypassing Windows Defender AV.

It’s aimed at pentesters, red teamers, and blue teamers wanting to learn the details of offensive malware. It covers a range of topics aimed at developing and delivering a payload via a dropper file, using a variety of mechanisms to encrypt, encode, or obfuscate different elements of the executable. From the course page the topics include:

  • What is malware development
  • What is PE file structure
  • Where to store your payload inside PE
  • How to encode and encrypt payloads
  • How and why obfuscate function calls
  • How to backdoor programs
  • How to inject your code into remote processes

RTO: Malware Development Essentials covers the above with 9 different modules, starting with the basics of the PE file structure, ending with combining all the techniques taught to create a dropper executable that evades Windows Defender while injecting a shellcode payload into another process.

The course is delivered via a content platform called Podia, which allows streaming of the course videos and access to code samples and the included pre-configured Windows virtual machine for compiling and testing code. Podia worked quite well, and the provided code was clear, comprehensive, well-commented, and designed to be reusable later to create your own executables.

Module 1: Intro and Setup

The intro and setup module covers a quick into to the course and getting access to the excellent sample code and a virtual machine OVA image that contains a development environment, debugger, and tools like PEBear. I really like that the VM was provided, as it made jumping in and following along effortless, as well as saving time creating a development environment.

Module 2: Portable Executable

This module covers the Portable Executable (PE) format, how it is structured, and where things like code and data reside within it. It introduces PEBear, a tool for exploring PE files I’d not used before. It also covers the differences between executables and DLLs on Windows.

Module 3: Droppers

The dropper module covers how and where to store payload shellcode within a PE, using the .text, .data, and .rsrc sections. It also covers including external resources and compiling them into the final .exe.

Module 4: Obfuscation and Hiding

Obfuscation and hiding was one of my favorite modules. Anyone that has had their shellcode or implants caught will appreciate knowing how to use AES and XOR to encrypt payloads, and how to dynamically decrypt them at runtime to prevent static analysis. I also learned a lot about Windows and the Windows API through the sections on dynamically resolving functions and function call obfuscation.

Module 5: Backdoors and Trojans

This section covered code caves, hiding data within a PE, and how to backdoor an existing executable with a payload. x64dbg debugger is used extensively to examine a binary, find space for a payload, and ensure that the existing binary still functions normally. Already knowing assembly helped me here, but it’s explained well enough for those with little to no assembly knowledge to follow along.

Module 6: Code Injection

I learned a ton from this section, and it really clarified my knowledge of process injection, including within a process, between processes, and using a DLL. VirtualAllocEx, WriteProcessMemory, and CreateRemoteThread are more than just some function names involving process injection to me now.

Module 7: Extras

This module covered the differences between GUI and console programs on Windows, and how to ensure the dreaded black console window does not appear when your payload is executed.

Module 8: Combined Project

This was the culmination of the course, where you are walked through combining all the individual techniques and tools you learned throughout the course into a single executable. I suggest watching it and then doing it yourself independently to really internalize the material.

Module 9: Assignment

The last module is an assignment, which asks you to take what you’ve learned in the combined project and more fully implement some of the techniques, as well as providing some suggestions for real-world applications of the course content you can try by yourself.

Takeaways

I learned a heck of a lot from this course. It was not particularly long, but it covered the topics thoroughly and gave me a good base to build from. I can’t remember a course where I learned so much in so little time. Not only did I learn what was intended by the course, but there were a lot of ancillary things I picked up along the way that weren’t explicitly covered.

C on Windows

I found the course to be a good introduction to C on Windows, assuming you are already familiar with C. It’s not a beginning C programming course by any means. Most of my experience with C has been on Linux with gcc, and the course provided practical examples of how to write C on Windows, how to use MSDN effectively, how to structure programs, and how to interact with DLLs. I was familiar with many of the topics at a high level, but there’s no substitute for digging in and writing code.

Intro to the Windows API

I also learned a great deal on how the Windows API works and how to interact with it. The section on resolving functions manually was especially good. I have a much stronger grasp of how Windows presents different functionalities, and how to lookup functions and APIs on MSDN to incorporate them into my own code.

Making Windows Concepts Concrete

As mentioned above, there were a lot of areas I knew about at a high level, like process injection, DLLs, the Import Address Table, even some Windows APIs like WriteProcessMemory and CreateRemoteThread. But once I looked up their function signatures on MSDN, called them myself, created my own DLLs, and obfuscated the IAT, I had a much more concrete understanding of each topic, and I feel much more prepared to write my own tools in the future using what I’ve learned.

A Framework For Building Your Own Payloads

The way the course built from small functions and examples, all meant to be reused and built upon, really made the course worthwhile and feel like an investment I could take advantage of later in my own tools. I’ve already managed to craft a dropper that executes a staged Cobalt Strike payload that evades Windows Defender. How’s that for a practical hands-on course?

No Certification Exam

The course is not preparation for or in any way associated with a certification exam, which in this case I think is a good thing. The course presents fundamental knowledge that is immensely useful in offensive security, and I think it’s best learned for its own sake rather than to add more letters after your name. I like certifications in general and have several, but I found myself not worried about covering the material for an exam and enjoyed learning the material and thinking of practical applications of it at work and in CTFs, Hack The Box, etc. instead. It’s a nice feeling.

Conclusion

I loved this course, and reenz0h is a phenomenal instructor. If it’s not been obvious so far, I’ve gained a lot of fascinating and practical knowledge that will be useful far into the future. My recommendation: take this course if you can. It’s affordable, not an excessive time commitment, and worth every second and penny you spend on it. And just in case my enthusiasm comes across as excessive or shilling, I have no association with Sektor7, their employees, or the authors of the course. Just a happy pentester with some new skills.

Updates to Chomp Scan

3 March 2019 at 16:20

Updates To Chomp Scan

I’ve been pretty busy working on updates to Chomp Scan. Currently it is at version 4.1. I’ve added new tools, an install script, a new scanning phase, a CLI mode, plus bug fixes and more.

What’s Changed

Quite a bit! Here’s a list:

New CLI

I’ve added a fully-functional CLI interface to Chomp Scan. You can select your scanning phases, wordlists, output directory, and more. See -h for help and the full range of options and flags.

Install Script

I’ve created an installation script that will install all dependencies and install Golang. It supports Debian 9, Ubuntu 18.04, and Kali. Simply run the installer.sh script, source ~/.profile, and Chomp Scan is ready to run.

New Scanning Phase

I’ve added a new scanning phase: Information Gathering. Like the others, it is optional, consisting of subjack, bfac, whatweb, wafw00f, and nikto.

New Tools: dirsearch and wafw00f

Upon request, I’ve added dirsearch to the Content Discovery phase. Currently it uses php, asp, and aspx as file extensions. I’ve also added wafw00f to the Information Gathering phase.

Output Files

There are now three total output files that result from Chomp Scan. They are all_discovered_ips.txt, all_discovered_domains.txt, and all_resolved_domains.txt. The first two are simply lists of all the unique IPs and domains that were found as a result of all the tools that Chomp Scan runs. Not all maybe relevant, as some domains may not resolve, some IPs may point to CDNs or 3rd parties, etc. They are included for completeness, and the domains especially are useful for keeping an eye on in case they become resolvable in the future.

The third output file, all_resolved_domains.txt, is new, and the most important. It contains all the domains that resolve to an IP address, courtesy of massdns. This list is now passed to the Content Discovery and Information Gathering phases. As the file only contains valid resolvable domains, false positive are reduced and scan time is shortened.

Introducing Chomp Scan

22 February 2019 at 16:20

Introducing Chomp Scan

Today I am introducing Chomp Scan, a pipeline of tools used to run various reconnaissance tools helpful for bug bounty hunting and penetration testing.

Why Chomp Scan?

The more I’ve gotten into bug bounty hunting, the more I’ve found times where managing all the different scanning tools, their flags, wordlists, and output directories becomes a chore. Recon is a vital aspect of bug hunting and penetration testing, but it’s also largely repetitive and tool-based, which makes it ripe for automation. I found I was contantly running the same tools with similar flags over and over, and frequently in the same order. That’s where Chomp Scan comes in.

I’ve written it so that all tool output is contained in a time-stamped directory, based on the target domain. This way it’s easy to go back and find certain outputs or grep for specific strings. As a pentester or bounty hunter, familiarity with your tools is essential, so I include all the flags, arguments, parameters, and wordlists that are being used with each command. If you need to make a change or tweak a flag, the code is (hopefully) commented well enough to make it easy to do.

A neat feature I’ve included is a list of words called interesting.txt. It contains a lot of words and subdomain fragments that are likely to be of interest to a pentester or bug hunter, such as test, dev, uat, internal, etc. Whenever a domain is discovered that contains one of these interesting words, it is flagged, displayed in the console, and added to a list. That list can then be focused on by later scanning stages, allowing you to identify and spend your valuable time on the most high value targets. Of course interesting.txt is customizable, so if you have a specific keyword or subdomain you’re looking for, you can add it.

Scanning Phases

Chomp Scan has 4 different phases of scanning. Each utilizes one or more tools, and can optionally be skipped for a shorter total scan runtime.

  • Subdomain Discovery (3 different sized wordlists)
  • Screenshots
  • Port Scanning
  • Content Discovery (4 different sized wordlists)

In The Future

Chomp Scan is still in active development, as I use it myself for bug hunting, so I intend to continue adding new features and tools as I come across them. New tool suggestions, feedback, and pull requests are all welcomed. Here is a short list of potential additions I’m considering:

  • A non-interactive mode, where certain defaults are selected so the scan can be run and forget
  • Adding a config file, for more granular customization of tools and parameters
  • A possible Python re-write, with a pure CLI mode (and maybe a Go re-write after that!)
  • The generation of an HTML report, similar to what aquatone provides

Tools

Chomp Scan depends on the following list of tools. Several are available in the default Kali Linux repos, and most are otherwise simple to install, especially if you already have a Go installation.

How To Get It

Visit the Chomp Scan Github repository for download and installation instructions.

alt text

alt text

alt text

alt text

❌
❌