shellcode编写
- 这里详细介绍一下shellcode可以怎么生成,怎么编写
介绍
-
shellcode
:是一段专门为利用计算机安全漏洞而编写的机器码,通常是为了在目标系统上执行命令或启动一个新的 shell(因此得名 “shellcode”)。 -
在一开始没有汇编基础的时候可以先使用
pwntools
内置的自动生成shellcode的脚本进行编写,然后直接发送,这样就可以getshell。但是这毕竟是脚本生成的东西,在一些题中对shellcode没有限制的情况下还是能使用的。 -
如果在一些shellcode被限制的情况下就没办法使用脚本生成了,这个时候就需要自己编写脚本了
基础
pwntools生成
- pwntools有自带的生成shellcode的工具,生成的代码格式如下,了解该代码就可以进行实战。做出题目level_1_shellcode
- 在使用pwntools生成shellcode的时候注意以下问题
- 请使用虚拟机执行该脚本,而不要使用windows上的Pycharm工具,因为可能没有汇编器
- 在
wsl
或者VM
的虚拟机上运行,确保有汇编器,如果没有使用该指令安装sudo apt install binutils
1 | context.arch = 'i386' # 指定cpu架构, |
编写shellcode
- 通常编写shellcode并不是直接写汇编代码
- 通常采用内联汇编的形式。什么是内联汇编:内联汇编可以直接理解为在C代码中嵌入汇编代码。注意并不是所有编译器都支持这么做。但GCC支持在C代码中直接嵌入汇编代码
- 内联汇编的关键字为
asm
,里面汇编代码的形式采用AT&T
的汇编格式而不是采用Intel
的汇编格式。内联汇编的规定如下- 指令必须用双引号引起来,无论双引号中是一条指令或多条指令
- 一对双引号不能跨行,如果跨行需要在结尾用反斜杠
\
转义。 - 指令之间用分号
;
换行符\n
或换行符加制表符\n \t
分隔。 - 寄存器前面加前缀%,立即数前面加前缀$,操作数由左到右的顺序。
- 接下来对shellcode进行简单编写
level_1_/bin/sh
- 打开ubuntu虚拟机,直接vim创建一个c文件,即可开始编写
- 需要使用
sudo
权限编辑该c文件,刚刚上手写会出现很多错误,问AI慢慢排错
1 |
|
level_2_write
- 使用内联汇编,通过系统调用将
hello world
打印在终端上
1 |
|
level_3_open
- 使用内联汇编打开
flag
文件,先在当前目录下创建一个flag
文件,写入一些内容 - 为了验证flag文件是否被打开,我使用read函数将该文件读到一个字符串中,并打印出来;
1 |
|
level_4_read
- 使用内联汇编写入
aaaa
到指定字符串上
1 |
|
level_5_orw
- 使用内联汇编通过系统调用,打开
flag
文件,读取flag
文件到指定字符串上,打印出flag
文件里面的内容
1 |
|
题目
level_1_shellcode
-
题目来源:PolarD&N (polarctf.com),pwn简单题部分,
Easy_Shellcode
-
下载:https://wwsq.lanzoue.com/i7vjd29q8aef 密码:b72p
-
前置知识:学会ret2text就可以了
-
拿到题目附件发现就一个
ELF
文件,先检查保护机制- 发现是
i386
架构 - 然后保护都没开
- Stack: Executable:这个是栈可执行,一般来说栈上的数据可读可写的,但是并不能做为代码执行。
- RWX: Has RWX segments:这个是程序段具有可读、可写、可执行的权限,一般不同部分的程序段权限是不一样的,比如bss段一般是只有可读可写不可执行的权限。本题只是比较简单的shellcode题目,所以权限没有设置很死,或者很宰
- 发现是
分析
-
使用IDA打开这个32位文件
-
先从
main
函数开始看,发现main
函数没有什么东西,只有一个init
初始化和start
函数,那么主要看start
函数
- 进入start函数,查看一下代码,发现有两个输入点,一个是向
str
输入0x100
,str
的地址位于.bss
段
-
还有一个是向栈上的buf输入0x100字节,但是buf的长度达不到0x100所以存在栈溢出
-
这时我们可以将shellcode注入到
str
中,然后使用ret
返回到str处,执行shellcode,即可得到shellcode。其实这题也可以当做ret2libc
来写。 -
结合前面使用pwntools生成的shellcode,可以直接得到shellcode
1 | from pwn import * |
- 这时变量a就是一串由汇编代码组成的字节码
1 | a = b'jhh///sh/bin\x89\xe3h\x01\x01\x01\x01\x814$ri\x01\x011\xc9Qj\x04Y\x01\xe1Q\x89\xe11\xd2j\x0bX\xcd\x80' |
- 剩下的就是接收发送问题了
利用
- 这里利用的时段可执行权限,写入shellcode,然后再返回到shellcode地址,执行shellcode
- exp:
1 | from pwn import * |
- 这题看完可以打一题试试PolarD&N (polarctf.com),pwn简单题
play
和name4
、shellcode1
本博客所有文章除特别声明外,均采用 CC BY-NC-SA 4.0 许可协议。转载请注明来自 iyheart的博客!
评论