每天一点小知识合集

1、审计dvwa高难度命令执行漏洞的代码,编写实例说明如下函数的用法

image-20231121163856661

第一部分

$_POST['Submit'] 被调用时,变量 $target 将被设置为用户输入的 IP 地址。

if( isset( $_POST[ 'Submit' ]  ) ) {
    $target = trim($_REQUEST[ 'ip' ]);

第二部分

从用户输入中移除特殊字符,例如 '&'';''|''-''$''('')' 、 和 '||'

    $substitutions = array(
        '&'  => '',
        ';'  => '',
        '| ' => '',
        '-'  => '',
        '$'  => '',
        '('  => '',
        ')'  => '',
        '`'  => '',
        '||' => '',
    );
	$target = str_replace( array_keys( $substitutions ), $substitutions, $target );

第三部分

这部分代码的作用是根据当前操作系统的类型,选择相应的命令进行网络测试。如果当前操作系统是 Windows,那么使用 ping 命令进行测试;否则,使用 ping -c 4 命令进行测试。其中,$target 是需要测试的目标主机的 IP 或域名。

if( stristr( php_uname( 's' ), 'Windows NT' ) ) {
    // Windows
    $cmd = shell_exec( 'ping  ' . $target );
}
else {
    // *nix
    $cmd = shell_exec( 'ping  -c 4 ' . $target );
}

第四部分

这部分代码的作用是将测试结果输出给用户。<pre> 标签用于显示预格式化文本,可以保留文本中的空格和换行符,使输出结果更清晰易读

// Feedback for the end user
echo "<pre>{$cmd}</pre>";

各部分的函数详解:

isset()          //函数用于检测变量是否已设置并且非 NULL
trim()           //去除字符串首尾处的空白字符(或者其他字符)
$substitutions() //是一个关联数组,它包含了一组需要被替换的字符串键值对。键是需要被替换的字符串,值是替换后的字符串 
array_keys($substitutions) //函数会返回$substitutions数组中的所有键,也就是需要被替换的字符串组成的数组。
含义部分:
str_replace()函数会在$target字符串中查找$substitutions数组中的键,然后用对应的值进行替换。具体来说,str_replace( array_keys( $substitutions ), $substitutions, $target )这行代码的作用是将$target字符串中出现的$substitutions数组中的键,替换为对应的值。

举例说明:
str_replace( $search , $replace , $subject )
$search:需要被替换的字符串或字符数组。
$replace:用来替换的字符串或字符数组。
$subject:需要进行替换操作的字符串或字符串数组。
str_replace 函数会在 $subject 字符串中查找 $search,并用 $replace 进行替换。如果 $search 和 $replace 是数组,那么 str_replace 会对 $search 和 $replace 数组中的元素进行一一对应的替换。
stristr()  //函数搜索字符串在另一字符串中的第一次出现。该函数是不区分大小写的。若进行区分大小写的搜索使用 strstr() 函数。

举例:
<?php
	echo stristr("Hello world!","WORLD");   //查找 "world" 在 "Hello world!" 中的第一次出现,并返回字符串的剩余部分
?>
php_uname() 函数返回一个字符串,包含当前操作系统的相关信息,具体内容取决于参数的值。例如,如果参数为 "s",则返回当前操作系统的名称。

2、审计impossible难度的代码,说明其中函数的作用,不要求每个函数都演示

image-20231121172213864

第一部分

if( isset( $_POST[ 'Submit' ]  ) ) {
    // Check Anti-CSRF token
    checkToken( $_REQUEST[ 'user_token' ], $_SESSION[ 'session_token' ], 'index.php' );   //在用户提交的请求中获取了一个名为 user_token 的令牌,然后与用户会话中的 session_token 进行比对,以确保请求的合法性。如果验证失败,可能会将用户重定向至 index.php 页面。这样做有助于保护网站免受 CSRF 攻击的威胁。

    // Get input
    $target = $_REQUEST[ 'ip' ];
    $target = stripslashes( $target );  //去除 IP 地址中的反斜杠。

    // Split the IP into 4 octects
    $octet = explode( ".", $target );  // 这里用 '.' 将 IP 地址进行了分割。

第二部分

这段代码的含义是检查数组 $octet 中的前四个元素是否都是数字,并且数组的大小是否为 4。如果所有这些条件都满足,那么条件语句的结果将为真(true)。然后在下面使用"."再将每一部分的数组内容连接起来。用于验证一个 IP 地址是否符合 IPv4 地址的格式,因为 IPv4 地址由四块由点分隔的数字组成。

// Check IF each octet is an integer
    if( ( is_numeric( $octet[0] ) ) && ( is_numeric( $octet[1] ) ) && ( is_numeric( $octet[2] ) ) && ( is_numeric( $octet[3] ) ) && ( sizeof( $octet ) == 4 ) ) {
        // If all 4 octets are int's put the IP back together.
        $target = $octet[0] . '.' . $octet[1] . '.' . $octet[2] . '.' . $octet[3];

第三部分

这部分和high级别一样,之前做过说明了,此处就不做解释

// Determine OS and execute the ping command.
        if( stristr( php_uname( 's' ), 'Windows NT' ) ) {
            // Windows
            $cmd = shell_exec( 'ping  ' . $target );
        }
        else {
            // *nix
            $cmd = shell_exec( 'ping  -c 4 ' . $target );
        }
           // Feedback for the end user
        echo "<pre>{$cmd}</pre>";

第四部分

else {
        // Ops. Let the user name theres a mistake
        echo '<pre>ERROR: You have entered an invalid IP.</pre>';
    }
}

// Generate Anti-CSRF token
generateSessionToken();

checkToken()   //作用是验证用户提交的令牌是否有效,以防止 CSRF(跨站请求伪造)攻击。
stripslashes() //函数用于移除字符串中的反斜杠(\)。它的作用是将转义过的字符还原为原始的字符形式
explode()      //函数使用一个字符串分割另一个字符串,并返回由字符串组成的数组。
is_numeric()   //函数用于检测变量是否为数字或数字字符串。
generateSessionToken() 是一个函数,用于生成一个随机的会话令牌(session token),通常用于在 Web 应用程序中保持用户会话的状态。

3、演示命令执行漏洞无回显如何渗透

这里构造了一个代码,呈现出一个命令执行漏洞的页面

<?php
if(isset($_GET['cmd'])){
    $cmd=$_GET['cmd'];
    `$cmd`;
}else{
    echo"?cmd=whoami";
}

?>

当我们访问页面的时候,正常显示代码

image-20231121195235873

从构造来看我们可以借助cmd这个参数来完成命令执行,但是当我们实验的时候,发现结果无法回显在页面上

image-20231121195400722

这里为了证明命令执行漏洞存在,我们可以借助yakit工具实现

image-20231121195448897

我们在yakit的dnslog模块中,新生成一个可用域名,然后我们使用刚刚的页面,对这个域名进行ping命令

image-20231121195558202

ping命令执行后,我们回到yakit页面,点击刷新,发现就在刚刚这个时间点,有一个ip就ping了一下这个刚生成的域名,从侧面证实了命令执行漏洞的存在。

image-20231121195827423

4、编写PHP代码,实现反序列化的时候魔法函数自动调用计算器

以下代码定义了一个简单的类 MyClass,并对该类进行了序列化和反序列化的操作。在实例化对象时,传入的名称为 “Alice”,然后将对象序列化为字符串。接着,使用 unserialize() 函数将序列化的字符串转换回对象,并自动调用了 __wakeup() 方法。

<?php
class MyClass {
    public $name;

    public function __construct($name) {
        $this->name = $name;
    }
    
    
    public function __wakeup() {    // 当调用unserialize()函数时,如果对象中定义了__wakeup()方法,该方法会在反序列化过程中被自动调用
        echo 'what do fuck you say?';          //输出一段字符串用于证明魔法函数成功调用
        system('calc');       //调用一个计算器
    }
}

// 将对象序列化为字符串
$serializedData = serialize(new MyClass("Alice"));

// 反序列化并调用对象的 __wakeup() 方法
$object = unserialize($serializedData);
?>
代码讲解部分:
1.class MyClass { ... }:定义了一个名为 MyClass 的 PHP 类。
2.public $name;:声明了一个公共属性 $name,用于存储对象的名称。
3.public function __construct($name) { ... }:定义了一个构造函数 __construct(),用于在对象实例化时初始化对象的属性。
4.$this->name = $name;:在构造函数中,将传入的名称赋值给对象的 $name 属性。
5.public function __wakeup() { ... }:定义了一个特殊的魔术方法 __wakeup(),该方法会在对象被反序列化后自动调用。
6.echo 'what do fuck you say?'; :在 __wakeup() 方法中,输出一条消息,证明魔法函数被调用了。

此时当我们打开这个页面的时候,就会发现自动弹出计算器,页面上也显示了我们设置的字符串。

image-20231121202621130

5、尝试回答什么是PHP反序列化漏洞

反序列化是将序列化的数据转换回其原始的数据结构或对象的过程。在 PHP 中,可以使用 serialize() 函数将对象或数据结构序列化为字符串,然后使用 unserialize() 函数将其反序列化。

而由于开发者在编写反序列化代码的时候,有时候不经意间会加入一些恶意的代码。从而导致可能出现的反序列化漏洞。

序列化和反序列化本身是为了实现数据在网络上完整高效的传输,但是由于反序列化过程中,对象的魔术方法会自动调用,魔术方法本身调用了别的方法,最终呈现一种链式调用,直到执行任意的代码或者命令。

  • 10
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值