1. 从“看不懂”到“秒懂”:科学计数法在CTF中的奇袭
很多刚接触CTF(Capture The Flag)网络安全竞赛的朋友,看到“科学计数法绕过”这个说法可能一头雾水。科学计数法不是数学课上的内容吗?怎么跟网络安全、跟PHP代码审计扯上关系了?我第一次在“复兴杯”这样的实战赛里遇到时,也是愣了好几秒。但恰恰是这种将基础学科知识灵活应用于安全场景的题目,最能考察一个选手的思维广度和临场应变能力。说白了,它考的就是你能否跳出“程序员思维”的定式,用更底层的、甚至是非计算机的视角去审视一段代码。
让我用一个最生活化的例子来解释。假设你有一个非常严格的保安(服务器),他只允许身高“180”厘米整的人进入。你身高179.5厘米,显然不符合。但如果你对保安说:“我的身高是1.795e2厘米。” 在口头汇报(弱比较)时,保安可能会把它心算成180厘米然后放行。但如果你站上精确的激光测高仪(强比较或运算),你的真实身高179.5厘米就会暴露。这里的“e”就是科学计数法中的指数标记。在PHP这类弱类型语言中,字符串“1.795e2”在和数字180比较时,PHP会尝试将它转换成数字,转换的结果就是179.5,但在某些宽松的比较条件下,它可能被“视为”180。这就是绕过逻辑的起点。
在“复兴杯”2023大学生网络安全精英赛的实战中,第一道题就给了我一个下马威。题目代码大概逻辑是要求我们输入一个值,这个值在弱比较(==)时要等于2023,但在后续某个运算中又不能等于2024。如果直接输入2023,肯定通不过第二关。题目提示了“科学计数法”,我立刻想到,能不能找一个用科学计数法表示后,在字符串转数字时恰好是2023,但其本身数值又不是2024的数呢?我尝试了“2.023e3”。我们来拆解一下:2.023 * 10^3 = 2023。当PHP用==比较"2.023e3" == 2023时,它会将左边的字符串转换为数字2023,比较成立。但如果代码里用到了更精确的运算,比如intval("2.023e3")或者直接进行加法"2.023e3" + 1,其结果会是2023 + 1 = 2024吗?不会,因为2.023e3作为浮点数参与运算,其值就是2023,加1就是2024。但题目的精妙之处在于,它可能设置了另一个检查点,要求你的输入在经过某种变换后不能等于2024。而“2.023e3”这个字符串本身,作为一个文本,它不等于数字2024。这就巧妙地满足了题目的两个矛盾条件。输入后,果然成功拿到了第一滴血(First Blood)。
这种题目的意义在于,它打破了我们对数据类型的惯性认知。在开发中,我们可能习惯了$_GET['num']拿来就和数字比,却忽略了PHP在背后默默做的类型转换(Type Juggling)可能带来意想不到的结果。攻击者正是利用这种“意想不到”,构造出符合表面逻辑但实际语义不符的输入,从而绕过检查。作为防守方,这就提醒我们,在涉及安全判断时,必须使用严格比较(=== 和 !==),并且对用户输入进行严格的类型过滤和范围校验。
2. 流量中的宝藏:网络取证与协议分析实战
CTF比赛中除了纯粹的代码审计和漏洞利用,还有一大类题型叫“Misc”(杂项),其中网络流量分析(PCAP Analysis)是常客。这非常考验选手的耐心和细致程度,就像侦探在浩如烟海的监控录像中寻找那一帧关键的线索。在“复兴杯”的这道题里,打开题目给出的流量包文件,扑面而来的可能是HTTP、TCP、TLS等各种协议的数据流,让人眼花缭乱。
我的习惯是先用Wireshark的统计功能,看看哪些协议和对话最活跃。题目提示了“电脑账号是ly”,这给了我第一个关键线索。我立刻在Wireshark的过滤栏中输入表达式:frame contains "ly"。这个过滤器会筛选出所有数据


被折叠的 条评论
为什么被折叠?



