unlink学习笔记
绝大部分内容来自 CTF-WIKI ,内容引用用于学习记录
Unlink原理我们在利用 unlink 所造成的漏洞时,其实就是对 chunk 进行内存布局,然后借助 unlink 操作来达成修改指针的效果。
我们先来简单回顾一下 unlink 的目的与过程,其目的是把一个双向链表中的空闲块拿出来(例如 free 时和目前物理相邻的 free chunk 进行合并)。其基本的过程如下
下面我们首先介绍一下 unlink 最初没有防护时的利用方法,然后介绍目前利用 unlink 的方式。
古老的 unlink在最初 unlink 实现的时候,其实是没有对 chunk 的 size 检查和双向链表检查的,即没有如下检查代码。
12345678910111213// 由于 P 已经在双向链表中,所以有两个地方记录其大小,所以检查一下其大小是否一致(size检查)if (__builtin_expect (chunksize(P) != prev_size (next_chunk(P)), 0)) \ malloc_printerr ("corrupted s ...
2020羊城杯Writeup
Relogin下载附件是一个 pyinstaller 打包的 exe 文件。
反编译 exe使用 pyinstxtractor.py 反编译:
1python pyinstxtractor.py login.exe
或者用 Pyinstaller 中的 \utils\cliutils\archive_viewer.py ,具体方法百度,略有不同
找到目录中同名无后缀文件,修改后缀为 .pyc ,接着再找到 struct 一并复制出来。用 winhex 将 login.pyc 文件还原回来,pyinstaller 会去除这部分信息(python 版本、时间戳)。将 struct 前 8 字节添加到 login.pyc 开头,struct 文件头信息与 login.pyc 编译前一致,直接复制懒得去找对应 python 版本的文件头。
在线网站反编译 pyc 文件得到源码。
逆加密算法15 元 1 次方的方程,用 z3 库解决时,设置变量为 Int 型需要注释有 (a8 << 7) 这一条方程,否则因为变量类型问题无法运算。这时计算结果明显错误,需要添加约束,约束全部 ...
off_by_one
堆中的 Off-By-One
绝大部分内容来自 CTF-WIKI ,内容引用用于学习记录
介绍严格来说 off-by-one 漏洞是一种特殊的溢出漏洞,off-by-one 指程序向缓冲区中写入时,写入的字节数超过了这个缓冲区本身所申请的字节数并且只越界了一个字节。
off-by-one 漏洞原理off-by-one 是指单字节缓冲区溢出,这种漏洞的产生往往与边界验证不严和字符串操作有关,当然也不排除写入的 size 正好就只多了一个字节的情况。其中边界验证不严通常包括
使用循环语句向堆块中写入数据时,循环的次数设置错误(这在 C 语言初学者中很常见)导致多写入了一个字节。
字符串操作不合适
一般来说,单字节溢出被认为是难以利用的,但是因为 Linux 的堆管理机制 ptmalloc 验证的松散性,基于 Linux 堆的 off-by-one 漏洞利用起来并不复杂,并且威力强大。 此外,需要说明的一点是 off-by-one 是可以基于各种缓冲区的,比如栈[^1]、bss 段等等,但是堆上(heap based) 的 off-by-one 是 CTF 中比较常见的。我们这里仅讨论 ...
Python2中input()函数漏洞
函数简介input()函数是python中的内置函数,函数作用是从stdin中读取数据
input() 与 raw_input() 区别python2 两个常见输入函数:input 和 raw_input 。
raw_input() 会将输入的内容转换为字符串:
1234567891011121314151617181920#!/usr/bin/env python# -*- coding: utf-8 -*-a1 = raw_input("字符串:")print type(a1)a2 = raw_input("数字:")print type(a2)a3 = raw_input("变量名:")print type(a3)'''$ python 1.py字符串:skye<type 'str'>数字:2311<type 'str'>变量名:a3<type 'str'>'''
...
2020 CISCN Writeup
Pwnbabyjsk解压后在众多文件夹中的找到 server.py 。内容如下:
12345678910111213141516import sysimport tempfileimport os# Python2中input()函数漏洞size = int(input())assert(size < 1024*1024) #1MB maxscript = sys.stdin.read(size) # reads one byte at a time, similar to getchar()temp = tempfile.mktemp()with open(temp, "w") as f: f.write(script)# os.environ['LD_PRELOAD'] = "./libJavaScriptCore.so.1"cmd = "LD_PRELOAD=/home/ctf/libJavaScriptCore.so.1 /home/ctf/jsc " + tempos.system(cmd) ...
Z3库-多元方程一把梭哈
国赛上逆向有道题目要算 37 元一次方程,肯定不能用手算。解决方法是用 python Z3 库,这个库可以帮助我们解决方程的计算问题。
Z3 在工业应用中实际上常见于软件验证、程序分析等。然而由于功能实在强大,也被用于很多其他领域。CTF 领域来说,能够用约束求解器搞定的问题常见于密码题、二进制逆向、符号执行、Fuzzing 模糊测试等。此外,著名的二进制分析框架 angr 也内置了一个修改版的 Z3。
安装1pip install z3-solver
简单使用123456from z3 import *x = Int('x')y = Int('y')solve(x > 2, y < 10, x + 2*y == 7)# [y = 0, x = 7]
做题约束条件肯定不会这么少,所以需要实例化一个 Solver() 对象,方便我们添加更多的约束条件。
进阶使用Solver 对象创建约束求解器:
1solver = Solver()
设置变量Int - 整数型1234# 声明单个变量x = Int('x')# ...
Chunk Extend/Overlapping | 堆拓展、重叠
堆拓展&溢出
绝大部分内容来自 CTF-WIKI ,内容引用用于学习记录
介绍chunk extend 是堆漏洞的一种常见利用手法,通过 extend 可以实现 chunk overlapping 的效果。这种利用方法需要以下的时机和条件:
程序中存在基于堆的漏洞
漏洞可以控制 chunk header 中的数据
原理chunk extend 技术能够产生的原因在于 ptmalloc 在对堆 chunk 进行操作时使用的各种宏。
在 ptmalloc 中,获取 chunk 块大小的操作如下
12345/* Get size, ignoring use bits */#define chunksize(p) (chunksize_nomask(p) & ~(SIZE_BITS))/* Like chunksize, but do not mask SIZE_BITS. */#define chunksize_nomask(p) ((p)->mchunk_size)
一种是直接获取 chunk 的大小,不忽略掩码部分,另外一种是忽略掩码部分。
在 ptmal ...
Buu刷题记录
wustctf2020_name_your_dog数组下标溢出,修改 got 表
mrctf2020_shellcode_revenge将 shellcode 换个编码,换成用可见字符串组成。
https://blog.csdn.net/weixin_44145820/article/details/105565953
护网杯_2018_gettingstart普通栈溢出,考点是浮点数在内存中怎么用 16 进制表示
浮点数16进制在线转换网站:http://www.binaryconvert.com/result_double.html?decimal=048046049
ciscn_2019_en_3_printf_chk会检测%N$,换个思路泄露寄存器中的 libc 地址
还有注意 buu 上 ubuntu18 绝大部分的环境是旧 glibc 没有 tcache double free 保护
reverse11. PE文件分析用的是 Exeinfo PE 这个软件,吾爱上有分享,爱盘也有收录。
这一步有点类似 pwn 查看程序的版本、保护情况:
64 位的程序。
2. 运行程序获 ...
Blind_pwn之格式化字符串
[scode type=”lblue”]文章首发于合天众智,转载到博客仅作备份[/scode]
可能需要提前了解的知识
格式化字符串原理&利用
got & plt 调用关系
程序的一般启动过程
原理格式化字符串盲打指的是只给出可交互的 ip 地址与端口,不给出对应的 binary 文件来让我们无法通过 IDA 分析,其实这个和 BROP 差不多,不过 BROP 利用的是栈溢出,而这里我们利用的是无限格式化字符串漏洞,把在内存中的程序给dump下来。
一般来说,我们按照如下步骤进行
确定程序的位数(不同位数有些许差别)
确定漏洞位置
利用
使用条件
可以读入 ‘\x00’ 字符的
输出函数均是 ‘\x00’ 截断的
能无限使用格式化字符串漏洞
32 位利用手法实验环境准备程序源码如下:
1234567891011121314151617181920212223242526272829303132333435363738#include <stdio.h> #include <string.h> #include <unistd.h&g ...
劫持64位静态程序fini_array进行ROP攻击
程序起点程序的启动流程如图所示:
可以看到 main 函数不是程序起点,之前写的 格式化字符串盲打 也分析过 text 段起点是 _start 函数 。_start 函数调用__libc_start_main 完成启动和退出工作。具体看看 _start 函数:
12345678910111213141516171819.text:0000000000401A60 public start.text:0000000000401A60 start proc near ; DATA XREF: LOAD:0000000000400018↑o.text:0000000000401A60 ; __unwind {.text:0000000000401A60 xor ebp, ebp.text:0000000000401A62 mov r9, rdx.text:0000000000401A65 p ...