0x01 漏洞描述
HTMLy 是一个开源的基于 PHP 的博客平台。它可以让用户创建安全、轻量且功能强大的网站或博客,并且即使在拥有数千篇文章的情况下,也能高效扩展。
该系统存在存储型XSS漏洞,由于xxx.php 文件中的xxx函数 对用户传入的数据没有进行严格过滤,导致用户可以在新建文章时写入恶意的攻击代码,由此触发XSS攻击。
0x02 环境搭建
版本信息
通过phpstudy 进行搭建
php:7.1.9
apache:2.4.39
htmly版本:2.9.9 最新版本
安装htmly
- 也可以直接下载installer.php 进行一键安装,默认下载最新版本
- 下载源码
 Release Composer Vendor Update and Improvements · danpros/htmly (github.com)
- 将文件夹放入phpstudy的web目录下 C:\phpstudy_pro\WWW
- 根据README.md中的步骤,修改htmly的配置文件- 在config文件夹中将example重命名为config.ini
- 修改config.ini,设置siteurl的地址1 
 2; The URL of your blog. 
 site.url = "http://htmly:8088/\/"
- 在 config/users的文件夹中,将example重命名为htmly.ini(填入自己像设置的用户名即可)
- 修改htmly.ini,填入密码
  
 
- 在config文件夹中将example重命名为
- 在phpstudy中创建项目
  
- 访问http://htmly:8088/install.php页面,进行安装
- 成功安装后跳转到该页面
  
- 访问 http://htmly:8088/login进入到管理员页面
  
phpstorm动态调试
参考往期文章,配置动态调试
thinkphp5.0 文件包含漏洞分析-超详细保姆级 - Gryffinbit的思维殿堂 0x03 动态调试章节
0x03 漏洞分析
XSS漏洞原理
跨站脚本攻击XSS通过将恶意得Script代码注入到Web页面中,当用户浏览该页之时,嵌入其中Web里面的Script代码会被执行,从而达到恶意攻击用户的目的。
漏洞函数
在htmly.php中,对传入的数据进行了处理
| 1 | add_content($title, $tag, $url, $content, $user, $draft, $category, 'post', $description, null, $dateTime); | 

在对$content变量进行的定义
| 1 | $content = from($_REQUEST, 'content'); | 

用户传入content数据,经过from函数进行处理并赋值给$content变量。跟进from函数。这个函数可以从数组中提取单个值或多个值(如果$name是数组),并且在提取过程中处理换行符和去除空白。
| 1 | function from($source, $name) | 
这个from()函数的作用是从指定的$source数组(例如$_REQUEST)中提取指定键的值,并进行一些处理。以下是对代码的详细解释:
- $map = array("\r\n" => "\n", "\r" => "\n");:- 这是一个映射数组,用于将Windows和Mac风格的换行符(\r\n和\r)转换为Unix风格的换行符(\n)。这有助于统一处理不同操作系统下的换行符,确保数据一致性。
 
- 这是一个映射数组,用于将Windows和Mac风格的换行符(
- if (is_array($name)):- 如果$name是一个数组,函数将遍历这个数组,从$source中提取每个键的值,并进行处理。
 
- 如果
- $data = array();:- 如果$name是数组,函数会创建一个空数组$data来存储结果。
 
- 如果
- foreach ($name as $k):- 遍历$name数组中的每个键$k。
 
- 遍历
- $data[$k] = isset($source[$k]) ? trim(strtr($source[$k], $map)) : null;:- 对于每个键$k,检查它是否存在于$source数组中。
- 如果存在,使用strtr()函数将换行符替换成\n,再用trim()去掉值的首尾空白字符,然后将结果存入$data[$k]。
- 如果键不存在,将结果设置为null。
 
- 对于每个键
- return $data;:- 如果$name是数组,返回处理后的结果数组$data。
 
- 如果
- return isset($source[$name]) ? trim(strtr($source[$name], $map)) : null;:- 如果$name不是数组,则直接从$source中获取对应的值,处理后返回。
- 如果键不存在,返回null。
 
- 如果
由于该函数对传入的数据没有进行严格过滤,所以导致了漏洞的存在。
0x04 攻击演示
漏洞点:http://htmly:8088///add/content?type=post
文章内容写入处存在xss
点击xss的文章
触发xss漏洞
 
     
          
         
          
        