level 0
牛牛牛,正式开始
「任意代码执行(Arbitrary Code Execution,ACE)」 是指攻击者在目标计算机或目标进程中运行攻击者选择的任何命令或代码的能力,这是一个广泛的概念,它涵盖了任何类型的代码运行过程,不仅包括系统层面的脚本或程序,也包括应用程序内部的函数或方法调用。
在此基础上我们将通过网络触发任意代码执行的能力通常称为 远程代码执行 「远程代码执行(RCE,Remote Code Execution,RCE)」。
「命令执行(Command Execution)」 通常指的是在操作系统层面上执行预定义的指令或脚本。这些命令最终的指向通常是系统命令,如Windows中的CMD命令或Linux中的Shell命令,这在语言中可以体现为一些特定的函数或者方法调用,如PHP中的shell_exec()
函数或Python中的os.system()
函数。
「代码执行(Code Execution)」 同我们最开始说到的任意代码执行,在语言中可以体现为一些函数或者方法调用,如PHP中的eval()
函数或Python中的exec()
函数。
虽然在很多教学场景,命令执行 和 代码执行 经常被用同一个缩写 RCE (Remote Code/Command Execution) 来指代,但显而易见的是,代码执行是更为广泛的概念。
leve 1
这题也很简单,讲了一个关键的前置知识,也是我之前经常忘记的
在某个语言中,通过一些方式(通常为函数或者方法调用)执行该语言的任意代码的行为,如PHP中的eval()
函数或Python中的exec()
函数。
当漏洞入口点可以执行任意代码时,我们称其为代码执行漏洞 —— 这种漏洞包含了通过语言中对接系统命令的函数来执行系统命令的情况,比如 eval(“system(‘cat /etc/passwd’)”; ); 也被归为代码执行漏洞。
我们平时最常见的一句话木马就用的 eval() 函数,如下所示(一般情况下,为了接收更长的Payload,我们一般对可控参数使用POST传参)
- eval就是执行括号内php语句的函数
- 直接传system()就可以了
level 2
level 3
牛牛启动
「命令执行(Command Execution)」 通常指的是在操作系统层面上执行预定义的指令或脚本。这些命令最终的指向通常是系统命令,如Windows中的CMD命令或Linux中的Shell命令,这在语言中可以体现为一些特定的函数或者方法调用,如PHP中的shell_exec()
函数或Python中的os.system()
函数。
当漏洞入口点只能执行系统命令时,我们可以称该漏洞为命令执行漏洞,如下面修改过的 “一句话木马”:system($_POST[‘a’]);
level 4
SHELL 运算符 可以用于控制命令的执行流程,使得你能够根据条件执行不同的命令。
&&(逻辑与运算符): 只有当第一个命令 cmd_1 执行成功(返回值为 0)时,才会执行第二个命令 cmd_2。例: mkdir test && cd test
||(逻辑或运算符): 只有当第一个命令 cmd_1 执行失败(返回值不为 0)时,才会执行第二个命令 cmd_2。例: cd nonexistent_directory || echo “Directory not found”
&(后台运行符): 将命令 cmd_1 放到后台执行,Shell 立即执行 cmd_2,两个命令并行执行。例: sleep 10 & echo “This will run immediately.”;(命令分隔符): 无论前一个命令 cmd_1 是否成功,都会执行下一个命令 cmd_2。例: echo “Hello” ; echo “World”
没绷住,也是直接秒了,很简单,就是我之前做的那么多次的,很常规payload:?8.8.8.8;cat /flag
level 5
上来就没绷住,就是简单的绕过方式(放现在,到处都是无参rce,哪里还给你这种机会)
在Shell中,单/双引号 “/‘ 可以用来定义一个空字符串或保护包含空格或特殊字符的字符串。
例如:echo “$”a 会输出 $a,而 echo $a 会输出变量a的值,当只有””则表示空字符串,Shell会忽略它。
- (星号): 匹配零个或多个字符。例子: .txt。
- ?(问号): 匹配单个字符。例子: file?.txt。**
- [](方括号): 匹配方括号内的任意一个字符。例子: file[1-3].txt。
- [^](取反方括号): 匹配不在方括号内的字符。例子: file[^a-c].txt。
- {}(大括号): 匹配大括号内的任意一个字符串。例子: file{1,2,3}.txt。
- 通过组合上述技巧,我们可以用于绕过CTF中一些简单的过滤:
- system(“c’’at /e’t’c/pass?d”);
- system(“/???/?at /e’t’c/pass?d”);
- system(“/???/?at /e’t’c/ss“);
构造cat “f”lag直接绕过
但是这里的通配符后续大有用处
https://www.leavesongs.com/PENETRATION/webshell-without-alphanum-advanced.html在离别歌神的这个文章中有所体现
level 6
也是第五题的延续考察吧
这题很奇怪,为什么cat不行,而得用/bin/cat呢
level 7
这题见到的太多了,常规的空格绕过,以及关键字绕过(用通配符*)
1 | ?cmd=cat$IFS/fl* |
直接过了,基础主要还是%09和$IFS来绕过空格
这里还有一些方法,简单举几个例子
- 重定向
1 | ?cmd=cat</fl""ag |
- {}只在bash里有用
1 | {cat,/f'l'ag} |
- 进制
1 | X=$'cat\x20/flag'&&$X |
这里再拓展一点吧,要是waf过滤了/该怎么做
1 | ${HOME:0:1}来替代"/": |
level 8
这里开始用重定向了
这个没见过,我认为是一种无回显rce,大概给大家看一下题
1 | /* |
这个是对于重定向内容的描述,简单来说就是会把你传的命令都定向道一个/dev/null目录,然后你就什么回显都看不到,后续连你报错都可以忽略
1 | function hello_shell($cmd){ |
这里就需要去了解一些常见方法了
- 分号的使用
1 | cmd=ls; |
由于分号可以让 ls 在 >/dev/null 2>&1 之前执行,因此我们可以直接这么强打,得到命令执行的结果
2. tee函数的使用
1 | ?cmd=ls | tee output.txt |
tee函数的作用在于:tee 命令可以复制输出,使得 ls 的结果仍然可以看到
后续访问output.txt来看执行的结果了
3. 逆向重定向
1 | ?cmd=ls 2>&1 | cat |
接下来补充一点相关知识
在Linux中文件描述符(File Descriptor)是用于标识和访问打开文件或输入/输出设备的整数值,每个打开的文件或设备都会被分配一个唯一的文件描述符,Linux 中的文件描述符使用非负整数值来表示其中特定的文件描述符有以下含义
- 标准输入(stdin):文件描述符为0,通常关联着终端键盘输入
- 标准输出(stdout):文件描述符为1,通常关联着终端屏幕输出
- 标准错误(stderr):文件描述符为2,通常关联着终端屏幕输出
level 9
八进制转换,这个是bash的一种特性(注意,只有bash有)
1 | caochuhan@DESKTOP-B9Q8MAA:/mnt$ $'\154\163' |
在Linux中试了一下,确实是这样,BUT
这种方法的缺陷就是无法一连串的指向带参命令,只能拆分开来
意思就是遍一下cat,再编一些/flag,最后再用空格连接起来,而不能合在一起一同转进制,这样子的指令是行不通的
例如
1 | bash-5.1# $'\143\141\164\40\57\146\154\141\147' |
这样子就出flag了,需要注意的是不能用空格连接后一起转,而是要分开转之后用空格连接
空格要是被过滤的话,就可以用
1 | ?cmd=$'\143\141\164'<$'\57\146\154\141\147' |
探姬给出的注释如下
1 | /* |
bash与dash不同
关于进制转换的脚本在线
https://probiusofficial.github.io/bashFuck/
level 10
营业执照思密达