无参RCE解题
正常解题
TGCTF–偷渡阴平
考点总结: PHP session_id、绕过waf、无参RCE(非预期)
源码如下
1 | |
非预期打无参RCE
方法一:
1 | |
get_defined_vars()获取已经定义的所有变量并返回一个数组current()接收前面的函数返回的数组并返回数组第一个元素end()将会移动数组内部指针到最后一个数组元素并返回这个值eval将会执行返回的值,然后引用赋值(就是&符号),将后边命令的结果赋值给b,这个b就是数组的最后一个元素,最终会被eval执行并且输出结果
方法二:
1 | |
getcwd():返回当前工作目录的绝对路径dirname():这个函数会返回指定路径的父目录,这里可以利用这个函数进行目录穿越到根目录scandir():这个函数会将指定目录下的所有文件和子目录的名称作为一个数组返回,这里返回的是根目录的所有文件和子目录var_dump():将返回的含有根目录的文件和子目录名的数组打印出来

1 | |
dirname(dirname(dirname(getcwd()))):穿越到根目录,并返回根目录chdir():这个函数会改变当前的工作目录到指定目录,这里将工作目录改变为根目录,并返回布尔值,如果没有这一步会发现不能读取根目录下的文件,只会报错dirname():因为上面的函数的返回值是布尔类型,但后面的函数接收的类型要是指定的目录,所以这里要加一个这个函数,将返回值改成根目录scandir():这个函数会将指定目录下的所有文件和子目录的名称作为一个数组返回,这里返回的是根目录的所有文件和子目录array_flip():这个函数用于交换数组中键和值的位置,若scandir()返回的数组是['.', '..', 'file1.txt', 'file2.php'],经过array_flip()处理后,会变成['.' => 0, '..' => 1, 'file1.txt' => 2, 'file2.php' => 3]array_rand():这个函数用于从数组中随机选取一个或多个键,这里就会随机选一个文件highlight_file():这个函数将随机选取的文件内容高亮显示出来
缺少scandir()函数更改工作目录这一步的结果是无法读取文件

加上这个函数就可以读文件了,因为是随机选取一个文件,所以刷新几次就可以读到了

方法三:
1 | |
array():创建一个空数组serialize():将创建的空数组序列化成字符串,结果是a:0:{}crypt():对序列化后的字符串进行加密,最后得到的结果是随机的,如$1$pc4jiIfD$pqtTfFXRHonNcpqbxqhtK.,这里就是需要随机出最后一个字符是点.strrev():把加密后的字符串进行反转,将点.放到字符串的开头ord()函数返回字符串第一个字符的 ASCII 值chr()函数根据 ASCII 值返回对应的字符chdir():这个函数会改变当前的工作目录到指定目录,这里将工作目录改变为根目录,并返回布尔值,如果没有这一步会发现不能读取根目录下的文件,只会报错dirname():因为上面的函数的返回值是布尔类型,但后面的函数接收的类型要是指定的目录,所以这里要加一个这个函数,将返回值改成根目录scandir():这个函数会将指定目录下的所有文件和子目录的名称作为一个数组返回,这里返回的是根目录的所有文件和子目录array_flip():这个函数用于交换数组中键和值的位置array_rand():这个函数用于从数组中随机选取一个或多个键,这里就会随机选一个文件show_source():这个函数将随机选取的文件内容高亮显示出来
session_id()
hex2bin()
TGCTF–偷渡阴平(复仇)
**考点总结:**PHP、session_id、绕过waf、RCE
这个把无参RCE给ban了,避免非预期
源码如下
1 | |
payload
1 | |
session_start():在 PHP中 这个函数的作用是开启一个新会话或者复用已有的会话session_id():这个函数用于获取当前会话的 ID,即cookie中的PHPSESSIDhex2bin():这个函数会将PHPSESSID的 十六进制字符串转化为二进制字符串system():会执行转化后的二进制字符串命令
这题的解题思路就是开启一个新会话,通过在当前会话的 ID 中构造要执行的命令,并转化为二进制字符串,使用system()函数执行命令

读文件
如果知道文件名,可以直接使用readfile读文件,在 PHPSESSION 中写入文件名
1 | |

getallheaders()
这个函数可以返回当前请求的所有请求头信息,局限于Apache
apache_request_headers()和getallheaders()功能相似,可互相替代,不过也是局限于Apache
1 | |
这里可以在数据包最后加入一个请求头,写入恶意代码,使用end()函数指向最后一个请求头,从而可以执行命令

get_defined_vars()
相较于getallheaders()更加具有普遍性,这个函数可以回显所有变量
1 | |
get_defined_vars()获取已经定义的所有变量并返回一个数组current()接收前面的函数返回的数组并返回数组第一个元素end()将会移动数组内部指针到最后一个数组元素并返回这个值eval将会执行返回的值,然后引用赋值(就是&符号),将后边命令的结果赋值给b,这个b就是数组的最后一个元素,最终会被eval执行并且输出结果
chdir()&array_rand()赌狗读文件
如果无法进行RCE,可以进行目录遍历读取文件
1 | |
无参RCE解题
https://yschen20.github.io/2025/04/29/无参RCE解题/