当前位置: 首页 > news >正文

SQLMap自动化注入实战:从Kali配置到高级参数与WAF绕过

1. 项目概述与核心价值

如果你刚接触网络安全,或者对渗透测试感兴趣,那么“SQL注入”这个词你一定不陌生。它就像一把能打开许多老旧网站后门的万能钥匙,而SQLMap就是自动化挥舞这把钥匙的顶级工匠。很多人听说过它,也看过一些零散的教程,但真正能把它用透、用精,在实战中游刃有余的人并不多。问题往往出在:工具装上了,命令也敲了,但面对一个真实的、有防护的网站时,却不知道从何下手,或者面对一堆参数选项感到迷茫。

这正是我写这篇指南的初衷。这不是一篇简单的“安装-运行”说明书,而是一份基于我在实际渗透测试和授权安全评估中,使用Kali Linux配合SQLMap进行自动化注入的深度实战手册。我们将彻底抛弃“依葫芦画瓢”式的学习,从零开始,不仅告诉你每个参数怎么用,更会深入剖析背后的原理、在不同场景下的策略选择,以及那些只有踩过坑才知道的细节技巧。无论你是想系统学习Web安全的学生,还是希望提升实战能力的安服工程师,这篇文章都将带你跨越从“知道”到“精通”的鸿沟,让你真正掌握SQLMap这把利器的灵魂。

2. Kali Linux环境深度配置与优化

工欲善其事,必先利其器。Kali Linux作为渗透测试的“瑞士军刀”,其开箱即用的特性为我们提供了极大便利,但针对SQLMap的高效使用,我们仍需进行一些深度配置,这能让你在后续的实战中事半功倍。

2.1 系统初始化与网络环境搭建

Kali Linux预装了海量工具,但默认设置可能不完全符合个人习惯或特定任务需求。首先,我强烈建议在虚拟机(如VMware或VirtualBox)中安装Kali,这能提供一个干净、可快照恢复的沙箱环境。关于虚拟机内存,对于运行Kali并执行SQLMap这类工具,4GB是底线,8GB或以上会获得更流畅的体验,尤其是在处理大量数据或开启多个复杂任务时。

安装完成后,第一件事是更新系统并配置稳定的软件源。打开终端,执行以下命令:

sudo apt update && sudo apt full-upgrade -y

这个操作会更新软件包列表并升级所有可升级的包。full-upgradeupgrade更彻底,它会处理因依赖关系变化而需要安装或移除的包。更新过程可能较长,请耐心等待。

接下来是网络配置。SQLMap在探测和注入过程中会产生大量网络请求。为了确保稳定性和速度,并为可能的流量分析做准备,我习惯为Kali配置一个独立的、仅主机的网络适配器(在虚拟机设置中添加),同时保留一个NAT适配器用于访问互联网。这样,测试流量和日常流量可以分离。

注意:在进行任何安全测试前,务必确保你拥有目标的明确授权。未经授权的测试是非法行为。本文所有技术讨论均基于授权测试、CTF竞赛或自有实验环境。

2.2 SQLMap的安装、验证与版本管理

Kali Linux默认已经集成了SQLMap,你可以直接在终端输入sqlmap来启动它。但是,默认仓库的版本可能不是最新的。SQLMap项目在GitHub上活跃更新,经常修复漏洞和添加新功能。因此,从GitHub克隆最新版本是专业玩家的常见做法。

首先,检查当前版本:

sqlmap --version

如果提示版本过旧(例如,低于最新的稳定版),或者你想使用开发版特性,可以按以下步骤操作:

  1. 克隆最新代码

    cd /opt # 通常将第三方工具放在/opt目录下 sudo git clone --depth 1 https://github.com/sqlmapproject/sqlmap.git sqlmap-dev

    这里使用--depth 1只克隆最近的一次提交,节省时间和空间。

  2. 创建便捷启动脚本: 为了能方便地使用自定义路径下的sqlmap,可以创建一个别名或软链接。

    echo “alias sqlmap-dev=‘python3 /opt/sqlmap-dev/sqlmap.py’” >> ~/.zshrc # 如果你使用Zsh # 或者,如果你使用Bash: # echo “alias sqlmap-dev=‘python3 /opt/sqlmap-dev/sqlmap.py’” >> ~/.bashrc source ~/.zshrc # 或 source ~/.bashrc

    现在,你可以通过sqlmap-dev命令来启动最新版的SQLMap,而系统的sqlmap命令保持不变,作为稳定后备。

  3. 解决依赖问题: SQLMap基于Python,通常依赖都已内嵌。但如果遇到类似“缺少某个模块”的错误,可以使用pip安装:

    pip3 install -r /opt/sqlmap-dev/requirements.txt

实操心得:我通常会同时保留系统版和开发版。日常学习和小规模测试用系统版,因为它更稳定。当遇到新奇的WAF(Web应用防火墙)或者需要尝试某个刚发布的新参数时,就切换到开发版。曾经在一次授权测试中,系统版SQLMap对某个云WAF绕不过去,切换到当天刚更新的开发版,利用其新增的一个--tamper脚本就成功绕过了,这让我深刻体会到跟进最新版本的重要性。

2.3 辅助工具配置与工作流整合

SQLMap不是孤岛。高效的渗透测试者会将它融入一个工具链中。这里介绍几个必备的“搭档”:

  1. Burp Suite:这是最重要的搭档。将浏览器代理设置为Burp,拦截你对目标网站的请求,然后将整个HTTP请求(包括Cookie、Headers)保存到一个文本文件(例如request.txt),再交给SQLMap使用-r参数加载。这完美解决了复杂登录状态、Token验证等问题。
  2. 浏览器插件:如“Copy as cURL”或“HackTools”。它们可以一键将浏览器中的请求转换为cURL命令或SQLMap格式的命令,极大提升效率。
  3. 自定义脚本:编写简单的Bash或Python脚本,用于批量处理目标URL列表,或者自动格式化SQLMap的输出结果。例如,一个脚本可以读取文件中的URL,依次进行基础扫描,并将有注入点的结果单独保存。

配置好这些,你的Kali Linux就不再是一个简单的工具集合,而是一个高效的自动化测试工作站。

3. SQLMap核心机制与参数哲学深度解析

很多教程只是罗列参数,这就像给你一把枪却不教你怎么瞄准。要精通SQLMap,必须理解它的工作逻辑和每个参数背后的设计意图。

3.1 SQLMap的工作流程剖析

当你对SQLMap下达一个指令时,它在后台执行的是一个高度智能化的流程。理解这个流程,你才能预判它的行为,并在出现问题时进行有效干预。

  1. 启发式检测:SQLMap首先会发送一些精心构造的、但通常无害的请求(如添加等),观察服务器的响应。它会检查响应中的HTTP状态码、响应时间、页面内容差异(通过对比算法)、以及数据库报错信息(如MySQL、Oracle的特定错误格式)。这个阶段的目标是判断目标“是否可能存在注入点”,以及“可能是哪种数据库”。
  2. 布尔盲注与时间盲注检测:如果第一步没有发现明显回显或报错,SQLMap会自动尝试布尔盲注。它会发送诸如… AND 1=1… AND 1=2这样的请求,通过对比两个请求返回页面内容的差异(哪怕只是一个单词、一个空格的不同)来判断条件真假。如果连内容差异都无法检测,它会尝试时间盲注,通过… AND SLEEP(5)这类语句,观察响应时间是否延迟,从而判断注入是否成功。
  3. 注入点参数定位与技术确认:一旦确认存在注入可能,SQLMap会尝试确定具体的注入点(是GET参数、POST参数、Cookie还是HTTP头),并测试所有可用的SQL注入技术(如联合查询、堆叠查询、报错注入等),找出最高效的一种。
  4. 指纹识别与数据库枚举:确认注入后,SQLMap会尝试获取数据库的版本、当前用户、当前数据库名等信息。这就像在进入一栋大楼后,先看看楼层指示牌。
  5. 数据提取:这是最终目的。SQLMap会利用已确认的注入技术,系统地枚举数据库中的表名、列名,并最终导出数据。它支持多种提取方式,并可以智能地处理大数据表的分块下载。

3.2 关键参数分类精讲与实战场景匹配

SQLMap的参数多达上百个,但掌握核心的20%,就能解决80%的问题。下面我将它们分类,并结合实战场景讲解。

第一类:目标指定(必须掌握)

  • -u “URL”:最基础用法,指定一个包含参数的URL,如-u “http://target.com/page.php?id=1”
  • -r request.txt强烈推荐。从Burp Suite等工具保存的请求文件中读取目标。这包含了所有Headers、Cookies、POST数据,是处理需要认证或复杂请求的唯一可靠方式
  • -g “google dork”:让SQLMap自动使用Google搜索可能存在注入的页面。慎用,且需确保你的网络和代理设置允许,并严格遵守法律和道德规范。
  • -l logfile:从一个由其他工具(如爬虫)生成的日志文件中读取多个目标URL进行批量测试。

第二类:注入检测与优化(提升效率)

  • --level--risk:这是SQLMap的“智能等级”开关。
    • --level(1-5):控制测试的广度。等级越高,SQLMap会测试越多的注入点(如HTTP Referer头、User-Agent头)和使用更多的payload。对于普通GET参数,level 1足够;对于需要Cookie或复杂POST的,建议从level 2开始;检查HTTP头注入则需要level 3或以上。
    • --risk(1-3):控制测试的深度/风险。风险越高,SQLMap会使用更具侵入性、可能造成数据修改或破坏的payload(如OR 1=1可能导致大量数据返回)。默认risk为1,大多数情况够用。除非在完全可控的测试环境,否则不要轻易使用risk 3
  • --technique:指定使用的注入技术。例如--technique=B只使用布尔盲注,--technique=BEUSTQ按顺序尝试布尔、报错、联合、堆叠、时间盲注和内联查询。当你通过手动测试已经知道目标适用哪种技术时,用这个参数可以极大加快速度
  • --dbms:如果你已经知道目标数据库类型(如MySQL、Microsoft SQL Server、Oracle),用--dbms=mysql直接告诉SQLMap,它能跳过指纹识别,直接使用针对该数据库的payload,效率倍增。

第三类:数据提取与控制(核心攻击面)

  • --dbs:枚举所有数据库名。
  • -D database_name:指定要操作的数据库。
  • --tables:枚举指定数据库中的所有表。
  • -T table_name:指定要操作的表。
  • --columns:枚举指定表中的所有列。
  • -C column1,column2:指定要提取的列。
  • --dump:提取数据。可以配合-D, -T, -C精确提取,也可以直接用--dump-all导出一切(不推荐,动静太大)。
  • --batch自动化神器。启用后,SQLMap在遇到需要用户选择(如检测到多种注入技术,问你用哪个)时会自动选择默认项,让整个过程无需人工干预,适合批量脚本。

第四类:规避与对抗(实战精华)

  • --tamper这是应对WAF的魔法棒。Tamper脚本用于对payload进行混淆、编码,以绕过常见的WAF过滤规则。例如:
    • --tamper=space2comment:用/**/替换空格。
    • --tamper=between:用BETWEEN替换>比较符。
    • --tamper=charencode:对payload进行URL编码。
    • 可以组合使用:--tamper=space2comment,between
    • SQLMap自带50多个tamper脚本,存放在/usr/share/sqlmap/tamper/(或你克隆目录的对应位置)。高级用法是研究这些脚本的代码,并根据目标WAF的特点自己编写或组合tamper
  • --random-agent:在每个请求中使用随机的User-Agent字符串,避免因固定UA被简单封禁。
  • --delay--timeout--delay 1表示每个请求间隔1秒,可以降低请求频率,避免触发速率限制。--timeout设置请求超时时间。
  • --proxy:通过代理服务器发送请求,可用于隐藏真实IP或调试流量。例如--proxy=”http://127.0.0.1:8080″将流量发送到Burp Suite,方便你观察SQLMap具体发送了什么payload。

参数组合心法:不要死记硬背命令。理解场景:对于一个需要登录的搜索功能进行注入测试,我的典型命令演进可能是:

  1. 用Burp抓取搜索请求,保存为search.req
  2. 初步探测:sqlmap -r search.req --batch --level 2 --risk 1(保守探测)。
  3. 如果发现注入点但被WAF拦截,升级:sqlmap -r search.req --batch --level 3 --risk 2 --tamper=space2comment,randomcase --random-agent(增加检测范围,使用混淆,随机UA)。
  4. 确认注入并获取数据库名:sqlmap -r search.req --batch --dbs
  5. 精准提取某个表的数据:sqlmap -r search.req --batch -D customer_db -T users -C username,password --dump

4. 全流程实战案例:从信息收集到数据提取

让我们通过一个模拟的实战场景,将上述所有知识串联起来。假设目标是一个名为vulnapp.test的虚拟测试网站,其上有一个需要登录后才能访问的“用户详情查看”页面,URL格式为http://vulnapp.test/user.php?id=USER_ID

4.1 第一阶段:信息收集与目标确认

首先,我们需要手动浏览网站,了解其功能。注册一个账号并登录。登录后,点击查看自己的用户详情,此时浏览器地址栏显示http://vulnapp.test/user.php?id=123。这个id参数看起来就是我们的潜在目标。

关键一步:使用Burp Suite拦截请求。打开Burp,配置浏览器代理,确保拦截(Intercept)开启。然后在浏览器中刷新用户详情页面。Burp会捕获到这个GET请求。仔细观察这个请求,你会发现除了URL,HTTP头部还包含了Cookie: session=abcde12345...等重要信息。这正是维持登录状态的关键。

在Burp的拦截窗口或历史记录中,右键点击这个请求,选择 “Copy to file”,将其保存为user.req。这个文件包含了SQLMap所需的一切:目标URL、方法和最重要的会话Cookie。

4.2 第二阶段:初步探测与注入点验证

现在,回到Kali Linux的终端。我们使用最基本的命令进行探测:

sqlmap -r /path/to/user.req --batch

这里使用了-r--batch-r确保了我们的请求带有正确的会话,模拟了已登录用户的行为。--batch让SQLMap自动处理所有交互。

SQLMap会开始它的启发式检测。在输出中,你会看到类似这样的信息:

[INFO] testing connection to the target URL [INFO] checking if the target is protected by some kind of WAF [INFO] testing if the target URL content is stable [INFO] testing if GET parameter ‘id’ is dynamic [INFO] heuristic (basic) test shows that GET parameter ‘id’ might be injectable ... [INFO] GET parameter ‘id’ is ‘MySQL >= 5.0.12 AND time-based blind (query SLEEP)’ injectable

太好了!它不仅发现id参数存在注入,还识别出数据库是MySQL,并且时间盲注技术有效。这是一个典型的盲注场景,因为页面可能不会直接显示数据库错误或查询结果。

4.3 第三阶段:绕过防御与深度枚举

假设在上一步中,SQLMap报告检测到了WAF(Cloudflare等)。我们需要启用规避策略。

sqlmap -r /path/to/user.req --batch --tamper=space2comment,randomcase --random-agent --delay 1
  • --tamper=space2comment,randomcase:组合使用两个脚本,混淆payload。
  • --random-agent:避免被基于UA的简单规则屏蔽。
  • --delay 1:每次请求等待1秒,降低请求频率,显得更“像人”。

现在,开始枚举信息。首先获取有哪些数据库:

sqlmap -r /path/to/user.req --batch --dbs

输出可能显示:

available databases [2]: [*] information_schema [*] vulnapp_db

我们的目标很可能是vulnapp_db。接着,枚举这个数据库里的表:

sqlmap -r /path/to/user.req --batch -D vulnapp_db --tables

输出可能包含users,products,logs等表。users表显然是高价值目标。查看它的结构:

sqlmap -r /path/to/user.req --batch -D vulnapp_db -T users --columns

输出会列出所有列,如id,username,password_hash,email等。

4.4 第四阶段:数据提取与结果处理

最后,提取我们关心的数据,比如用户名和密码哈希:

sqlmap -r /path/to/user.req --batch -D vulnapp_db -T users -C username,password_hash --dump

SQLMap会开始提取数据。对于时间盲注,这个过程会比较慢,因为它需要逐个字符进行猜测和验证。你可以看到它实时的进度。提取完成后,SQLMap会将数据以表格形式显示在终端,并默认保存到本地CSV和HTML文件中,路径通常在~/.sqlmap/output/vulnapp.test/目录下。这个自动保存的功能非常贴心,确保了工作成果不会丢失。

至此,我们完成了一次完整的、从认证界面到数据提取的SQL注入自动化攻击链。这个过程清晰地展示了如何将工具、参数和实战流程结合起来。

5. 高级技巧、疑难排错与防御视角

掌握了基本流程,我们来看看那些能让你的操作更上一层楼的高级技巧,以及如何解决常见问题。

5.1 高级参数与场景化应用

  1. 二阶SQL注入:有时注入点不在最初输入的地方,而是在数据被存储后,在另一个页面或功能中被调用时触发。SQLMap支持二阶注入测试,使用--second-order参数指定一个触发URL。例如,你在用户资料页的“昵称”字段注入了一个payload,但这个payload只有在其他用户查看你的资料页时才执行。你需要分析业务流,找到触发点。
  2. 自定义Payload和边界符:如果目标的SQL查询非常特殊,你可以使用--prefix--suffix参数来指定payload前后需要添加的字符串,以构造出合法的SQL语句。这需要对目标代码的SQL拼接方式有较深猜测或了解。
  3. 优化性能:对于盲注,--threads参数可以设置多线程(如--threads 5)来加快枚举速度,但会增加目标负载和被发现的风险。--predict-output参数可以让SQLMap尝试预测常见值的输出格式(如admin),从而减少请求次数。
  4. 从数据库中读取文件:在特定权限下(如MySQL的FILE_PRIV),可以利用注入点读取服务器上的文件。命令如--file-read “/etc/passwd”这是高危操作,仅用于授权测试的核心阶段
  5. 执行操作系统命令:在极少数情况下(如SQL Server的xp_cmdshell被启用),甚至可以通过注入点执行系统命令(--os-cmd,--os-shell)。这标志着已获得对服务器的极高控制权。

5.2 常见错误、警告与排查指南

即使按照教程操作,你也一定会遇到各种报错。下面是一些常见问题及解决思路:

问题/错误信息可能原因排查与解决思路
[CRITICAL] connection timed out to the target URL目标无法访问、网络问题、被防火墙阻断、--timeout设置太短。1. 用pingcurl手动检查目标可达性。
2. 检查Burp代理或--proxy设置是否正确。
3. 增加--timeout值(如--timeout 30)。
4. 确认测试是否被目标IP封禁,考虑使用代理池。
[WARNING] the testable parameter ‘X’ you provided is not into the Cookie使用-u参数但目标需要Cookie,或者-r文件中的Cookie已过期。永远优先使用-r参数,并确保从Burp导出的请求是登录后的最新会话。手动更新请求文件中的Cookie值。
[INFO] heuristic test shows that the target might not be injectable目标确实不存在注入点,或者WAF/过滤规则非常严格,阻止了探测请求。1. 尝试提高--level--risk
2. 使用--tamper脚本组合进行混淆。
3. 尝试--technique=U(联合查询)或--technique=T(时间盲注)单独测试。
4. 手动测试,确认参数是否真的动态影响输出。
[ERROR] invalid value for ‘–tamper’Tamper脚本名称拼写错误,或该脚本不在SQLMap的tamper目录中。检查拼写。使用sqlmap --list-tampers查看所有可用脚本名。确保自定义脚本路径正确。
进程卡在某个百分比很久通常是遇到了网络波动、目标响应慢、或盲注时某个字符的猜测遇到困难。1. 观察控制台输出,看是否在不断重试某个请求。
2. 可以适当增加--timeout
3. 对于盲注,可以尝试使用--hex参数,有时非ASCII字符会导致问题。
4. 如果确认卡住,可以Ctrl+C中断,使用--sql-shell手动尝试查询,或调整-C指定更少的列。
your sqlmap version is outdated使用了旧版本的SQLMap。按照本文2.2节的方法,从GitHub克隆最新版本使用。

一个典型的排错流程:当SQLMap报告“可能不可注入”时,不要轻易放弃。我会这样做:1) 用Burp重放请求,手动添加一个单引号,观察响应是否有变化或报错;2) 如果没变化,尝试id=1 AND 1=1id=1 AND 1=2,对比页面差异;3) 如果还没差异,尝试id=1 AND SLEEP(5),用秒表看响应是否延迟。如果手动测试有迹象,再回到SQLMap,用更精确的参数(如指定--technique=B--technique=T)进行定向攻击。

5.3 从攻击到防御:理解原理才能有效防护

作为一名负责任的安全从业者,我们学习攻击技术的终极目的是为了防御。通过SQLMap的实战,我们可以深刻理解哪些开发漏洞会导致自动化工具轻易得手:

  1. 永远不要信任用户输入:这是铁律。所有来自客户端(URL参数、表单、Cookie、Headers)的数据都必须视为不可信的。
  2. 使用参数化查询(预编译语句):这是防止SQL注入最根本、最有效的方法。无论是PHP的PDO、Python的sqlite3、Java的PreparedStatement,还是.NET的SqlParameter,其原理都是将SQL代码与数据分离,从根本上杜绝了拼接导致的代码注入。
  3. 实施最小权限原则:数据库连接账户不应使用rootsa等高权限账户。应为其分配仅能完成应用功能所需的最小权限,例如只授予特定表的SELECT权限,而非DROP,FILE等。
  4. 部署Web应用防火墙(WAF):虽然WAF可以被绕过(正如我们使用--tamper所做),但它能阻挡大量的自动化扫描和低技能攻击,为修复漏洞争取时间。
  5. 自定义错误信息:避免将详细的数据库错误信息(如MySQL错误)直接返回给用户。应使用通用的错误页面,防止攻击者通过报错信息获取数据库结构线索。
  6. 定期安全测试与代码审计:使用SQLMap等工具对自己开发的应用进行定期的授权渗透测试,主动发现并修复漏洞,这才是安全建设的正向循环。

在我自己的开发和安全评估经历中,见过太多因为简单的字符串拼接而导致的严重漏洞。使用SQLMap的过程,就像一位严格的老师,它用最直接的方式告诉你,你的应用在哪个环节是脆弱的。当你能够熟练运用SQLMap发现别人的漏洞时,你在编写代码时,自然会对自己手中的代码多一份敬畏和谨慎。这才是工具带给我们的、超越技术本身的成长。

http://www.jsqmd.com/news/1362906/

相关文章:

  • DeepAsk:基于RAG的本地知识库AI问答插件部署与实战
  • Cocos Creator资源导出插件开发:从原理到企业级实践
  • 数据科学与大数据技术在能源消耗分析中的应用实践
  • 2026 年现阶段苏尼特左旗靠谱的装配式金属雕花保温装饰墙板工厂找哪家,花几千块装的墙,竟能同时搞定保温、装饰还省时间? - 实业推荐官
  • 基于LangChain与AutoGen构建AI Agent的5个实操场景
  • 告别网盘限速:九大平台直链下载助手全方位使用指南
  • 蓝速科技 AI 数字人一体机:一体化交付破解工期难题
  • DFS算法处理重复元素排列问题详解
  • Python Web安全入门:从爬虫到渗透测试的自动化实战
  • ThinkPHP与Laravel双框架教务系统开发实践
  • 装一个运维工具监控CPU 内存磁盘
  • 5分钟快速上手:macOS终极Windows应用运行工具Whisky完整指南
  • 基于YOLO与OpenCV的野生动物视频自动化分析技术方案
  • Docker多容器化部署前后端分离项目实践指南
  • 3步构建专业级QQ群数据采集系统:Python爬虫实战指南
  • HTML与CSS核心原理与高效开发实战
  • 黑锋航空座椅优化:纳帕真皮包覆升级 - 品牌排行榜
  • 2026 年当下,泸县靠谱的镀锌护栏源头厂家找哪家,花几万块装的户外护栏,居然是“中看不中用”?这玩意儿才是真能防十年锈!-标众护栏厂 - 企业官方推荐【认证】
  • 终极免费方案:Wand-Enhancer解锁游戏修改完整功能
  • 用Obsidian构建《Crossout Mobile》战车知识库:从静态展示到动态战术分析
  • 2026年马来西亚出口美国公司如何选 捷运达物流JYD指南 - 起跑123
  • 2026年优选文丘里变风量阀:实验室通风系统升级与选型全指南 - 装修教育财税推荐2026
  • Unity UI圆角效果终极指南:从贴图到Shader的完整实现方案
  • jikuai项目 M9 批次交付完成 — 五项全部落地 .请看看它的工作完成的怎么样,下一步该做什么 ? (Comate 3小时完成三个月任务)
  • XCOM 2模组管理器终极指南:5分钟掌握AML启动器高效管理技巧
  • 提示工程与Blender结合:自然语言驱动3D建模实践
  • USB-Disk-Ejector:终极解决方案如何轻松解决Windows设备占用烦恼?
  • 【风电功率预测】【多变量输入单步预测】基于BiTCN-SVM的风电功率预测研究附Matlab代码
  • 从零到三维:如何用开源工具将无人机照片变成专业级地图和模型?[特殊字符]
  • Selenium元素定位全攻略:从基础方法到Page Object实战