‘壹’ 如何使用php的外部函数功能
1.缺少declare,正确的描述如下
private Declare Function FindWindow Lib "user32" Alias "FindWindowA" (ByVal lpClassName As String, ByVal lpWindowName As String) As Long
2 declare的说明
Declare 语句
用于在模块级别中声明对动态链接库 (DLL) 中外部过程的引用。
语法 1
[Public | Private] DeclareSubnameLib"libname" [Alias"aliasname"] [([arglist])]
语法 2
[Public | Private] DeclareFunctionnameLib"libname" [Alias"aliasname"] [([arglist])] [Astype]
Declare 语句的语法包含下面部分:
部分 描述
Public 可选的。用于声明对所有模块中的所有其它过程都可以使用的过程。
Private 可选的。用于声明只能在包含该声明的模块中使用的过程。
Sub 可选的(但Sub 或 Function 二者需选其一)。表示该过程没有返回值。
Function 可选的(但Sub 或 Function 二者需选其一)。表示该过程会返回一个可用于表达式的值。
name 必需的。任何合法的过程名。注意动态链接库的入口处(entry points)区分大小写。
Lib 必需的。指明包含所声明过程的动态链接库或代码资源。所有声明都需要Lib 子句。
libname 必需的。包含所声明的过程动态链接库名或代码资源名。
Alias 可选的。表示将被调用的过程在动态链接库 (DLL)
中还有另外的名称。当外部过程名与某个关键字重名时,就可以使用这个参数。当动态链接库的过程与同一范围内的公用变量、常数或任何其它过程的名称相同时,也可以使用
Alias。如果该动态链接库过程中的某个字符不符合动态链接库的命名约定时,也可以使用 Alias。
aliasname 可选的。动态链接库或代码资源中的过程名。如果首字符不是数字符号 (#),则
aliasname 是动态链接库中该过程的入口处的名称。如果首字符是
(#),则随后的字符必须指定该过程的入口处的顺序号。
arglist 可选的。代表调用该过程时需要传递的参数的变量表。
type 可选的。Function 过程返回值的数据类型;可以是 Byte、布尔、Integer、Long、Currency、Single、Double、Decimal(目前尚不支持)、Date、String(只支持变长)或 Variant,用户定义类型,或对象类型。
arglist 参数的语法以及语法各个部分如下:
[Optional] [ByVal | ByRef] [ParamArray] varname[( )] [Astype]
‘贰’ 怎么用php命令执行php代码
PHP执行命令的四种方法
方法一:使用exec函数执行系统外部命令
原型:function exec(string $command,array[optional] $output,int[optional]
$return_value)
<?
exec("dir",$outPut);
print_r($outPut);
?>
说明:列出和PHP执行文件同级目录下的所有目录及文件信息。
知识点:exec执行系统外部命令时不会输出结果,而是返回结果的最后一行,如果你想得到结果你可以使用第二个参数,让其输出到指定的数组,此数组一个记录代表输出的一行,即如果输出结果有20行,则这个数组就有20条记录,所以如果你需要反复输出调用不同系统外部命令的结果,你最好在输出每一条系统外部命令结果时清空这个数组,以防混乱。第三个参数用来取得命令执行的状态码,通常执行成功都是返回0。
方法二:使用system函数执行系统外部命令
原型:function system(string $command,int[optional] $return_value)
1
2
3
<?
system("dir");
?>
知识点:system和exec的区别在于system在执行系统外部命令时,直接将结果输出到游览器,如果执行命令成功则返回true,否则返回false。第二个参数与exec第三个参数含义一样。
方法三:使用函数passthru执行系统外部命令
原型:function passthru(string $command,int[optional] $return_value)
知识点:passthru与system的区别,passthru直接将结果输出到游览器,不返回任何值,且其可以输出二进制,比如图像数据。
方法四:反撇号`(和~在同一个键)执行系统外部命令
1
2
3
<?
echo `dir`;
?>
知识点:在使用这种方法执行系统外部命令时,你要确保shell_exec函数可用,否则是无法使用这种反撇号执行系统外部命令的。
‘叁’ php如何调用外部php文件中的函数
在实验的时候发现是可以的,代码如下
<?php
function func(){ echo "I'm a external function <br />"; }
class Test {
function doExternalFunction($_externalFunc, $_param){
func();
$_externalFunc($_param);
}
}
function sayHello($_param){
echo "hello, $_param";
};
$name = "HanMeiMei";
$test = new Test();
$test->doExternalFunction("sayHello", $name);
?>
在调用Test类实例的doExternalFunction()方法时,外部的func()方法是可以运行的,因为它是全局的。但是建议不要这样使用,
因为Test::doExternalFunction()对func()函数有依赖,当项目比较大时,而func()和Test类没有同时引入到一个文件中来,会引
起错误。比较理想的情况是,使用回调函数的形式来调用外部函数,就像执行在Test::doExternalFunction()执行sayHello()一样
‘肆’ 怎样在一个PHP文件中执行另一个PHP文件
二种方法:
1.在服务器端执行:
即在服务器端PHP文件解析的时候执行,使用include(),require()函数将文件引入
include("thatday.php");
然后调用thatday.php中的主函数
2.在客户端执行:
此方法的效果等同于iframe,即会产对所执行文件的一次访问.
<img src="thatday.php" width="0" height="0" border="0">
‘伍’ 在服务器上用php调用cmd执行某exe文件,求代码!!!!
很多情况下需要php调用其他程序如shell命令、shell脚本、可执行程序等等,此时需要使用到诸如exec/system/popen/proc_open等函数,每种函数有各自适合使用的场景以及需要注意的地方。
前提:PHP没有运行在安全模式
如果PHP运行在安全模式下,那么在执行外部命令、打开文件、连接数据库、基于HTTP的认证这4个方面将会受到制约,可能在调用外部程序时无法获取预期的结果,此时需要设置特定目录,可以在php.ini中编辑safe_mode_exec_dir参数来指定。
1. exec
原型:string exec ( string command [, array &output [, int &return_var]] )
描述:返回值保存最后的输出结果,而所有输出结果将会保存到$output数组,$return_var用来保存命令执行的状态码(用来检测成功或失败)。
例子:$ret = exec("ls -al", $output, $var);
注意:
A. 输出结果会逐行追加到$output中,因此在调用exec之前需要unset($output),特别是循环调用的时候。
B.
如果想通过exec调用外部程序后马上继续执行后续代码,仅仅在命令里加"&"是不够的,此时exec依然会等待命令执行完毕;需要再将标准输出
做重定向才可以,例如:exec("ls -al >/dev/null &", $output, $var);
C.
要学会善用EscapeShellCmd()和EscapeShellArg()。函数EscapeShellCmd把一个字符串
中所有可能瞒过Shell而去执行另外一个命令的字符转义。这些字符在Shell中是有特殊含义的,象分号(|),重定向(>)和从文件读入
(<)等。函数EscapeShellArg是用来处理命令的参数的。它在给定的字符串两边加上单引号,并把字符串中的单引号转义,这样这个字符串
就可以安全地作为命令的参数。
2. system
原型:string system ( string command [, int &return_var] )
描述:执行给定的命令,返回最后的输出结果;第二个参数是可选的,用来得到命令执行后的状态码。
例子:$ret = system("ls -al", $var);
注意:略。
3. passthru
原型:void passthru (string command [, int return_var])
描述:执行给定的命令,但不返回任何输出结果,而是直接输出到显示设备上;第二个参数可选,用来得到命令执行后的状态码。
例子:passthru("ls -al", $var);
注意:略。
4. popen
原型:resource popen ( string command, string mode )
描
述:打开一个指向进程的管道,该进程由派生给定的 command 命令执行而产生。 返回一个和 fopen()
所返回的相同的文件指针,只不过它是单向的(只能用于读或写)并且必须用 pclose() 来关闭。此指针可以用于 fgets(),fgetss()
和 fwrite()。
例子:$fd = popen("command", 'r'); $ret = fgets($fd);
注意:只能打开单向管道,不是'r'就是'w';并且需要使用pclose()来关闭。
5. proc_open
原
型:resource proc_open ( string cmd, array descriptorspec, array
&pipes [, string cwd [, array env [, array other_options]]] )
描述:与popen类似,但是可以提供双向管道。具体的参数读者可以自己翻阅资料,比如该博客:http://hi..com/alex_wang58/blog/item/a28657de16fec55195ee372a.html。
注意:
A. 后面需要使用proc_close()关闭资源,并且如果是pipe类型,需要用pclose()关闭句柄。
B. proc_open打开的程序作为php的子进程,php退出后该子进程也会退出。
C. 笔
者在使用的时候遇到获取外部程序输出阻塞的问题,也就是在例子中的fgets($pipes[1])语句阻塞了,无法继续进行。经过多方查证后发现,问题
一般出在外部程序中,比如外部程序是C程序,使用fprintf(stdin, "****
\n");输出结果,此时需要加上fflush(stdout);才行,否则输出结果可能会暂留缓存中,无法真正输出,而php也就无法获取输出了。
例子:
///< 打开管道
$pwd = "*****";
$pipes = array();
$command = "*****";
$desc = array(array('pipe', 'r'), array('pipe', 'w'), array('pipe', 'w'));
$handle = proc_open($command, $desc, $pipes, $pwd);
if (!is_resource($handle)) {
fprintf(STDERR, "proc_open failed.\n");
exit(1);
}
///< 读写
fwrite($pipes[0], "*****\n");
$ret = rtrim(fgets($pipes[1]), "\n");
///< 关闭管道
fclose($pipes[0]);
fclose($pipes[1]);
fclose($pipes[2]);
proc_close($handle);
‘陆’ 常见WEB攻击之命令注入
即 Command Injection。是指通过提交恶意构造的参数破坏命令语句结构,从而达到执行恶意命令的目的。
在Web应用中,有时候会用到一些命令执行的函数,如php中system、exec、shell_exec等,当对用户输入的命令没有进行限制或者过滤不严导致用户可以执行任意命令时,就会造成命令执行漏洞。
黑客将构造好的命令发送给web服务器,服务器根据拼接命令执行注入的命令,最后讲结果显示给黑客。
以DVWA为例,下面使用ping命令测试IP,正常输入一个IP或者域名会返回一个正常的返回结果。
当输入恶意构造的语句 www..com && netstat -an,会把后面的语句也给执行了:
执行结果:
PHP的常见命令执行函数:
system(),exec(),shell_exec(),passthru()
1、system()
system — 执行外部程序,并且显示输出
常规用法:
使用PHP执行:
php test1.php www..com
exec — 执行一个外部程序
3、shell_exec()
shell_exec — 通过 shell 环境执行命令,并且将完整的输出以字符串的方式返回。
4、passthru()
passthru() 函数与 exec() 函数类似,执行外部程序并且显示原始输出。
Windows:
用^转义<
如果加上单引号会写不进去,如果加双引号会把双引号一起写进去,所以要用^转义<
linux:
linux下需要用来转义<,不过很多php都默认开启gpc,可以先用16进制转换一句话再用xxd命令把16进制还原.
<?php eval($_POST[pass]);>
转换为16进制:
由于我用的是Linux,所以使用payload写入一句话:
写入成功:
1、采用白名单,或使用正则表达式进行过滤。
2、不要让用户可以直接控制eval()、system、exec、shell_exec等函数的参数。
3、在进入执行命令函数和方法前,对变量进行过滤,对敏感字符进行转义。