Trustwave Unveils New Offerings to Maximize Value of Microsoft Security Investments. Learn More

Trustwave Unveils New Offerings to Maximize Value of Microsoft Security Investments. Learn More

Managed Detection & Response

Eliminate active threats with 24/7 threat detection, investigation, and response.

Co-Managed SOC (SIEM)

Maximize your SIEM investment, stop alert fatigue, and enhance your team with hybrid security operations support.

Advisory & Diagnostics

Advance your cybersecurity program and get expert guidance where you need it most.

Penetration Testing

Test your physical locations and IT infrastructure to shore up weaknesses before exploitation.

Database Security

Prevent unauthorized access and exceed compliance requirements.

Email Security

Stop email threats others miss and secure your organization against the #1 ransomware attack vector.

Digital Forensics & Incident Response

Prepare for the inevitable with 24/7 global breach response in-region and available on-site.

Firewall & Technology Management

Mitigate risk of a cyberattack with 24/7 incident and health monitoring and the latest threat intelligence.

Offensive Security
Solutions to maximize your security ROI
Microsoft Exchange Server Attacks
Stay protected against emerging threats
Rapidly Secure New Environments
Security for rapid response situations
Securing the Cloud
Safely navigate and stay protected
Securing the IoT Landscape
Test, monitor and secure network objects
Why Trustwave
About Us
Awards and Accolades
Trustwave SpiderLabs Team
Trustwave Fusion Security Operations Platform
Trustwave Security Colony
Technology Alliance Partners
Key alliances who align and support our ecosystem of security offerings
Trustwave PartnerOne Program
Join forces with Trustwave to protect against the most advance cybersecurity threats
SpiderLabs Blog

thicknet: Griefing Boss Hogg

Most things I do seem really awesome at the time. Like the time I was at the Italian restaurant with my wife, and I made her a heart out of spaghetti. Or that time that I jumped onto the Chicago subway right as the doors were closing and then sang the Indiana Jones theme song with the crazy guy all the way to O'Hare. Or that time I jumped off the roof.

But it never fails that time and familiarity erodes the awesomeness of these feats. I've been trying to peel the "Hang Ten" sticker off of my stereo cabinet for years. And in retrospect, the macaroni aorta was definitely a bit over the top.

In a way, the same can be said for thicknet. As great as that thing is, calling it a "framework" turned out to be a bit of a stretch. It's kind of like hiring the Dukes of Hazzard as our own personal security force. They'll do anything we want, as long as it's something in Hazzard County and it involves griefing Boss Hogg (or in our case, Oracle). If you start talking to Bo and Luke about Microsoft SQL TDS, Uncle Jesse would probably get in his truck and chase us into the next episode. I think we're starting to outgrow this analogy.


After getting accepted to the excellent BSidesCLE (they apparently fill the 2pm slot according to Pop-O-Matic Bubble) I found myself in need of a new thicknet module. After agonizing between Microsoft SQL and CC:Mail for Netware 3.12 for awhile (also decided via Pop-O-Matic), I set to work on MSSQL's TDS protocol. And wow, after taking apart Net8, TDS seems like a bedtime story. This was going to be easy.


Except that Bo and Luke can't leave Hazzard County:

thicknet::pcap::Oracle::inject($sessions{$context}, $input);

Now I finally understand this whole object-oriented thing that you computer science people are always going on about. I want to create a new module that does a lot of what the old module does, but has some key differences. Plus, I need to be able to say "inject" to whatever session I want and have it magically do the right thing. You tricky kids, with your classes and objects and FM radio.

Fine, let's sell out to the man and start making objects. thicknet now has three types:

  • Pcap objects – these are responsible for grabbing packets off the wire. They use them to create …
  • Packet objects, which are processed and broken up into readily available properties such as "src_ip" and "src_port". These are used to feed …
  • Session objects, which track actual TCP conversations. Session objects are in charge of things like injection, and ACK-ing packets when we go into injection mode.

    Now when the main script wants to inject, we can simply tell the session to do so:


    Cooter would be proud indeed.

    So now that the college profs are off our back, it's time to play with TDS, the official fuzzy protocol mascot of Microsoft SQL. There's a really great document here that explains the whole thing:

    Other than some header info, it's almost like taking what you type on the command line and shoving it into a packet. Here's an example of a simple query (taken from Microsoft SQL Server 2008):


    Starting at 0x0020, the play-by-play details:

    01 – Type = SQL Batch. Generic construct for sending SQL messages.

    01 – Status = End of Message. This is the last packet in this request.

    0056 – Length. Size of the packet including 8 byte packet header.

    0000 – SPID / Server Process ID. Can be specified by client, but not required or common to do so.

    01 – Packet ID. Just set this to 01, it's for future functionality to track a sequence of TDS packets but is currently ignored according to the spec.

    00 – Window. Also reserved for future use, set to 00.

    And now we get into the data headers:

    16 00 00 00 – Total Length of Data Headers. Bytes from here to SQL command.

    12 00 00 00 – Header Length. Bytes from here to SQL command. We only have one header so it's a little redundant with the "Total Length".

    02 00 – Header Type. 01 is Query Notifications, 02 is a Transaction Descriptor, which we're using to do the query.

    00 00 00 00 00 00 00 01 – MARS Transaction Descriptor. Multiple Active Result Sets has been around since Microsoft SQL 2005, and is a way to feed multiple requests into a session without waiting for the results. We can set this to 01 for now (but should probably make a non-MARS version for older versions of the database)

    00 00 00 – Outstanding request count. How many outstanding MARS requests we have, in this case none. (Oddly, in the spec this is 4 bytes, but I've been seeing 3 in actual MSSQL traffic)

    Then we have the actual payload, which is encoded using UCS-2 Little-Endian. That's a fancy way of saying multi-byte encoding with the little number in the front, which is also a fancy way of saying that you put a 00 after your ASCII characters. It's a bit more complex than that if you want to use international symbols, or Funny Letters as they like to say where I grew up. (In my neighborhood you could get punched in the face for saying things like "umlaut")

    The great thing about this whole setup is that we don't have any session-specific blobs of data. Unlike Oracle Net8, where we had a bunch of stuff going on that we didn't understand, we can pretty much build these payloads from scratch and sit them on top of our L3-L4 sled. It's also nice to have the actual spec in front of us, but even if we didn't, we could just fake it using a sled like we did in Net8 land.

    So now, using the Session class as a base, we can create our own injection logic that creates the payload and adds our text accordingly. Here's the code from thicknet/session/

    my $str = encode("UCS-2LE", $cmd);
    my $len = length($str) + 30;
    my $data = pack('C*',0x01,0x01,0x00,$len,0x00,0x00,0x01,0x00,0x16,0x00,0x00,0x00,0x12,0x00,0x00,0x00,0x02,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x01,0x00,0x00,0x00);
    $data = $data . $str;

    Don't freak out about the hex, you have the cheat sheet a few paragraphs up. Both the TDS header and the data header can be completely static except for the data length, which we populate with $len. Once created, we call pcap_sendpacket, and it's off to the races. We also have to own the TCP session at this point, but that's old hat since last time.

    Here's the new MSSQL module in action. Notice that we don't see any visible disruption in SQL Management Studio. Database "studio" apps like this one frequently maintain a connection pool to speed the process of performing queries. Sometimes the database times out these connections, so it's a common occurrence for the application to open another connection without thinking twice. This design aspect is great for us, since it allows us to grab a connection without freaking out the user.

    The overarching moral of the story remains the same as always: encrypt your database communications. thicknet will fall flat on its smug face if it tries to inject into an encrypted stream. Microsoft offers good options here, so it's definitely worth a look:

    But enough of this cautionary stuff, there's a whole world outside of Hazzard County just waiting for you. You, with your object-oriented thicknet and your crazy sleds with the doors welded shut. The cipher might get you, but the creds never will.

Latest SpiderLabs Blogs

Search & Spoof: Abuse of Windows Search to Redirect to Malware

Trustwave SpiderLabs has detected a sophisticated malware campaign that leverages the Windows search functionality embedded in HTML code to deploy malware. We found the threat actors utilizing a...

Read More

The Sentinel’s Watch: Building a Security Reporting Framework

Imagine being on shift as the guard of a fortress. Your job is to identify threats as they approach the perimeter. The more methods you have for detecting those threats, the better your chances of...

Read More

Fake Advanced IP Scanner Installer Delivers Dangerous CobaltStrike Backdoor

During a recent client investigation, Trustwave SpiderLabs found a malicious version of the Advanced IP Scanner installer, which contained a backdoored DLL module. Our client had been searching for...

Read More