pwn入门-shellcode详解
pwn入门-shellcode详解
shellcode详解
shellcode通常是软件漏洞利用过程中使用一小段机器代码
作用:
- 启动shell,进行交互
- 打开服务器端口等待连接
- 反向连接端口
- …
shellcode:
1 | //gcc -m32 -o shell shell.c |
gdb shell
r n
我们并不知道system的地址
第一,直接生成的shell代码比较大
第二,不能调用系统函数
触发中断(int 0x80或者syscall),进行系统调用。
system(“/bin/sh”)底层是调用execve(“/bin/sh”,0,0)
完整的syscall调用表:https://publicki.top/syscall.html
32位shellcode编写
设置ebx指向/bin/sh
ecx=0,edx=0
eax=0xb
lnt0x80触发中断调用
1 | ;;nasm -f elf32 i386.asm |
64位:
1 | ;;nasm -f elf64 x64.asm |
1 | push "/sh" ; 将字符串 "/sh" 压入栈中 |
在 execve
系统调用中:
1 | int execve(const char *filename, char *const argv[], char *const envp[]); |
filename
(对应 ebx
):要执行的程序路径
argv
(对应 ecx
):参数列表
envp
(对应 edx
):环境变量
1 | mov al, 0xb ; 将 al 设置为 0xb (syscall号) |
int 0x80 ; 触发中断,调用内核执行系统调用
当程序执行 int 0x80
时,CPU 切换到内核态,并将控制权交给内核中的系统调用处理程序。
eax 中的值决定了要调用哪个系统调用。
在这段代码中:eax = 0xb
→ 调用 execve
系统调用。
自己写的不能输入00字符
快速生成shellcode
使用pwntools快速生成对应架构的shellcode
设置目标架构
生成shellcode
32位:
1 | from pwn import* |
1 | /* execve(path='/bin///sh', argv=['sh'], envp=0) */ |
64位:
1 | from pwn import* |
例题mrctf2020_shellcode
查看保护
查看哪些段是可读可写可执行,先调试
IDA打开
read上面的三个mov是进行输入,buf长度,400h,然后和0进行比较,如果小于等于0退出,退出,把地址给rax,然后call rax。
反编译器在静态分析时,无法确定 rax
中的值,因此不知道程序将跳转到哪里。
所以反编译失败
程序逻辑
- 向buf读取0x400字节内容
- 并调用执行读入的内容
把shellcode读入栈直接执行,两种方案,第一种直接手写,第二种用生成的
直接下断点:
1 | from pwn import * |
手写的payload不用p.interactive(),因为在 pwntools
中,p.interactive()
是一个非常重要的方法,用于将当前的程序与用户进行交互,让你可以像在终端中直接操作目标程序一样进行输入和输出,我们手写的那个已经实现了这个功能
执行
这里需要安装tumx
1 | from pwn import * |
- 向程序发送一个包含 Shellcode 的 Payload。
- 如果漏洞被成功利用,程序将打开一个 Shell。
p.interactive()
允许你直接在 Shell 中输入命令
断点之前是下在了11dd这个位置
b *(0x5cb081ff3000+0x11dd)
然后c
切换窗口一直搞不明白ctrl+b然后再输入左右键,需要熟练
左边输入p.send(payload1)
s单步跟入
执行到断点退出
能获得系统调度
例题ciscn_2019_s_9
这里没有直接调用shellcode 使用jmp esp能直接跳转到栈执行,输入一段shellcode,再将Return地址覆盖位jmp esp,离栈顶8h,栈底20h,总长32,加上返回地址长36
(建议先看栈溢出下面就懂了)
1 | from pwn import * |
栈溢出
栈溢出常发生在局部变量中,栈是高地址向低地址延申的,而局部变量又是低地址向高地址延伸的,如果没控制输入长度的话,可以覆盖返回地址
缓冲区溢出(Buffer overflow)
编写程序时没有考虑到控制或者错误控制用户输入的长度,本质就是向定长的缓冲区中写入了超长的数据,造成超出的数据覆写了合法内存区域
栈溢出(Stack overflow)最常见、漏洞比例最高、危害最大的二进制漏洞。在CTF PWN中往往是漏洞利用的基础
堆溢出(Heap overflow)堆管理器复杂,利用花样繁多
CTF PWN中的常见题型,Data段溢出(比如bss段,比较少见)攻击效果依赖于Data段上存放了何种控制数据
例题
没找到例题文件,直接贴个代码吧
1 | from pwn import * |
也可以用senlineafter代替5和6行
脚本解释补充
sendline = send +换行
recvuntil 直到这条语句输出后
p.interactive()取得交互shell
sendafter,接收xx之后再send
b’a*0x18+p64(backdoor)建议都加b
栈溢出补充
来自B站国资社畜栈溢出(一)
返回地址:
注意要看右边然后si
- 看返回地址:0x8049182
- 普通运算
- 生成一个20长度的字符
aaaabaaacaaadaaaeaaa
返回地址被覆盖
由于不能直接输入不可见字符,得用py去打
1 | from pwn import * |