命令注入中的空格与黑名单绕过:CTF题spaceman实战解析
CTFshow平台的DJBCTF大吉大利杯我连续跟了两届整体题目对新手很友好但web方向的某些题放在“新手”标签下实际考验的却是很细的shell知识。spaceman太空人这道题页面上只有一个卡通宇航员、一个输入框和一个Execute按钮背景用CSS做了星空效果乍看就是个纯前端玩具。题目名字拆开就是space和manspace这个暗示几乎摆在台面上——这道题八成和“空格”过不去。我第一反应是看页面源码。按F12扫了一遍HTML和JS没发现隐藏接口也没有多余的js逻辑只有一个POST表单指向当前页面字段名叫cmd。看到cmd这个参数名基本可以确定这就是命令执行点接下来要做的就是摸清楚它到底滤了什么。在输入框随便提交了一个ls页面直接返回了根目录下的文件列表。命令确实执行了而且回显直接输出在页面上。试了一下带空格的命令ls /被拦截提示是spaceman说不能用某些词。这就有意思了说明存在一个黑名单而且空格被列在里面。到这里我已经知道目标了怎么在没有空格、没有常见命令名、没有flag关键字的情况下把flag读出来。1. 题目初探一个能执行命令的“太空人”1.1 打开页面之后我做了什么这类页面我见得太多了先不急着提交payload第一步永远是信息收集。页面本身是个极简的HTML表单一个文本框一个Execute按钮外加一个星空背景和宇航员插画。HTML里没有任何隐藏表单字段也没有外部js文件说明交互逻辑都压在服务端。尝试提交ls后页面回显了根目录列表。这个信息量其实很大第一命令是真正被执行的不是模拟器第二回显直接打在页面上省去了盲注的麻烦第三列目录用的是根目录相对路径说明当前工作目录大概率就是nginx或apache的web目录flag文件可能放在根目录或者其他固定位置。顺带观察了一下id和whoami的输出确认自己是低权限的www-data用户。这类信息对后续判断有用尤其当你不知道flag文件权限时知道自己是谁、能读什么文件会少走很多弯路。接着尝试ls /被拦了。随后又试了cat /etc/passwd同样被拦。但拦截提示并没有告诉我具体哪个词命中了规则只说“no no no”所以只能靠测试去反推黑名单内容。1.2 高亮源码暴露了一切第二次刷新页面时我才注意到页面底部有一大段被语法高亮的PHP代码这就是当前文件的源码。题目用了highlight_file(__FILE__)直接把源码放出来了省去了扫描备份文件这一环。?php error_reporting(0); highlight_file(__FILE__); if (isset($_POST[cmd])) { $cmd (string)$_POST[cmd]; $blacklist /\s|cat|flag|more|less|head|tail|nl|tac|sort|rev|base64|curl|wget|cp|mv|sh|\*|\?/i; if (preg_match($blacklist, $cmd)) { die(Spaceman says: no no no.); } system($cmd); } else { echo form methodpostinput typetext namecmd /button typesubmitExecute/button/form; } ?拿到源码事情就变得非常清晰了输入通过POST字段cmd传递最终交给system()执行过滤用的是黑名单正则大小写不敏感禁掉了所有空白字符\s、常见读文件命令、flag关键字、通配符*和?连curl、wget、cp、mv这些工具也禁了。一个经典的“看似严格、实则可以绕过”的命令注入点。接下来就是逐块拆解过滤规则找到它覆盖不到的地方。2. 过滤规则分析它到底把路堵死了没2.1 从黑名单看命题人的思路黑名单的特点是“只封已知的、常见的写法”但Linux shell的表达方式远多于任何黑名单能枚举的范围。出题人能想到cat、tac、nl、more、less、head、tail、sort、rev这些读文件命令说明这题预期解法就是绕过读文件命令。同时他封掉curl、wget是怕选手直接把flag外带出去封cp、mv可能是防止把flag文件复制到web目录再下载。这种过滤风格在CTF里很常见它的弱点在于“逐字逐词匹配而不是解析语法”。换句话说只要原始字符串里不出现黑名单里的连续子串它就能通过检查至于这个字符串经过shell解析之后会变成什么正则根本不关心。这正是所有shell黑名单类题目的突破口也是我最喜欢的一类考点。黑名单里还禁了\s这意味着所有空白字符都没了其实不是。\s匹配的是输入字符串里真实存在空白字符而${IFS}这种写法在输入字符串里全是普通字符没有任何空白所以正则认为你是清白的。shell拿到之后把它展开成空白这时候才真正起到空格的作用。这就是“正则看的是源码shell看的是展开结果”的典型错位。2.2 为什么空格比命令名更重要在命令行里空格是单词分隔符。cat和/flag.txt之间如果没有空白shell会把它当作一个完整单词cat/flag.txt这不是命令名肯定会报错。所以很多人在构造payload时第一件事就是思考怎么在没有空格的情况下分开参数。这也是题目名字spaceman的暗示space就是空格。作者先把空格禁掉等于封死了最直接的注入写法。只要绕过空格后面就好办了。比较常见的空格替代方案包括${IFS}shell内置的字段分隔符变量默认是空格、Tab、换行展开后就充当了空格$IFS$()在dash下更稳的写法通过空命令替换防止某些环境下$IFS被忽略花括号展开{cat,/flag.txt}会展开成cat /flag.txt逗号分隔的两个词在展开后天然分开重定向替代cat/flag.txt用输入重定向命令和文件之间完全不需要空格。这些方案里IFS是最通用的几乎每个Linux环境都支持。2.3 Linux shell的等价写法有多少种这也是我想强调的一点shell命令不只是“命令名空格参数”这一种形态。同一个操作可以通过重定向、管道、花括号、命令替换、变量拼接等不同机制表达出来。只要黑名单没有把所有机制都禁掉就一定有绕过的空间。比如读取文件这件事至少可以这么写cat flagcat flag flag catnl flagsort flagcat $(find . -name flag)paste flagsed -n 1,$p flagawk {print} flagod -c flag更别说每种命令还可以用引号、反斜杠、变量插值再次变形。正则过滤只能看到一种形态可shell实际能解释的形态有几十种。所以这类题的核心能力不是背payload而是理解shell的语法构成。你越懂shell黑名单就越像一个筛子总能找到漏洞。3. 三种绕过技巧的完整拆解3.1 空格绕过${IFS}为什么能行先看${IFS}。IFS是Internal Field Separator的缩写是shell内置的字段分隔符变量默认值是spacetabnewline。在未加引号的变量展开中shell会用IFS的字符去分词。比如echo${IFS}hello经过变量展开后实际上变成echo helloPHP的system()底层调用/bin/sh -cdash和bash都会执行这个展开所以cat${IFS}/flag在大多数Linux环境都能成立。注意我写的是${IFS}而不是$IFS这是因为在某些shell里$IFS后面直接跟字母时shell会试图解析成一个更长的变量名比如$IFSx而不是$IFS后面跟x。加花括号是一个保险习惯。我在比赛环境里验证过ls${IFS}/可以正常列出根目录说明这个思路可行。还有一个衍生技巧是$IFS$()它通过空命令替换把$IFS和后面内容隔开防止某些dash环境下解析出错。如果你在任何地方看到$IFS$()它干的事和${IFS}一样只是多了一层保险。这里必须提醒一句IFS展开只发生在不加引号的情况下。如果你写了${IFS}shell会把它当作普通字符串的一部分而不是分隔符那就白搭了。所以构造payload时千万不能顺手加引号。3.2 命令名绕过引号拼接与反斜杠命令名被黑名单拦截最简单的绕过是把命令名“拆开”再让shell拼回去。shell在解析时会先处理引号和转义再把拼接的结果当命令执行。cat /flag.txt # 中间插入空双引号 cat /flag.txt # 中间插入空单引号 c\at /flag.txt # 用反斜杠转义字符这三种写法在shell执行时都会变成cat /flag.txt。正则匹配的是原始输入它看到的是cat里面没有连续的cat所以顺利通过。原理很简单shell的词法分析阶段先做引号去除双引号中间的一对空引号被直接删掉剩下的c和at自然拼在一起单引号同理反斜杠放在普通字符前对普通字符没有特殊作用也会在词法阶段被移除。这三种方式在我测过的dash、bash、sh下都成立。这里有一个容易踩的坑单引号里面如果再放单引号会出问题所以构造时最好用双引号或者混着用。另外反斜杠如果被黑名单禁掉了就不能用第三种但前两种始终可靠。如果连引号都被禁那就只能用后面的变量插值思路了。3.3 参数名绕过字符串拼接与字符类参数里的flag关键字也一样核心手段还是让正则找不到连续子串。除了引号拼接还有一个trick是glob字符类cat /f[l]ag.txt[l]在shell的路径名展开中会匹配单个字符l所以f[l]ag.txt最终展开成flag.txt但原始输入里没有flag这个连续子串。当然如果匹配到多个文件就会产生歧义所以要保证通配结果唯一。如果题目把*和?都禁了字符类不受影响因为黑名单只写了*和?没有写[和]。但如果你用的是flag这种引号拼接就完全不依赖glob在任何环境都成立。另外参数路径也不一定非要写flag原词。如果flag文件固定叫flag.txt你可以用flag.txt也可以用fl\ag.txt甚至可以用/flag.txt。在参数部分插入引号和反斜杠并不会影响最终路径解析。这一点和命令名绕过完全同构本质都是“让正则找不到连续子串同时让shell拼回原词”。4. 实战payload构造与通关记录4.1 先探测环境再决定路径先执行ls${IFS}/页面回显了根目录列表。根目录下面躺着一个flag.txt文件名很直白说明flag文件就在眼前现在的问题只是怎么把它读出来。顺便说一句命令执行的回显直接打到页面上这意味着题目是RCE回显型不用走盲注思路省了很多事。如果此时发现回显被关那就得考虑时间盲注、DNS外带等方案复杂度完全不一样。拿到根目录列表之后第一反应是cat /flag.txt但这个payload在空格、命令名、参数名三个维度全被拦截。接下来就需要把三步绕过组合起来。4.2 几组payload的成败对照我在本地沙箱里把几种payload都试了一遍顺便记录了拦截情况。payload是否拦截结果cat /flag.txt被拦有空格和cat无输出ls${IFS}/通过列出根目录cat${IFS}/flag.txt被拦有cat和flag无输出cat${IFS}/flag.txt被拦有flag无输出cat${IFS}/flag.txt通过输出flagcat/flag.txt通过输出flag注意第三行和第四行的区别cat即使被引号拆开了只要参数里还有原生的flag字符串照样会被拦。必须每一环都考虑周全只绕过一处是不够的。第四行和第五行对比才看得出完整的绕过链条。4.3 最终一发的完整解最后的payload很简单cat${IFS}/flag.txt拆开来看cat绕过命令名黑名单shell解析后得到cat${IFS}替代空格作为命令和参数之间的分隔符flag.txt绕过参数关键字黑名单最终路径恢复为/flag.txt。如果提交时用POST的cmd字段这个字符串会原样进入PHPpreg_match检查通过system()交给shell执行shell解析完等价于cat /flag.txtflag就出来了。另外还有另一种不依赖IFS的写法也是我现场试出来的cat/flag.txt输入重定向让cat从文件读取标准输入命令本身不需要空格。shell语法里两边可以没有空白所以这个payload连空格思路都省了。两种方式都通过了过滤最终都拿到了flag。拿到flag之后我特意又验证了一下cat的通用性发现它对所有读文件命令都适用比如sort/flag.txt、tac/flag.txt。本质上都是利用重定向取代空白绕开的依然是同一个“空格”关卡。4.4 如果出题人把IFS也禁了怎么办赛后复盘时我想过如果黑名单再加一条IFS怎么办其实还有几个备选思路。$和$*特殊变量在命令名中使用c$at当shell没有位置参数时$展开为空字符串起到拼接作用最终得到cat环境变量截断如果bash可用${PATH:0:1}可以取到/用多个变量截断组合出想要的字符串花括号展开{cat,/flag.txt}可以通过花括号展开生成两个词同时解决空格和关键字问题重定向方案仍然有效符号不依赖空格、IFS也不依赖花括号。这说明一道好题的核心价值在于让你把一个知识点彻底吃透。如果只是背了cat flag然后绕过空格那道题就白做了。真正的收获是理解shell的多层展开机制明白“黑名单看的是原始字符串shell看的是展开结果”这才是所有命令注入绕过的底层逻辑。5. 踩坑实录与快速自查清单5.1 我在这道题上卡住过的地方第一个坑是$IFS和${IFS}的区别。我一开始直接写了cat$IFS/flag.txt在本地bash里测试没问题但提交到题目环境却报错。原因是有些sh在解析时会把$IFS/flag.txt当作一个更长的变量名的一部分来尝试展开虽然多数bash不会这么处理但dash的行为更保守。换成${IFS}之后题目环境就通了。这也是为什么网上各种writeup里写IFS绕过时都强调花括号。第二个坑是输入框里直接输入双引号时偶尔会被页面的JS预处理干扰。我一开始是在浏览器表单里直接粘贴payload有几次提交之后没有得到预期结果后来换用Burp重放请求才发现浏览器对某些字符做了实体编码服务端收到的已经不是我以为的字符串。换成Burp直接发POST包后一次就通了。如果你也在做这类题建议工具直接用Burp或者curl少用浏览器表单去碰运气。第三个坑是通配符的虚无感。我最初想到用/???/???或者f*然后发现黑名单把*和?都禁了这才意识到出题人早就把这些常规退路堵住了。后来换成引号拼接立刻通了。这一类绕过的核心不是记住某个技巧而是掌握一个原则黑名单只会枚举它认识的样子你要做的是构造它不认识但shell认识的样子。5.2 一份可以直接抄走的命令注入绕过速查整理一份我常备的绕过速查表遇到类似题目可以直接对照。要绕过的东西常用写法空格${IFS}、$IFS$()、{cmd,param}、cmdfile命令名cat、cat、c\at、c$at参数里的关键字flag、f[l]ag、fl\ag、f$lag通配符被禁放弃glob改用引号拼接或枚举路径回显被关时间盲注、DNS外带等需在授权范围内测试整条命令被禁用重定向、管道、子shell重新组合语法几个补充说明${IFS}最通用但要注意大小写正则加了/i时ifs也会被匹配花括号展开{cat,/flag.txt}虽然能并列生成两个词但如果黑名单把cat和flag都禁了还是得先做引号拼接重定向读文件是很多选手容易忽略的常规解法因为它的思维模型和“空格分隔参数”完全不同如果题目环境没有cat而是busybox可以用busybox cat但payload要相应调整还是同样的绕过思路。写这份记录的时候我特意没有把payload做任何隐藏因为CTF比赛环境本身就是一个授权攻防靶场这些技巧也完全适用于合规的渗透测试练习。spaceman这题难度不高但把“命令注入黑名单过滤”这个方向考得很系统从空格到命令名再到参数名每一层都对应一个shell语法点。真正把这套东西吃透之后再回头看这类题你的关注点就不再是“有没有绕过姿势”而是“出题人漏掉了哪一层语法”。

相关新闻

商业服务机器人落地指南:从具身智能到选型部署全解析

商业服务机器人落地指南:从具身智能到选型部署全解析

最近我和某连锁餐饮品牌的运营负责人聊了聊,他们门店里那两台送餐机器人已经承接了超过七成的传菜任务。放在两年前,这还是个不敢想的数字——机器人在高峰期一堵就是十几分钟,顾客盯着菜看却端不上来,场面一度很尴尬。但现在不一…

2026/10/17 15:30:01 阅读更多 →
Eclipse 实用技巧全解析:从环境配置到调试与性能优化

Eclipse 实用技巧全解析:从环境配置到调试与性能优化

Eclipse 用了小十年,从大学第一次装这个 IDE 写作业,到后来在项目里靠它 Debug 追线上问题,再到看着周围人一个个换了商业 IDE,我却始终没法把它完全扔掉。不是固执,而是这工具有些东西实在太好用了,尤其在…

2026/10/17 15:30:01 阅读更多 →
具身智能数据焦虑破局:Psi-R2.5强Pair Data训练链路实战

具身智能数据焦虑破局:Psi-R2.5强Pair Data训练链路实战

1. 具身智能的“数据焦虑”:为什么高质量数据成了新战场过去两年,具身智能赛道最不缺的就是“Demo”。各种人形机器人叠衣服、冲咖啡、分拣零件的视频满天飞,看着确实热闹。但真正在一线做训练的人心里都清楚,这些Demo背后往往是几…

2026/10/17 15:30:01 阅读更多 →

最新新闻

Pod生命周期管理:Init容器、探针与优雅终止配置实战

Pod生命周期管理:Init容器、探针与优雅终止配置实战

很多人写Pod配置,习惯从网上抄一份YAML就往集群里丢,表面上跑得挺正常,可一遇到发布、故障、流量抖动,问题就全冒出来了。这些年我排查过的线上事故里,至少有一半的根因都能归结到Pod生命周期管理上——要么Init容器卡…

2026/10/17 18:31:58 阅读更多 →
UE5 MovieRenderQueue 黑块条纹故障根因与修复指南

UE5 MovieRenderQueue 黑块条纹故障根因与修复指南

简介:本资源是一份面向Unreal Engine 5中高级开发者与影视渲染工程师的实战型技术指南,聚焦MovieRenderQueue(MRQ)在实际项目中高频出现的渲染异常问题,如图像条纹、黑块、场景多出物体、全黑输出、相机偏移及着色器编…

2026/10/17 18:31:58 阅读更多 →
Claude Code 模板库实战:npm 一键配置 MCP 与 CLI 环境

Claude Code 模板库实战:npm 一键配置 MCP 与 CLI 环境

1. 这个模板库到底解决了什么问题第一次接触 Claude Code 的人,十有八九会卡在同一个地方:装完了 CLI,敲开终端,面对一个空荡荡的对话框,不知道下一步该干什么。官方文档告诉你它能读文件、能跑命令、能连 MCP&#xf…

2026/10/17 18:31:58 阅读更多 →
用mprotect定位踩内存:三个保护模式与实战技巧

用mprotect定位踩内存:三个保护模式与实战技巧

踩内存这种故障,恐怕是C/C项目里最让人挠头的一类问题。它不像空指针那样干脆利落——空指针崩了就崩了,栈上清清楚楚;踩内存则是延迟引爆的,某处代码把不该写的内存写坏了,但现场不会立刻暴露,往往要等到另…

2026/10/17 18:31:58 阅读更多 →
星界战略:多法域出海合规与数据主权架构实战指南

星界战略:多法域出海合规与数据主权架构实战指南

1. 从“星界战略”这个名字说起:它到底要解决什么问题 第一次看到“星界战略”这个词,很多人会以为是个游戏项目或者科幻设定。但在出海圈子里摸爬滚打几年之后,我越来越觉得这个名字取得很准确——它描述的是一种 跨法域、跨文化、跨监管体…

2026/10/17 18:31:58 阅读更多 →
TensorFlow BaselineClassifier踩坑复盘:从数据管道到模型导出的全链路避坑指南

TensorFlow BaselineClassifier踩坑复盘:从数据管道到模型导出的全链路避坑指南

1. 从一次模型上线事故说起:为什么我盯上了BaselineClassifier去年冬天,团队接了一个用户流失预测的需求。数据量不大,几十万条样本,特征也就二十来个,业务方要得急,三天内要看到第一版可解释的基线结果。当…

2026/10/17 18:30:57 阅读更多 →

日新闻

DeepSeek选型与部署:V3/R1、Ollama、API全攻略

DeepSeek选型与部署:V3/R1、Ollama、API全攻略

简介:《DeepSeek使用方法.pdf》是一份面向DeepSeek入门及进阶用户的完整使用指南,重点围绕V3与R1两款模型的能力差异与适用场景展开,帮助读者根据任务类型与成本选择合适的模型。资源共1个PDF文件,压缩包大小约311KB,篇…

2026/10/17 0:00:25 阅读更多 →
200+Deepseek润色指令拆解:从底层原理到场景落地的完整指南

200+Deepseek润色指令拆解:从底层原理到场景落地的完整指南

简介:这是一份聚焦DeepSeek提示词优化的《200Deepseek润色指令》PDF文档,共收录两百余条可直接套用的润色指令,涵盖语法修正、风格统一、逻辑梳理、表达精炼等维度,并针对商务写作、学术论文、广告文案等场景给出差异化建议。文档…

2026/10/17 0:00:25 阅读更多 →
OpenCV轮廓法物体计数系统:轻量、可控、可落地的工业级实现

OpenCV轮廓法物体计数系统:轻量、可控、可落地的工业级实现

简介:本资源是一份基于OpenCV的本科课程设计完整报告,面向计算机视觉初学者、图像处理学习者及高校通信/信息类专业学生,解决物体智能计数与检测结果结构化记录的实际问题。项目覆盖图像预处理、轮廓检测、边界框绘制、轨迹栏交互式参数调节、…

2026/10/17 0:00:25 阅读更多 →

周新闻

流感时间序列预测实战:ARIMA/LSTM全流程拆解与避坑指南

流感时间序列预测实战:ARIMA/LSTM全流程拆解与避坑指南

简介:基于 ARIMA、LSTM、Transformer 等模型的流感时间序列预测 Python 源码,面向计算机相关专业课程设计与期末大作业学生,以及项目实战学习者。内容覆盖预处理、平稳性检验、定阶、残差分析、多模型对比预测的完整时序建模流程,…

2026/10/16 21:35:51 阅读更多 →
影刀RPA新手教程:键盘模拟输入实战——输入文本与模拟按键的区别

影刀RPA新手教程:键盘模拟输入实战——输入文本与模拟按键的区别

影刀RPA新手教程:键盘模拟输入实战——输入文本与模拟按键的区别 做影刀RPA自动化,十个新手有八个栽在"往输入框里填东西"这件事上:要么填不进去,要么填了一半,要么直接把原来内容追加在后面。这背后的根因&…

2026/10/17 1:44:59 阅读更多 →
影刀RPA新手教程:阅文起点小说数据采集实战——书籍信息与章节内容

影刀RPA新手教程:阅文起点小说数据采集实战——书籍信息与章节内容

影刀RPA新手教程:阅文起点小说数据采集实战——书籍信息与章节内容 1. 认识影刀:什么场景该用RPA采小说数据 起点中文网的页面结构相对稳定——分类榜单、书籍详情、章节内容三块独立页面,跳转链路清晰。这种场景非常适合影刀自动化&#x…

2026/10/16 15:04:24 阅读更多 →

月新闻

我发现了一个新思路:用 Remotion + Claude Code 像写代码一样自动化生成短视频

我发现了一个新思路:用 Remotion + Claude Code 像写代码一样自动化生成短视频

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/10/16 21:54:38 阅读更多 →
Windows下 Codex 中 Chrome 和 Computer Use 插件不可用问题排查及解决参考方式:TaoToken 统一 Key 配置与验证

Windows下 Codex 中 Chrome 和 Computer Use 插件不可用问题排查及解决参考方式:TaoToken 统一 Key 配置与验证

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/10/17 17:22:31 阅读更多 →
黑夜航拍船只数据集训练YOLOV5模型全流程解析

黑夜航拍船只数据集训练YOLOV5模型全流程解析

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/10/16 14:23:36 阅读更多 →