PHP实现在线端口扫描
字数 792 2025-08-18 11:39:19

PHP实现简易在线端口扫描器教学文档

一、技术原理

PHP通过fsockopen()函数实现端口扫描功能,该函数用于打开网络套接字连接。

fsockopen函数说明

fsockopen(
    string $hostname,
    int $port = -1,
    int &$errno = null,
    string &$errstr = null,
    float $timeout = ini_get("default_socket_timeout")
): resource|false

参数说明:

  • $hostname: 目标主机名或IP地址
  • $port: 要连接的端口号
  • $errno: 错误编号(引用传递)
  • $errstr: 错误信息(引用传递)
  • $timeout: 连接超时时间(秒)

二、实现步骤

1. 获取扫描参数

  • 目标IP地址
  • 待扫描的端口列表(默认值:21,23,25,79,80,110,135,137,138,139,143,443,445,1433,3306)

2. 端口扫描核心逻辑

function getOpenPort($ip, $port) {
    $msg = array('Ftp','Telnet','Smtp','Finger','Http','Pop3','Location Service',
                'Netbios-NS','Netbios-DGM','Netbios-SSN','IMAP','Https',
                'Microsoft-DS','MSSQL','MYSQL');
    
    foreach ($port as $key => $value) {
        echo $value.'&nbsp&nbsp';
        echo $msg[$key].'&nbsp&nbsp';
        $fp = @fsockopen($ip, $value, $errno, $errstr, 0.5);
        $result = $fp ? '<font color="#43CD80"><开启></font><br>' 
                      : '<font color="#FF6347"><关闭></font><br>';
        echo $result;
    }
}

3. SSRF漏洞防护

防止扫描内网地址的黑名单机制:

$blackHostlist = array("172.", "10.", "localhost", "127.", "192.");

foreach($blackHostlist as $blackHost) {
    if(strpos($ip, $blackHost) === 0) {
        echo '<script>alert("禁止扫描内网地址!");</script>';
        die();
    }
}

三、完整代码实现

前端表单 (index.html)

<form method="post" action="scan.php">
    目标IP - IP Address: <input type="text" name="ip" id="domain"><br><br>
    扫描端口 - Ports: <input type="test" name="port" value="21,23,25,79,80,110,135,137,138,139,143,443,445,1433,3306"><br><br>
    开始扫描 - Start: <input type="submit" value="点击开始扫描 - Scaning">
</form>

后端处理 (scan.php)

<?php
function getOpenPort($ip, $port) {
    $msg = array('Ftp','Telnet','Smtp','Finger','Http','Pop3','Location Service',
                'Netbios-NS','Netbios-DGM','Netbios-SSN','IMAP','Https',
                'Microsoft-DS','MSSQL','MYSQL');
    
    foreach ($port as $key => $value) {
        echo $value.'&nbsp&nbsp';
        echo $msg[$key].'&nbsp&nbsp';
        $fp = @fsockopen($ip, $value, $errno, $errstr, 0.5);
        $result = $fp ? '<font color="#43CD80"><开启></font><br>' 
                      : '<font color="#FF6347"><关闭></font><br>';
        echo $result;
    }
}

$ip = $_POST['ip'];
$port = explode(',', $_POST['port']);

$blackHostlist = array("172.", "10.", "localhost", "127.", "192.");
foreach($blackHostlist as $blackHost) {
    if(strpos($ip, $blackHost) === 0) {
        echo '<script>alert("禁止扫描内网地址!");</script>';
        die();
    }
}

getOpenPort($ip, $port);
?>

四、关键点说明

  1. 超时设置fsockopen的timeout参数设置为0.5秒,平衡响应速度和准确性

  2. 错误抑制:使用@符号抑制连接失败时的错误输出

  3. 端口服务映射:数组$msg将端口号映射为常见服务名称

  4. 结果可视化:使用不同颜色区分开放(绿色)和关闭(红色)的端口

  5. 输入处理:将逗号分隔的端口字符串转换为数组explode(',', $_POST['port'])

五、安全注意事项

  1. SSRF防护必须实现,防止被用来扫描内网

  2. 可扩展的黑名单:可根据需要添加更多内网IP段

  3. 输入验证:建议增加对IP地址格式的验证

  4. 权限控制:实际应用中应考虑添加身份验证机制

  5. 日志记录:记录扫描请求,便于审计

六、优化建议

  1. 增加多线程/异步扫描提高效率
  2. 添加扫描进度显示
  3. 实现更友好的错误处理
  4. 增加扫描历史记录功能
  5. 添加端口描述信息的自动获取

这个简易端口扫描器适合学习网络编程基础,实际生产环境使用需要考虑更多安全性和性能因素。

PHP实现简易在线端口扫描器教学文档 一、技术原理 PHP通过 fsockopen() 函数实现端口扫描功能,该函数用于打开网络套接字连接。 fsockopen函数说明 参数说明: $hostname : 目标主机名或IP地址 $port : 要连接的端口号 $errno : 错误编号(引用传递) $errstr : 错误信息(引用传递) $timeout : 连接超时时间(秒) 二、实现步骤 1. 获取扫描参数 目标IP地址 待扫描的端口列表(默认值:21,23,25,79,80,110,135,137,138,139,143,443,445,1433,3306) 2. 端口扫描核心逻辑 3. SSRF漏洞防护 防止扫描内网地址的黑名单机制: 三、完整代码实现 前端表单 (index.html) 后端处理 (scan.php) 四、关键点说明 超时设置 : fsockopen 的timeout参数设置为0.5秒,平衡响应速度和准确性 错误抑制 :使用 @ 符号抑制连接失败时的错误输出 端口服务映射 :数组 $msg 将端口号映射为常见服务名称 结果可视化 :使用不同颜色区分开放(绿色)和关闭(红色)的端口 输入处理 :将逗号分隔的端口字符串转换为数组 explode(',', $_POST['port']) 五、安全注意事项 SSRF防护 必须实现,防止被用来扫描内网 可扩展的黑名单 :可根据需要添加更多内网IP段 输入验证 :建议增加对IP地址格式的验证 权限控制 :实际应用中应考虑添加身份验证机制 日志记录 :记录扫描请求,便于审计 六、优化建议 增加多线程/异步扫描提高效率 添加扫描进度显示 实现更友好的错误处理 增加扫描历史记录功能 添加端口描述信息的自动获取 这个简易端口扫描器适合学习网络编程基础,实际生产环境使用需要考虑更多安全性和性能因素。