Hack This Site - Realistic - BudgetServ Web Hosting

Thu, Jun 10, 21

Welcome back to my walkthrough of hackthissite.org’s CTF missions. I will be going through my thought process of how I solved these missions, and therefore also giving away the solutions. If you came across this to give you hints, watch out for spoilers! Good luck, have fun.

Our next realistic mission asks us to retrieve a backup from a web hosting service that shut down my client’s account. They wish to retrieve this backup which they say should still be available within the service.

I will begin by investigating the website to see if there is anything that is interesting or odd about their functionalities and implementations of the frontend. The first thing that I notice is that all the pages are served to the client using the following path: /page.pl?page= followed by the name of the page. The second thing, noticeable from the faq page, is that there is an ‘admin’ portal that allows to upload files to a client’s directory that is accessible under the path /admin/. Lastly, there is a ‘WebMail’ service that is accessible under the path /page.pl?page=email.

We will first checkout this ‘WebMail’ service. Upon loging in with nothing inputed, I am instantly presented with the message:

Due to the recent security breach, WebMail is currently unavailable.

With this, I will ignore this page for now, keeping in mind that it is possible that it may be used later on in this challenge. Checking out the /admin/ page and trying a basic administrator login - admin:password - results with an expected “Login Incorrect” message along with two cookies being set: {bs_pass, bs_user}. Testing with a username and password that have spaces in it, I notice that both of these cookies are URL-encoded.

From here, the only thing that is left to quickly test is the /page.pl?page= endpoint. Trying a page that I don’t expect to exist - test - results with the following output:

open(file, "pages/test") failed: No such file or directory

This suggests that the /page.pl script takes the user input from the query string field page and directly concatenates it into the PEARL 2 argument open() function. Now, from a previous CTF challenge where I exploited PEARL’s exec() command, I had learned that the open() PEARL function is susceptible to command injection but I do not know too much about it, thus some research is required in order to understand how such command injection could work. The following is the what my research on this function turned up:

With this information now on hand, we are ready to exploit this function. Since we know that the code looks like the following: open(file, "pages/$userinput"), if we were to have my $userinput= |echo vulnerable|, then the final version that is to be interpreted looks like the following: open(file, "pages/|echo vulnerable|"). This is interpreted as followed:

  1. PEARL locates a pipe character and thus assumes that the input are shell commands
  2. pages/ is not identified as a proper commmand by the shell
  3. echo vulnerable is run by the shell and piped to the file filehandler

Now I will do a quick test by trying the following path page.pl?page=%7Cecho%20test%7C which is equivalent to page.pl?page=|echo test|. This gives us the following output on the webpage:

Page cannot m{[\0.<>\/&\s]}

Whilst this is not the expected output, it suggests that the page cannot contain any spaces as it doesn’t match the regex shown in the error message. It is possible that the creators of hackthissite ensured that only a few commands are possible - as they have done in previous challenges - to ensure no one can do any damage to their proper website. Thus, I must figure out which command will be of use to me at this moment. Ideally, I would want to identify some sort of file structure so that I can start looking for where the client’s files could be located, thus I will try the following path instead: page.pl?page=%7Cls%7C - equivalent to page.pl?page=|ls|. The following is the output given by the webpage:

admin bs.dbase client_http_docs frontpage.gif index.html index.pl letter.gif logo.gif ms.gif mysql.gif order.pl page.pl pages perl.gif php.gif server.gif sqlite.png suspended.html tux.gif webmail.php

The following list is the same as above but just more visually separated:

Now that we have a view of the directory of this website, we can see that client documents are most likely available in /client_http_docs/. Accessing this path, in turn, gives us a directory listing for 4 of their clients, including our own. Accessing the /client_http_docs/space46/ path results in the following message:

This account has been suspended.

Otherwise, accessing the other clients of this service’s pages, we can see that only one is sophisticated enough to pay any attention to: client_http_docs/therightwayradio/. This website is a forum site with a user sign up capability. Before moving forward I must try and figure out what is my end goal. I hope to somehow infiltrate a current client of this service to see whether they would have the ability to access the filespace of client_http_docs/space46/. Since the only way forward is through this forum site, this should be the current focus.

The forum has one post by a rsmith mentioning how hackers have infiltrated the site prior and have stolen their identities and that since then, a logging script has been added to the website. I would assume that rsmith is most likely the owner of the website and my goal is to steal his cookies. Its possible that this forum is susceptible to XSS attacks. Thus I will make an account and create a forum post enticing people to click it to steal their cookies. Going to the register page, it notes that we must have an auth code in order to create an account. This presents yet another challenge as I do not have any ‘auth code’. From here it is once again unclear what to do.

Going back to the rsmith account under the query string ?page=userinfo&id=-1 I wonder whether it is possible for me to access a website-wide userlist for this forum site. Changing the query string to ?page=userinfo does indeed result in the whole user list. At this moment I instantly see that I am able to change the password for the account with id = 0. I will take a note of the email and username - a@gmail.com, aclu_bomber_08290 - and change the password to password. Now, after doing so, I will attempt to login as this account. Success!

Now that I have logged in, I notice that I have been given the cookie rw_session that seems to match to some session id. Furthermore, I have access to a mod page that I pointed out earlier that is easily accessible where the register link was prior. This page allows us to pose SQL queries to a SQL database. Inspecting this form, I can see that we have a hidden input field that determines which database we are accessing. We wish to try and list all user information of the original bs.dbase file, the current value is rwr.dbase, thus changing the value to ../../bs.dbase should point to the correct database. Now, I will submit the query SELECT * FROM users; in hopes to access the user table for the budget server service. Clicking submit serves an error message saying the following:

DBI connect('dbname=./db/../../bs.dbase','',...) failed: unable to open database file(1) at dbdimp.c line 94

This suggest that we should change the value of the database location to be ../../../bs.dbase. Running the query once again serves a new error message saying the following:

DBD::SQLite::db prepare failed: no such table: users at ./pages/mod.pl line 16.

It is obvious that the database has their user information stored in another table. This means that we must figure out where they would have stored their user information. It does note that they are using an SQLite DBMS, which means that we may be able to directly query the sqlite_master table which stores information on database tables within SQLite. The query that I will submit will be the following: SELECT * FROM sqlite_master. This returns the following information:

sql name rootpage type tbl_name
CREATE TABLE web_hosting (web_user varchar(255), web_pass varchar(255), web_package integer, web_email varchar(255)) web_hosting 2 table web_hosting

This shows that there is only one table present, web_hosting, and the user information that we are interested in would be: {web_user, web_pass, web_email}. My new query is thus the following: SELECT web_user AS username, web_pass AS password, web_email AS email FROM web_hosting. This gives us the following results:

password email username
notofthisworld space46@space46.nod space46
letgodsortitout rsmith@therightwayradio.nod therightwayradio
suckereveryminute admin@wonderdiet.nod wonderdiet

Perfect, we now have direct access to another client of Budget SERV which we could possibly use to get the files of our client. We will assume the role of therightwayradio - since we’ve already exploited them already, why not keep going.

Going back to the admin/ page of Budget SERV, and loging in as therightwayradio, we are now presented with a ‘directory’ like form with the following functionality: {list, delete, upload, new, edit, download} within the directory space of therightwayradio. The next step forward is to attempt to make my way into the space46 directory space and use the download functionality to download the needed file. Trying to step into the ../ directory leads to an error. Instead, I will try to change one of the input options to be the value of: /var/www/budgetserv/html/client_http_docs/space46/src.tar.gz and press the download functionality. Once again, we are given an access denied error. It is possible that we must change our cookies to match that of space46 to ensure that we are allowed access, thus we will set our cookies to match with the following: {bs_pass: notofthisworld, ps_user: space46}. This yields a message saying that the account has been suspended. Again, I am a little stumped.

Perhaps we can try to access the download directly. I will use my browser’s dev tools to track which calls are made by changing the cookies back to therightwayradio’s credentials, and downloading a random file. I see that it makes a call to the following path admin/d.pl?file=/var/www/budgetserv/html/client_http_docs/therightwayradio/bs. This means that we should try to access the following path: admin/d.pl?file=/var/www/budgetserv/html/client_http_docs/space46/src.tar.gz instead to try and download the files of our client.

Accessing this link prompts us with a message saying that we have completed the mission!

Onto the next one.