I Know What You Shipped Last Summer - RCE, SQLi and More in Logistics Software e-TMS
During an external penetration test for one of our clients we stumbled upon their e-TMS instance. e-TMS is a transportation management software developed by Andsoft with a lot of features such as management of transport orders, transport organization, tracking, invoicing and many more. We found several critical vulnerabilities such as multiple remote code executions, sql injections (paired with md5 hashed passwords…), a file read and reflected cross-site scripting - all unauthenticated! In fact, we did not test the authenticated part of e-TMS. According to Andsoft’s website, it is used by many large companies in the logistics sector, the largest of which has up to 41,000 employees and a revenue of 8.2 billion euros. During the penetration test, we identified 42 publicly exposed e-TMS instances, all susceptible to the discovered vulnerabilities.
Overview of the CVEs
While we requested only one CVE for each vulnerability type (=5 in total), the Spanish CNA INCIBE insisted on issuing one CVE for each occurrence of a vulnerability, resulting in a total of 40 CVEs. The vulnerabilities were found in v15.12 of e-TMS, and the client confirmed that their other instance with v25.03 (the latest as of January 2025) was also vulnerable to them.
CVE Number | Name | Severity |
---|---|---|
CVE-2025-59735 - CVE-2025-59741 | Unauthenticated Remote Code Execution | Critical |
CVE-2025-59742 - CVE-2025-59743 | Unauthenticated SQL Injection | Critical |
CVE-2025-59744 | Unauthenticated File Read | High |
CVE-2025-59746 - CVE-2025-59774 | Reflected Cross-Site Scripting | Medium |
CVE-2025-59745 | Insecure Password Hashing (md5) | Medium |
The advisory of INCIBE can be seen here.
Remediation
The critical vulnerabilities have been fixed by Andsoft in our clients’ instances. However, we have no information whether Andsoft has fixed them in the other clients’ instances, nor if there is an official version in which they have been fixed. In fact, the other vulnerabilities (Unauthenticated File Read, Reflected Cross-Site Scripting, Insecure Password Hashing) have still not been fixed in our clients’ instances as of 01/05/2025. Andsoft has not responded to our emails or to the Spanish national CNA INCIBE.
We have only examined the unauthenticated part of e-TMS. However, a quick look at the source code of the authenticated pages indicated that the situation there was even worse. It should therefore be carefully checked who has access to e-TMS and accounts that are no longer required should be removed. Furthermore, all users should be encouraged to set a strong and unique password so that attackers cannot gain access to the authenticated part via weak passwords.
Ideally, e-TMS should not be publicly accessible on the internet in order to reduce the attack surface until the serious vulnerabilities in the authenticated and, above all, unauthenticated part of e-TMS have been eliminated.
CVEs in Detail
Unauthenticated Remote Code Execution
One of the scanners we used (Dalfox) reported an XSS vulnerability (see Reflected Cross-Site Scripting) in the login page /clt/loginfrm.asp
. While inspecting the vulnerable body parameter M
, we noticed an interesting error message if M
contained, for example, a "
.
Even without any knowledge of French, we could clearly see that it was a Microsoft Visual Basic script error message stating that a string was not closed properly. This was already a good indicator that we had an unauthenticated remote code execution. Exploiting it required a bit of tinkering, as we are not that familiar with classic ASP and VB Script, as both are legacy and long deprecated.
Eventually, we came up with the payload 1 & Execute("Set shell=CreateObject(""WScript.Shell""):Set exec=shell.Exec(""cmd.exe /c whoami & cd & hostname""):Response.Write(exec.StdOut.ReadAll)")
which allowed us to execute arbitrary commands and write their output to the response.
Further, we have created payloads to
- list all subdirectories in a directory
1 & Execute("Sub ListSubfolders(folderPath):Set fso=CreateObject(""Scripting.FileSystemObject""):Set folder=fso.GetFolder(folderPath):For Each subFolder In folder.SubFolders:Response.Write(subFolder.Path & ""<br>""):Response.Flush:Next:End Sub:ListSubfolders ""\\x.x.x.x\Inetpub\ANDSYS_WIN\""")
- dump all files in a directory
1 & Execute("Set fso=CreateObject(""Scripting.FileSystemObject""):Set folder=fso.GetFolder(""\\x.x.x.x\Inetpub\ANDSYS_WIN\clt\""):For Each file In folder.Files: Set f=fso.OpenTextFile(file.Path,1):Response.Write(file.Name & ""<br>"" & f.ReadAll & ""<hr>""):f.Close:Response.Flush:Next")
This allowed us to dump the source code directory by directory without having to deal with the client’s EDR.
And, oh boy, was the source code a gold mine. Keep in mind that we were contracted for an external penetration test with a time constraint of ~1.5 hours per server. However, in order to dig for more gold, we decided to invest some of our slack time in exploring the source code, which resulted in the discovery of more critical vulnerabilities. We limited our scope to the unauthenticated portion of the web application, otherwise it would have been a bottomless pit.
In fact, there was not only the login page /clt/loginfrm.asp
but a total of 25!
And many of them were vulnerable to the same RCE. It appears that some clients received a personalized login page with a hardcoded image of the client’s logo. Other than that, the code was identical. For some reason, the personalized login forms were delivered to all e-TMS clients.
So let’s take a look at the vulnerable code in /clt/loginfrm.asp
to see how the RCE was made possible.
Disclaimer: For legal reasons, we will not show any of the original source code. Therefore, we have mocked the vulnerable code using node.js. A positive side effect is that most of you are probably more familiar with JavaScript than VB Script anyway.
Well, that’s straightforward. It takes the value of the body parameter M
and calls eval
on it. The eval
in VB Script behaves much like the eval in JavaScript: It takes a string and evaluates it as code…
After a lot of back and forth, with our client being the man in the middle during the communication with Andsoft, they finally fixed it by changing the line containing the eval to strError = "LOGIN ERROR"
. This will only return a generic error message - without using eval.
While looking for the use of more evals in the unauthenticated parts of the web application, we stumbled upon /CLT/LOGINERRORFRM.ASP
.
Almost the same vulnerability with the only difference that M
is a query parameter instead of a body parameter.
Unauthenticated SQL Injection
Two SQL Injections have been found in the unauthenticated part of e-TMS.
The first one affects the /CLT/track_request.asp
page.
While the default form presented is not vulnerable to SQLi, the form presented if the query parameter forgot=1
is set is vulnerable.
This sends the following request to /inc/login/TRACK_REQUESTFRMSQL.ASP?FORGOT=1
, which results in an SQL error message.
This error-based SQLi could be easily exploited using sqlmap to dump, among other things, the hashed passwords of the users. This revealed that the passwords were only md5 hashed (see Insecure Password Hashing (md5)).
But let’s have a look at the source code:
The query parameter FORGOT
must have any value. This brings us to the part of the code where a SQL query is constructed. The body parameter USRMAIL
is embedded directly into the SQL query without any validation or sanitization - leading to SQL injection.
Although the code contains a function to sanitize untrusted data for SQL queries, it is not used in many places, such as here.
The second SQLi concerns /inc/connect/CONNECTION.ASP
.
The cookie SessionID
seems to be insecurely embedded in a SQL query. Let’s have a look at the source code:
The reason is similar to the first SQLi. request.cookies("SessionID")
is passed directly to the SQL query and not to ToSqlVarcharQuote
first.
Unauthenticated File Read
e-TMS has a page (lib/asp/DOCSAVEASASP.ASP
) that returns the content of any file in the webroot. No authentication required.
DOCURL
specifies the target file and can be either a query or a body parameter. In particular, the configuration file of e-TMS, which contains SQL and Active Directory credentials, as well as API keys, is a high value target. However, we will not disclose it’s name or path :)
Reflected Cross-Site Scripting
Well, cross-site scripting (XSS) seems to be a big problem. Every page available to unauthenticated users was vulnerable to XSS.
/CLT/LOGINFRM.asp
,/clt/LOGINFRM_DJO.ASP
,/clt/LOGINFRM_LXA.ASP
,/clt/LOGINFRM_BET.ASP
,/clt/LOGINFRM_original.ASP
,/clt/LOGINFRM_CAT.ASP
: Query parametersl
,demo
,demo2
,TNTLOGIN
,UO
andSuppConn
/lib/asp/alert.asp
: Query parameterM
/clt/resetPassword.asp
: Query parameterL
/CLT/changepassword.ASP
: Query parametersReset
andL
/CLT/TRACK_REQUEST.ASP
: Query parametersforgot
andL
Here is a simple PoC (/clt/loginfrm.asp?l="><svg/onload="alert(%27still%20not%20fixed%27)">
) to illustrate this:
Insecure Password Hashing (md5)
The Unauthenticated SQL Injection was exploited to dump the user table. This revealed that the passwords were simply hashed using the insecure md5 hashing algorithm. Thus, most of the passwords could be cracked without any effort. Let’s take a look at the encrypt
function:
While e-TMS seems to support both MD5 and SHA256 as hashing algorithms, the SHA256 case cannot be reached because it is hardcoded to use MD5
.
Timeline
2025-01-06 | Start of the external penetration test |
2025-01-13 | Reported RCEs and SQLis to our client |
2025-01-16 | End of the external penetration test |
2025-01-17 | Attempt #1 to contact the vendor - no response |
2025-01-27 | Delivered the penetration test report to our client |
2025-01-27 | Attempt #2 to contact the vendor - no response |
2025-02-26 | Requested CVEs with INCIBE as CNA |
2025-04-25 | Asked INCIBE for a status update - the vendor did not respond to them |
2025-09-19 | CVEs were published |