Alex Hanlon Has The Flag & Going in Blind - Square CTF 2022

Square CTF logo.

This past weekend I played SquareCTF 2022 hosted by Block, Inc. with my college team, Psi Beta Rho. I focused mostly on challenges related to web exploitation and was able to solve a couple challenges which I have provided writeups for below. I was certainly suprised to see the amount of web challenges related to SQL Injection (SQLi). The two challenges I solved below demonstrate classic examples of combining error-based investigation and SQLi authentication bypass.


Alex Hanlon Has The Flag!

Prompt for the Square CTF challenge, 'Alex Hanlon Has The Flag!'

I started off by first visiting the provided site at which looked like the following.

Image of Alex Hanlon site.'

Since no source code was provided and aftering examining the client-side source code via “Inspect Element”, I decided to attempt to fuzz some possible inputs (e.g. common passwords). After attempting the following payload below, this resulted in the following error appearing on the site.

' OR 1=1

Demonstrated error after above payload was injected resulting in SQL error.

This revealed several things about the attack target. One, the site was utilizing SQL for user authentication on a server written in Java. Two, it was vulnerable to SQL injection as it did not appear common SQLi characters were flted meaning that a SQLi authentication bypass attack was possible. Three, it returned very informative errors about the particular problems with the injected payload allowing for exploration via error-based SQLi. Based on the above error message, I was able to estimate that the following SQL query is utilized for authentication.

SELECT * FROM user WHERE username='$username' AND password='$password';

For this reason, I attempted to inject the common SQLi payload below. For a great reference, I was able to get some assistance from PayloadsAllTheThings to figure out some potential injections.

' OR 1=1 -- -

The above would affect the SQL query as the following and comment out the rest allowing for an arbitrary user to be authenticated. Note that password is required by the client-side form but in terms of the injection, the value does not matter due to it being commented out.

SELECT * FROM user WHERE username='' OR 1=1 -- -' AND password='$password';

This outputted the following.

Login as admin with the above payload!

We were able to login!!! Just… not as the correct user. Revisting the challenge prompt indicated that we need to log in as “Alex Hanlon”. I decided to start by taking advantage of the error-based investigation part of this challenge and to attempt to find more information about the overall database. After some investigation, I found that this article was incredibly helpful and providing some details and sample payloads I could craft to solve this problem. Started off by using the following payload to find out the name of the various database schemas. “group_concat” was a particularly useful function as this allowed me to produce a singular output field that was required by the error handler and combine multiple entries into one output.

' union select group_concat(schema_name) from information_schema.schemata -- -

This returned the following error.

Sorry, information_schema,performance_schema,appdb is the wrong user

Recognizing that the database name was “appdb”, I was able to then query the name of possible tables within the database.

' union select group_concat(table_name) from information_schema.tables where table_schema='appdb' -- -

This returned the following error.

Sorry, user is the wrong user

We now know the name of the table where the user information is stored. We can then find the name of all the columns within this table.

' union select group_concat(column_name) from information_schema.columns where table_name='user' -- -

This returned the following.

Sorry, password,username is the wrong user

Given that we had a column for “username” and a column for “password” we can output the contents from this field.

' union select group_concat(username,':',password) from user -- -

This resulted in the following.

Sorry, admin:password is the wrong user

At this point, I was able to understand the database layout yet I still could only get the first entry from the “user” table. I started off by simplifying the above queries and then excluded the username of “admin”. For the following query, after inputting it into the username field, this yielded the flag.

' union select username from user where username!='admin' -- -

which resulted in getting the flag!

Got the flag for Alex Hanlon!

While this method was certainly long, it provided an extensive process to get the overall database layout which became helpful for the second problem below. An additional note is that the following payload is much simpler but also works as an acceptable solution as well, however, the above methodology was incredibly helpful for the second challenge.

' OR 1=1 AND username!='admin' -- -

Some additional investigation post-CTF found the following information.

' union select group_concat(username) from user -- -

Which output the following error.

Sorry, admin,ahanlon is the wrong user

This revealed that the username for Alex Hanlon is “ahanlon”. However, when a similar payload for passwords was attempted, this resulted in the following error.

' union select group_concat(password) from user -- -
Sorry, password is the wrong user

Even when this payload was attempted, it returned a server error from the application instead.

' union select group_concat(password) from user where username!='admin'-- -

This indicated that within the database, the password for “ahanlon” was a null value making it practically impossible to login via knowing the username and password. However, this allowed the following to be another possible payload solution.

ahanlon' -- -

To view the released challenge source to test this exploit on your own, visit the following link:

Going In Blind

Prompt for the Square CTF challenge, 'Alex Hanlon Has The Flag!'

For this challenge, we continued the problem from the previous challenge where they give us a similar looking user interface to the previous problem.

Starting webpage for 'Going in Blind'

Using “Inspect Element”, we can view the source code to start to see part of the challenge of this problem.

    <title>CTF Web 200</title>
    <meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />
    <h1>Welcome to CTF Web 200!</h1>
    <p>Alex Hanlon has the flag again! Once again, try to login to his account. But, you can only use alphanumeric characters to login.</p>
    <div style="white-space:pre-wrap" ></div>
    <form action="/" method="post">
      <label for="username">Username:</label>
      <input type="text" id="username" name="username" title="Alphanumeric characters only!" pattern="[A-Za-z0-9]*"><br><br>
      <label for="password">Password:</label>
      <input type="password" id="password" name="password" title="Alphanumeric characters only!" pattern="[A-Za-z0-9]*"><br><br>
      <input type="submit" value="Submit">

My first thought was to attempt to see if the pattern filter was applied client-side so I removed the “pattern=’[A-Za-z0-9]*’” from the source code and attempted the same SQLi payload as the first problem to try and see if the solution could be achieved.

' union select username from user where username!='admin' -- -

This caused a server error when attempting this indicating that the filtering was also applied server-side when running this application.

Server error returned after attempting to remove client-sider filtering.

So, if I could only add those filtered characters via the HTML form, how could I perform SQLi? This got me thinking about the potential ways the POST request via the form could be made. We knew from the form that the parameters for the given request where “username” and “password”. What other vectors could allow us to pass in these values? One theory I had was potentialy via url parameters. I took the same payload from before and used to URL Encode the payload to visit the following URL.


With great suprise, this produced the following output.

Successful login but no flag.

It appears that URL parameters are not parsed for SQLi allowing us to continue our attack! However, we were able to successfully login to Alex Hanlong again it appears, revisiting the challenge description tells us that the flag is hidden somewhere a bit more difficult this time. After inspecting all of the client-side locations (i.e. source code, local storage, cookies, etc) the flag did not appear to be sent. This got me thinking about potential ideas and this brought me back to my approach to the first problem. What if the flag was in an entry in the database itself? Working with this theory, I decided to URL Encode the same exploratory payloads as the first problem. I then visited the following URLs.


This returned the following error.

Sorry, information_schema,performance_schema,appdb is the wrong user

This indicated that the database structure was roughly the same allowing me look for possible tables.


This returned the following error.

Sorry, flag,user is the wrong user

It appears that there is a hidden table called “flag”! Knowing this I decided to explore columns of the flag table.


This returned the following error.

Sorry, flag is the wrong user

Indicating that there was a column named flag. I then decided to explore all of the entries in the flag table.


This produced the flag proving that it was hidden in the database as a hidden entry.

Flag acquired for 'Going in Blind'!

While this method was a bit long for the first problem, the exploratory error based SQLi alowed for a better understanding of the overall database schema leading to a successful solve on this problem.

To view the released challenge source to test this exploit on your own, visit the following link:

This post is licensed under CC BY 4.0 by the author.