超硬核:深入讲解Perl安全之代码审计——perl脚本中存在的问题与存在的安全风险

博主:鴻漸之翼
个人介绍:男,搞底層的FW,喜歡發一點沒用的東西。

介绍:

程序设计语言通常不构成安全风险,风险是由程序员带来的。几乎每种语言都有某些缺陷,这些缺陷在某种程度上可能有助于创建不安全的软件,但软件的整体安全性仍然在很大程度上取决于开发者的安全意识。Perl也有安全“陷阱”,然而大多数Perl程序员并不了解这些陷阱。

在本文中,我们将介绍一些被广泛误用和忽视的Perl特性。本文将展示perl语言不正确的使用方式,错误使用方式又是如何对运行程序的用户,及系统构成威胁。本文也会展示如何利用这些漏洞,以及如何修复或避免它们。

基本用户输入漏洞

Basic user input vulnerabilities

Perl脚本中安全问题的一个主要来源是未正确验证(或未验证)的用户输入。任何时候你的程序可能会从一个不受信任的用户那里获取输入,即使是间接的,你都应该小心。例如,如果我们使用Perl编写CGI脚本,那么恶意用户可能会向您发送虚假输入。

如果未经验证就使用,对此类应用程序的不当输入就可能会导致许多问题。在没有正确验证的情况下,使用用户提供的参数执行其他程序,使最常见的错误。

system() 和exec()函数

Perl语言以其“粘贴语言”而出名,它可以出色地调用其他程序来帮协助完成它的工作。通过收集一个程序的输出,以特定的方式重新格式化,并将其作为输入传递给其他程序,仔细地协调它们的活动,从而使一切都能顺利运行。
执行外部程序或系统命令的一种方法是调用exec()函数。当Perl遇到exec()语句时,它会查看调用exec()时使用的参数,然后启动一个执行指定命令的新进程。Perl从不将控制权返回到调用exec()的原始进程。
另一个类似的函数是system(),system()与exec()函数非常相像。唯一的区别是perl首先从父进程中派生一个子进程。父进程等待着子进程结束,然后继续执行程序的其他部分。
下面我们将详细讨论system()与exec()的函数调用。

给system()函数运行的是一个列表。
system()抽象列表
1.程序名称
2.其余元素(作为传递参数传递给程序)
如果只要一个参数,system()调用方式会有不同。这种情况下
perl会扫描参数,查看是否含有shell字符。如果是则继续解释,perl将生成一个命令shell,如果perl不了解特殊的shell字符,perl会将字符串分解成单词,并调用更高效的C库调用execvp()

假设我们有一个CGI表单,它要求输入用户名, 并显示一些包含该用户统计信息的文件。我们可以使用system()调用cat。

 system ("cat /usr/stats/$username"); 

$username来自以下表单:

 $username = param ("username");

用户填写表单时,例如;username=jdimov,然后提交表单。
perl在字符串”cat /usr/stats/jdimov“中找不到任何元字符,它运行cat程序,然后返回脚本。这个脚本看起来无害,但实际上可能被恶意攻击者利用。问题在于,通过表单的‘username’字段中使用特殊的字符,攻击者可以通过shell执行任意命令。
例如,假设攻击者发送字符串"jdimov; cat /etc/passwd"。
perl将分号识别为元字符,并传递给shell

  cat /usr/stats/jdimov; cat /etc/passwd

攻击者同时获得虚拟统计文件和密码文件。如果想具有破坏性,我们可以祭出“rm -rf”。
前面提到过,system()接受一个参数列表,并将第一个元素作为命令执行,将其余元素作为参数传给它,我们只需要稍微更改脚本,以便执行我们的程序。

  system ("cat", "/usr/stats/$username");

因此我们分别为程序指定每个参数,所以永远不会调用shell。所以使得rm -rf不管用,因为攻击字符串被解释为文件名。
这种方法比单参数版本要好得多,因为它避免了使用shell,但仍然存在潜在的缺陷。特别是,我们需要担心username的值是否会被用来利用正在执行的程序(在本例中为“cat”)的弱点。例如,攻击者仍然可以通过将$username设置为字符串“…/…/etc/passwd”,利用我们重写的代码来显示系统密码文件。

根据程序的不同,许多其他事情可能会出错。例如,一些应用程序将特殊字符序列解释为执行shell命令的请求。一个常见的问题是,某些版本的Unix“mail”实用程序,在看到~!上下文中的转义序列。因此,用户输入包含!rm -”在某些情况下可能会导致问题。
就安全性而言,上面提到的 system()函数同样适用于exec()

open()函数

Perl中的open()函数用于打开文件。在最常见的形式中,它的使用方式如下:


                
评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

IT鹅

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

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

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

打赏作者

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

抵扣说明:

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

余额充值