Dogfinder – Nullcon HackIM CTF Berlin 2025 Writeup

I like dogs, so I wrote this awesome dogfinder page. Somewhere on the filesystem is a nice treat for you.

After reading the challenge description, I got a hint that our flag is on the system. Later, we will confirm that. Upon visiting the URL http://52.59.124.14:5020 I see a simple page with search functionality that allows users to find different types of dogs by using filters.

Crawling yielded only one endpoint with some parameters: http://52.59.124.14:5020/?name=&breed=&min_age=&max_age=&page=2&order=id. My hacker sense immediately realized that this was a case of SQL injection.

My methodology to find SQL injection is a three-step process.

  1. Detect
  2. Identify
  3. Exploit

Detect

It’s time to detect which parameter is vulnerable. So, I started checking each parameter one by one. I assume that these parameters make a query something like SELECT * FROM dogs WHERE name=? OR breed=? OR min_age>? OR max_age<? ORDER BY id .

Testing order parameter when I put '. The server gave me an empty response, but when I commented out using --. The server responded with all results in a table. Now, I know that the vulnerable parameter is order , and the application is inserting my input in ORDER BY

SELECT * FROM dogs WHERE name=? OR breed=? OR min_age>? OR max_age<? ORDER BY my_input

Identify

We know the vulnerable parameter, now we have to check which type of vulnerability is possible here are which database we are working with. Chatting with DeepSeek, I came to know that we can actually use CASE statement inside ORDER BY for conditional response like

SELECT * FROM dogs WHERE name=? OR breed=? OR min_age>? OR max_age<? ORDER BY CASE WHEN (1=1) THEN breed END

So I immediately check with 1=1 and 1=2. By seeing the difference in response, I can say that it is Boolean Base Blind SQL Injection.

http://52.59.124.14:5020/?name=&breed=&min_age=&max_age=&page=&order=case+when+(1=1)+then+breed+end Gives a different response from this

http://52.59.124.14:5020/?name=&breed=&min_age=&max_age=&page=&order=case+when+(1=2)+then+breed+end

To exploit further, we must know which database we are working with, and for this, DeepSeek gave a clever idea: we used database database-specific function to differentiate between databases.

WHEN (CURRENT_DATABASE()=CURRENT_DATABASE()) IS NOT NULL -> Postgresql

WHEN (DATABASE()=DATABASE()) IS NOT NULL -> MySQL

So by sending these two requests, we know that we are working with POSTGRESQL

http://52.59.124.14:5020/?name=&breed=&min_age=&max_age=&page=&order=case+when+(current_database()=current_database())+is+not+null+then+breed+end -> For Postgresql

http://52.59.124.14:5020/?name=&breed=&min_age=&max_age=&page=&order=case+when+(database()=database())+is+not+null+then+breed+end -> For MySQL

Exploitation

Now we know that it is Boolean-Based Blind SQL Injection and the database is Postgresql.

First of all, we need to know how many tables are in the current database, and then we check if the flag is stored in the database.

1 Comment

  1. Hi, this is a comment.
    To get started with moderating, editing, and deleting comments, please visit the Comments screen in the dashboard.
    Commenter avatars come from Gravatar.

Leave a Reply

Your email address will not be published. Required fields are marked *