Web-Zhuanxv-WriteUp

Zhuanxv


拿到后台界面

  1. 打开链接发现是一个显示时间的页面

    png

  2. dirseach 扫一下目标站点有没有暴露什么敏感文件或者目录

    png

    发现存在一个 list 目录 , 进入后跳转为后台登录页面

    png

    登录页面第一个想到 SQL 注入 , 随手试了几个 Payload 没有注入成功 , 应该没有那么简单 , 先放在一边 .


拿到后端的部分源码

  1. 先拿 Burpsuite 看一下刚才整个登录流程

    1. 进入 list 目录时页面的跳转

      png

      页面弹窗 , 点击后跳转页面到后台登录页面

    2. 获取登录页面背景图片

      png

      在跳转到后台登录页面后 , 目标站点会请求页面背景图片

  2. 这里获取背景图片的请求是比较可疑的 , 很可能存在 目录遍历 等漏洞

    1. 获取 web.xml

      开始尝试获取 /etc/passwd 文件 , 没有成功 , 这里获取的文件可能存在某种过滤 , 然后发现可以读取 WEB-INF 目录下的文件 , 正常情况下 WEB-INF 目录下的文件无法通过浏览器直接访问 , 通过 Action 访问相对安全 , 所以很多配置文件都放在该目录下, 最后尝试获取 web.xml 文件 , 成功拿到该文件 .

      Payload : ../../WEB-INF/web.xml

      png

      发现后台使用的是 Struts2 框架 : 定义并使用 Struts2 作为过滤器 , 该过滤器拦截所有的 HTTP 请求 .

    2. 获取 Struts.xml

      struts2 默认配置文件存放在 WEB-INF/classes/ 目录下 , 在该路径下可以拿到 struts.xml 配置文件

      png

      Struts2 的核心功能是 Action , 对开发者来说 , 使用 Struts2 框架的主要工作就是编写 Action 类来实现业务 . 这里主要关注 Action 配置

      拿其中一个 Action 的配置来分析

      png

       Name 属性 : Name属性是必须的  , 代表请求的 Action 名称 , 该属性默认是不允许有斜杠( / )的 , 并且最好不要有点号( . )
      
       Class 属性 : Class属性为 Action 类完整类名 , 对应 Action 处理类对应的具体路径 . 如果省略 , 默认的 Class 属性是 ActionSupport 的完整类型 , 当然该属性不会省略 , 否则就没有编写这个 Action 的必要了
      
       Method 属性 : Method属性代表指定 Action 中的方法名 . 如果不指定 Method , 执行 Action 时默认调用 execute() 方法 . 
      
       Result Name 属性 : 对应 Action 返回的逻辑视图的名称 , 默认为 Success
      
       Result Type 属性 : 对应 Action 返回的结果类型 , 默认为 dispatcher( 用于服务器内部跳转 )
      
    3. 将几个 Action 配置中 Class 属性指定路径添加 .class 后缀 , 通过前面下载背景图片的方式下载到本地

      png

      将文件名修改为 *.class 保存下来 , 之后会用到 , 一共四个文件 .


拿到数据库交互文件

通过 Struts2 这个点拿到了三个 Action 类文件 , 这还不够 , 还不知道后台登录时与数据库的交互是怎样实现的 , 而且很多时候 , Struts , Spring , Hibernate 三大框架往往是一同使用的 , 因此被称为 " SSH " 三大框架 .

Spring 是一个轻量级 , 基于 IOC( Inversion Of Control , 控制反转 )AOP( Aspect Oriented Programming , 面向切面编程 ) 核心技术的企业级开源开发框架 .

Spring 核心配置文件为 : applicationContext.xml , 在 classes 目录下是可以找到这个文件的

png

在该文件最后可以找到与 DAO( Data Access Object , 数据访问对象 ) 相关的文件 , Dao层主要用于连接数据库 , 封装增删改查的数据库语句 . 因此该文件中存在与数据库交互的相关信息

png

与前面的方法类似 , 将这两个敏感文件修改后下载到本地 , 后面再分析

png

那么Flag会在哪里呢 ? 在 Spring 核心配置文件 applicationContext.xml 中能看到 数据库的连接信息 以及 Hibernate 实体映射文件 " User.hbm.xml "

  1. 通过数据库的连接信息 , 可以知道连接数据库的具体路径以及数据库的用户名与密码

    png

    直接给了 root 的用户名和密码 , 但是题目中明确指出 : 目标主机仅开放了Web服务端口 , 所以无法直接连接数据库 .

  2. Hibernate 实体映射文件

    png

         Class 属性 : 配置实体与表的对应关系
    
         Class Name 属性 : 实体的完整类名
    
         Class Table 属性 : 与实体对应的表的名称
    
         Id 属性 : 配置实体与表中id的关系
    
         Id Name 属性 : User对象中标识主键的属性名称
    
         Id Column 属性 : 主键在表中的列名
    
         Generator Class 属性 : 主键生成策略 , Identity 表示依赖于数据的主键自增功能
    
         Property 属性 : 实体中属性与表中列的对应关系
    
         Property Name 属性 : 实体中的属性名称
    

    从上面的返回信息可以得知数据库中表的相关信息

     一张表为 "hlj_members" , 存在递增的主键 "Id" 字段 以及 "name" 字段 和 "password" 字段
    
     一张表为 "bc3fa8be0db46a3610db3ca0ec794c0b" , 存在递增的主键 "welcometoourctf" 字段 和 flag 字段
    

    这里看到了 Flag 字段 , 很有可能我们要的 Flag 就在数据库中 .

分析后端源码

现在有了明确的目标 , 开始分析之前拿到的 6 个 .class 文件源码

png

.class 文件是由 .java 文件 编译后得到的 , 本身不可读 . 所以要将 .class 文件逆向处理 . 这里使用 jd-gui 这个工具 .

png

逆向编译后可以看到源代码

  • AdminAction.class
    该文件主要包含读取文件等操作 , 没啥重要的地方

  • DownloadAction.class
    该文件主要用于下载背景图片 , 代码中对文件缀后进行了判断 , 只有后缀为 .xml , .class , .jpg 的文件才可以被成功读取

    png

  • UserDaoImpl.class
    该文件主要包含数据库操作 , 因为后端使用了 Hibernate框架 和 HQL语句 , 因此一般的 SQL 注入语句无法注入成功

    png

  • UserLoginAction.class
    该文件主要包含用户登录对用户名和密码规范性的检测 , 判断用户是否登录成功

  • UserOAuth.class
    该文件主要是通过 Session 来判断用户是否已登录 , 如果未登录则要求用户登录

  • UserServiceImpl
    该文件包含两个比较重要的函数 findUserByName()loginCheck()

    png

    在之前的文件中会调用这两个函数 , 需要注意这个 loginCheck() 函数 , 首先他会对用户输入的用户名进行过滤 , 将" = " 和 " " 两个特殊字符转换为 " " , 说明在输入的用户名中不可以出现 等于号 和 空格 , 然后对输入的用户名和密码进行正则匹配 , 但此时程序出现了漏洞 , 仅需要用户输入的密码匹配成功后 , 程序就判断正则匹配通过 , 而没有判断用户名的正则匹配是否通过 , 因此可以对用户名进行 HQL 注入 , 拿到我们需要的信息

因此 , 这里的攻击点变为了 HQL 注入 . 而现在又知道了后台查询语句是怎么构造的( UserDaoImpl.class 文件中有 ) , 因此可以顺利出构造我们的 Payload


HQL注入

那么使用哪种SQL注入技巧呢? 这里仅有的注入点是一个登录界面 , 那么是否可以在不知道用户名密码的情况下登录成功呢 ?

注意 , 在注入时不可以使用 等于号( = ) 以及空格( ) , 因此常规的万能公式肯定是不行的 . 但是这都不是事 , 1=1 这个永真条件可以用 ''LIKE''替换 , 而空格则可以使用注释( /*-*/ ) , 小括号 , 换行( \n )来代替

在构造SQL语句时会使用到 AND , OR , LIKE 三个运算符 , 这里需要注意他们的优先级 : LIKE > AND > OR

  • 尝试万能公式登录后台
    BurpSuite POST Payload : user.name='OR''LIKE''OR''LIKE'&user.password=abc

    png

    数据库在代入语句并执行查询时是按如下顺序处理的 .

    png

    我在这一步还遇到一个问题 , 这里写一下

    最开始我写的 Payload 是这样的 : Payload : user.name='OR''LIKE''OR'&user.password=abc , 但是利用该Payload 并没有登录成功 , 但想不明白为什么不可以 .

    经过测试 , 我猜测有这么一个可能 , 如下

    • 这两个 Payload 在解析思路上是相同的 , 但在处理 AND 时有一点不同 , 单独拿出来看是这样的 :
      png

    • 而第二个 Payload( 登录失败的 Payload ) 在处理时存在一个 Warning

      png

    • 理论上 Warning 是不影响程序运行的 , 但会不会是 MySQL 在返回结果时将这个 Warning 也返回了, 后端 Java 在处理结果时抛出这个异常( MySql.Data.MySqlClient.MySqlException Truncated incorrect INTEGER value ) , 导致程序出错呢 ?

      Java 是强类型语言 , 而 MySQL 是弱类型数据库 . MySQL 对变量的类型没有明确限定 , 而Java中变量类型被定义就不会再变 .

      因此 , MySQL 中对类型的 Warning , 返回到 Java 后端就变成了 ERROR , 导致程序抛出异常出错 .

      这个结论仅仅是一个可能 , 如果您知道原因欢迎留言~

  • 进一步读取数据库相关信息
    虽然此时可以登录网站后台 , 但在网站后台并没有我们想要的 Flag , 真正的 Flag 在数据库里

    想要读取数据库中的信息 , 可以采用布尔盲注 , 因为能否登录后台成功完全取决于 Payload 中 ''LIKE'' 条件是否为 " 1 ". 而这里的条件可以任意构造 .

    当前所查询的实体类为 User ( 在 HQL 语句中查询的是实体类 , 实体类与数据表存在映射关系 , 这个映射关系就写在 *.hbm.xml 文件中 , 因此HQL语句中 from 后跟着的是实体类名 ' User ' , 而不是实际的表名 'hlj_members' ) . 根据配置文件得知该实体类中存在两个属性 namepassword ( 分别对应原数据表中的两个字段

    • 拿到 name 字段值
      因为查询使用的是 HQL 语句 , 所以很多 MySQL 的特性无法使用 , 这里拿到 name 字段值的思路是 : 将该字段值拿出 , 取出字段值的第x个字符 , 分别与其他字符做比较 , 如果与某个字符匹配 , 那么就代表该字段的第x个字符等于相匹配的字符 , 依次类推 .

      Payload : 'OR(SUBSTRING(name,...,1))LIKE'...'OR''LIKE'

      盲注脚本构造如下

      png

      运行结果如下

      png

      成功拿到 name 字段!

    • 拿到 password 字段值
      这里的思路与之前拿 admin 字段值的思路类似 , 但是有个点我始终搞不明白 , 在构造 Payload 时 , User 两侧是不可以使用小括号来替换空格的 , 必须要换另外一种方式( 比如采用换行符 \n 阶段 )

      Payload : 'OR(SELECT(SUBSTRING(password,...,1))FROM\nUser\nWHERE(name)LIKE'homamamama')LIKE'...'OR''LIKE'

      png

      从上图可以看出 , 在 User 两侧我使用了\n替换空格而没有使用小括号 . 原因我猜测是 Java 中强制类型转换的问题 . 因为 From 后面是实体类名 , 而 Java 中强制类型转换的写法为 Test test1 = (Test)test2 , 所以这里 ( 类名 ) 可能会被解析为类型转换

      这只是一个猜测 , 如果您知道正确答案欢迎留言 ~

      png

      成功拿到 homamamama 用户的密码 6YHN7UJM

    • 拿到 Flag
      其实拿到Flag根本不需要前面两步 .... 直接拿就拿到了哈哈哈

      png

      运行后即可拿到 Flag

      png

      成功拿到 Flag


总结

这道题主要考察 SSH 三大框架的理解 以及 HQL 语法 , 感觉还是很有意义的 ~

暂无评论

发送评论 编辑评论


				
|´・ω・)ノ
ヾ(≧∇≦*)ゝ
(☆ω☆)
(╯‵□′)╯︵┴─┴
 ̄﹃ ̄
(/ω\)
∠( ᐛ 」∠)_
(๑•̀ㅁ•́ฅ)
→_→
୧(๑•̀⌄•́๑)૭
٩(ˊᗜˋ*)و
(ノ°ο°)ノ
(´இ皿இ`)
⌇●﹏●⌇
(ฅ´ω`ฅ)
(╯°A°)╯︵○○○
φ( ̄∇ ̄o)
ヾ(´・ ・`。)ノ"
( ง ᵒ̌皿ᵒ̌)ง⁼³₌₃
(ó﹏ò。)
Σ(っ °Д °;)っ
( ,,´・ω・)ノ"(´っω・`。)
╮(╯▽╰)╭
o(*////▽////*)q
>﹏<
( ๑´•ω•) "(ㆆᴗㆆ)
😂
😀
😅
😊
🙂
🙃
😌
😍
😘
😜
😝
😏
😒
🙄
😳
😡
😔
😫
😱
😭
💩
👻
🙌
🖕
👍
👫
👬
👭
🌚
🌝
🙈
💊
😶
🙏
🍦
🍉
😣
Source: github.com/k4yt3x/flowerhd
颜文字
Emoji
小恐龙
花!
上一篇
下一篇