尧图建网站 尧图建网站 YAOTU WEB BUILD 免费咨询
ARTICLE DETAIL

资讯详情

深耕网站建设与建站编程的一线实战洞察。

奇安信校招笔试复盘:安全岗必考的路径遍历与密码学

奇安信校招笔试复盘:安全岗必考的路径遍历与密码学 2019年秋招季我在一所普通211的机房点开了奇安信2019校招笔试题二。说实话题量不算大但风格让我印象很深——没有太多纯算法题也没有“手写单例模式”这种套路化问题取而代之的是大量“给你一段代码请指出漏洞并修复”的场景题。后来我才慢慢想明白这才是安全公司校招笔试应该有的样子它不care你会背多少知识点它想看的是你在面对一段不可信代码时会不会下意识站在攻击者角度做判断。这篇文章不是原题答案速查而是站在一个过来人的视角复盘那套题里真正拉分的几个考点路径遍历、密码学配置、编程题写法以及考完后用什么方式把知识漏洞补上。如果你正在准备奇安信、深信服、绿盟这类安全公司的校招或者想从开发岗转安全岗这篇应该能帮你省下不少瞎摸索的时间。1. 那套卷子的隐藏主线从“会不会”到“怎么想”先说结论这套笔试题二和互联网大厂开发岗笔试最大的分水岭不是考察范围而是考察粒度。开发岗可能会问你“HashMap和Hashtable有什么区别”安全岗则会问“如果用户输入的key会拼进一个日志文件你怎么写才不产生日志注入”。同一个知识点开发岗考概念安全岗考风险。这是整个卷子给我的第一观感。我凭记忆把卷子大致分成四块网络与操作系统基础、Web安全、密码学、算法编程。虽然具体分值不一定记得准但分布趋势大概是这样的模块大概占比代表性考点网络与操作系统基础20%TCP三次握手状态、HTTP状态码语义、Linux文件权限Web安全35%SQL注入、XSS、CSRF、路径遍历、反序列化密码学基础20%RSA简单计算、AES模式辨析、密码哈希存储算法/编程题25%字符串/数组处理、边界条件设计这四块不是孤立存在的。奇安信作为安全公司笔试题尤其喜欢在“Web安全”和“编程题”之间埋交叉考点同样是给一段代码找问题开发岗希望你回答“这里会抛空指针”安全岗希望你回答“这里用户可控输入可能导致任意文件读取”。这两种回答之间的差距就是“会不会写代码”和“能不能做安全开发”的差距。1.1 安全岗笔试和开发岗笔试的本质区别举一个我在卷子里印象很深的例子一个文件下载接口代码大概长这样String fileName request.getParameter(fileName); File file new File(/data/files/ fileName); response.setContentType(application/octet-stream); // 读取file并返回给客户端开发岗视角是文件名从参数来拼到路径里逻辑很顺没什么问题。安全岗视角则是fileName里如果带../呢如果带URL编码呢如果用户传一个绝对路径呢同样一段代码前者看到功能后者看到风险。这就是安全思维的第一层永远假设外部输入不可信。第二层差异是影响面分析。开发岗答完“这里有bug”可能就结束了安全岗还要继续想这个漏洞能不能远程利用能不能读取配置文件能不能进一步升级成任意文件写入在笔试卷上哪怕题目只要求“指出漏洞”我也会在答案末尾补一句“攻击者可能利用该接口读取系统用户文件或应用配置造成敏感信息泄露”。这不仅是展示知识面更是在告诉阅卷人我知道这个漏洞的危害边界在哪里。第三层是修复成本。安全岗笔试里最常见的“给你五分钟写修复方案”考察的不是你能不能写出最完美的代码而是你有没有考虑兼容性和误用风险。比如路径遍历最简单的写法是if (fileName.contains(../)) { throw new SecurityException(invalid path); }但这种黑名单方案遇到编码绕过就废了。更好的方式是先做路径规范化再校验最终路径是否还在允许目录内。在笔试现场能写出第二种方案的考生大概率见过真实漏洞而不只是背过理论。1.2 我在考场上总结的答题策略先啃简答再做选择我见过很多同学按题目顺序一路做结果在单选多选上抠了半小时最后编程题没时间写简答题随便糊两行。这套卷子不是按难度排的前面的选择题也可能很阴间。我的策略是发卷后先花两分钟把简答题扫一遍优先写“逻辑清晰、能拿大分”的题目。为什么因为简答题按点给分你写一个修复方向就有分多选题错一个选项就全废性价比太低。假设简答题里有路径遍历、RSA计算、编程题我会先做RSA计算和路径遍历修复这两道题逻辑确定10分钟内能拿满。然后回头处理概念型选择比如“HTTP方法安全”“SQL注入绕过”这类遇到不确定的先标记大题做完再检查。如果笔试系统支持Markdown我会在简答题文本框中用清晰的小标题把“漏洞描述、利用场景、修复方案、测试用例”分开。阅卷人一天要看很多份卷子结构清爽的答案天然有印象分。这个习惯我到现在做安全评审时还在用算是那场笔试留下的一个正向副作用。2. 路径遍历这道综合题从文件下载接口到目录穿越的完整分析这套卷子里我印象最深的是路径遍历综合题。它不是CTF里那种偏门考点而是非常贴近真实业务的一个“文件下载”接口。在线答题页给了一段简化后的Java代码描述大概如下public void download(HttpServletRequest request, HttpServletResponse response) { String fileName request.getParameter(fileName); String basePath /data/files/; File file new File(basePath fileName); // 读取file并输出到response }题目有三问第一指出这段代码存在的安全漏洞第二攻击者可能利用这个漏洞做什么第三给出修复方案。这种题在安全公司笔试题里很经典因为它把“攻击原理”和“代码修复”放进了同一个场景天然适合考察综合能力。我当时的思路是不要只说“文件名没校验”要说明攻击者如何把路径一层层往上带。正常请求是download?fileNamereport.pdf读取的是/data/files/report.pdf。但如果用户传入download?fileName../../../../etc/passwd在Linux环境下系统会从/data/files/出发往上层一级一级跳最后落到/etc/passwd。这还不是最可怕的如果这个接口换成上传或者保存文件同样的逻辑可能变成任意文件写入危害直接升级。2.1 漏洞核心目录拼接不等于路径约束很多同学写过new File(basePath fileName)觉得前缀目录写死了路径就一定被约束在目录里。实际上basePath fileName只是在字符串层面做了拼接并没有在路径语义层面做约束。操作系统解析路径时..就是“上一级目录”它不会因为你前面加了/data/files/就自动禁止跳出去。这里有一个容易被忽略的细节Web容器拿到URL参数时可能已经做过一次URL解码。攻击者把../写成%2e%2e%2f有些框架会解码成../有些不会。如果应用里还有多个过滤器参数的编码状态可能在多层之间不断变化。所以修复时不能只看当前代码还要考虑整个请求链路对参数做了什么处理。我在答题时专门写了一句“建议在入口处统一做输入规范化和校验”后来工作里做代码审计发现这句话确实是对的方向。另外Windows环境比Linux更麻烦。Linux下主要防御../、绝对路径、符号链接Windows还有盘符、UNC路径、保留设备名、短文件名等一堆边缘情况。笔试不会要求你把所有平台差异写全但至少要有“路径问题要考虑跨平台”的意识。能写出这句阅卷人会认为你见过真实代码而不是只会背例题。2.2 怎样把“利用与修复”写到阅卷人愿意给满分我当时把答案组织成四段你也可以直接照这个结构来漏洞类型路径遍历Path Traversal / Directory Traversal对应CWE-22。攻击方式通过修改fileName参数使用../或编码绕过读取任意文件。影响范围读取系统敏感文件、应用源码、数据库配置造成信息泄露。修复方案使用Path.normalize()做规范化再用startsWith()做目录约束。修复代码我写的是这样一个版本String fileName request.getParameter(fileName); Path baseDir Paths.get(/data/files/).toAbsolutePath().normalize(); Path target baseDir.resolve(fileName).toAbsolutePath().normalize(); if (!target.startsWith(baseDir)) { throw new SecurityException(非法文件路径); } File file target.toFile(); if (!file.exists() || !file.isFile()) { throw new FileNotFoundException(文件不存在); } // 继续读取文件并返回这段代码每一行都有作用第二行先把允许访问的根目录变成标准形式第三行把用户传入的文件名resolve到根目录下再做一次normalize把../都归并掉第四行检查目标路径是否仍然以根目录开头如果用户传了../../../../etc/passwdnormalize之后的路径就不再以baseDir开头直接拒绝最后再判断文件是否存在并限制只能读取普通文件避免命中目录或特殊文件。在答案里我额外写了几组测试用例这是很多应届生容易漏掉的部分正常请求fileNamereport.pdf期望返回文件。恶意请求fileName../../../../etc/passwd期望返回错误。编码请求fileName%2e%2e%2f%2e%2e%2fetc/passwd期望返回错误。绝对路径fileName/data/secret.txt期望返回错误。写上测试用例阅卷人会默认你有测试意识和交付意识。安全岗笔试不只是看你有没有漏洞嗅觉还看你会不会把方案落地成可以验证的东西。3. 密码学模块RSA参数、AES模式以及“概念迁移”的拿分技巧很多人做安全岗笔试题最怕密码学。其实奇安信这类公司的校招笔试题不会让你破解现代加密更多是看基础概念清不清楚以及能不能从“会用”上升到“会选”。我记得那套卷子里有一道RSA小计算题干类似“已知n33e7d3明文m5求密文c”。这种题放在实际场景里太小了但用来验证考生是否理解模幂公式非常有效。3.1 一道RSA小计算题的完整推导看到这种题别慌。RSA公钥加密公式就一条c m^e mod n。把数字代进去就是c 5^7 mod 33。手算的时候千万不要真的把5自乘7次再取模那不仅容易错还很浪费时间。我当时是这么拆的先算5^2 25再算5^4 25^2 625而625 mod 33 625 - 33×18 625 - 594 31。于是5^7 5^4 × 5^2 × 5 31 × 25 × 5 38753875 mod 33因为33×117 3861所以3875 - 3861 14。密文c 14。如果想验证一下私钥解密用m c^d mod n14^3 274433×83 2739余数是5正好还原明文。这种题把公式和中间步骤写清楚基本就拿满了。步骤公式结果加密c 5^7 mod 3314解密m 14^3 mod 335这里有一个关键点RSA计算公式是模幂不是直接求幂。很多同学写到最后忘记mod n或者把e和d用反那是必扣分的。还有如果题目再延伸问φ(n)、公钥和私钥的数学关系也要能够解释φ(n) (p-1)(q-1)这个来源。笔试里不一定会让你硬算大数但基本功不能模糊。3.2 比计算更容易失分的AES模式辨析除了RSA计算密码学简答题还特别爱问“AES-ECB模式有什么问题为什么推荐GCM”这个问题看似在考加密算法实际在考安全配置能力。ECB模式最大的问题是同样的明文块会被加密成同样的密文块。如果加密一张图片图片轮廓会在密文里隐隐可见如果攻击者能让受害者加密自己构造的明文块还能通过密文是否相同判断出“两个明文块是否相同”这就产生了模式泄露。所以在安全场景里ECB通常是不被推荐的。但如果你只说“ECB不安全所以用CBC”还没答到点子上。CBC虽然解决了模式泄露但不提供完整性保护。更稳妥的答法是推荐使用GCM这类带认证的AEAD模式因为它同时提供机密性、完整性、以及防重放能力。把这三个关键词写上去阅卷人就知道你不是死记硬背。还有一类常见的选择题“密码存储应该用MD5还是SHA-256”很多应届生会选SHA-256但实际上单纯SHA-256在GPU暴力破解面前依然不够。正确的思路是选加盐的慢哈希比如bcrypt、scrypt、PBKDF2。把“哈希算法”和“密码存储”这两个概念分开是安全岗的基本功。把这些内容放在一起记密码学部分基本不会失分。4. 编程题一道“第一个不重复字符”怎样写出安全岗风格笔试题二里的编程题没有LeetCode的Hard题我记得有一道和字符串有关的题类似“给定一个字符串找到第一个不重复的字符并返回下标如果不存在返回-1”。这道题看起来简单但安全公司的核分点有点不一样。除了要A还要A得像个安全工程师。4.1 我的第一版代码与第二版代码的差别第一版我写得非常快就是标准的哈希计数法def first_unique_char(s): dic {} for ch in s: dic[ch] dic.get(ch, 0) 1 for i, ch in enumerate(s): if dic[ch] 1: return i return -1这个版本功能上没有大问题时间复杂度O(n)空间复杂度O(字符集大小)能过大部分测试点。但放到安全岗的语境下我会再补一层“对不可信输入保持怀疑”的处理def first_unique_char(s): if not isinstance(s, str) or len(s) 0: return -1 if len(s) 10**6: return -1 count {} for ch in s: count[ch] count.get(ch, 0) 1 for i, ch in enumerate(s): if count[ch] 1: return i return -1第二版加了类型判断和超长输入限制。你可能觉得LeetCode标准答案不会这么写但在安全公司这种“不能盲目信任输入”的习惯是加分项。尤其是后端接口的入参可能来自前端、第三方服务、甚至攻击流量写接口时先想边界能少出很多事故。4.2 边界条件和测试用例是安全岗笔试的隐形题编程题里最容易被忽略的是边界条件。我后来和面试官复盘时他说批卷子时最怕看到“注释里写着一般不会发生这种情况”——因为安全工程师的日常就是处理那些“不太可能发生”的情况。这道题我会在提交前先自测几组用例输入输出-1。输入abcab输出下标2对应字符c。输入abab输出-1。输入None或非字符串对象输出-1。输入包含中文或emoji要确认字符遍历方式不会把Unicode拆错。如果是线上笔试系统只允许提交代码我会在代码开头用注释把这组用例写上去让阅卷人看到我的思考过程。这不算“作弊”这是在展示测试设计能力。安全岗写代码至少要像写测试用例一样认真。4.3 时间分配“先把测试用例写出来再动手写代码”我习惯的编程题流程是拿到题目后先不要急着写代码用3分钟在纸上把边界用例列出来再写主逻辑最后留2分钟跑一遍用例。这种习惯在LeetCode上可能显得慢但在笔试考场上反而稳。因为你一旦把“空字符串、单个字符、全部重复、超长输入、非字符串”这些情况想清楚代码框架就已经出来了。如果题目没有明说“是否区分大小写”“下标从0开始还是从1开始”我会在注释里写清楚自己的假设。安全岗笔试很看中这种“需求说不清我就去确认”的沟通意识而不是闷头实现一个和出题人预期不一致的版本。5. 考后复盘一张“原理-利用-修复”对照表带来面试机会笔试交卷后不管感觉好不好我建议立刻做一件事把卷子里见过的考点整理成一张“原理-利用-修复”对照表。这套复盘方法我到现在都还在用。它不是简单抄笔记而是逼你把每一个漏洞都切成三段来理解。5.1 我是怎么整理那张表的找一张A4纸横轴写三个字段原理、利用、修复。纵轴按知识点一行一行写。最开始几行可能会很粗糙比如“SQL注入原理是SQL拼接利用是注入参数修复是用预编译”。但整理到一半你会发现自己能填出来的部分越来越少而那些填不出来的恰恰就是你的复习重点。我当时花了两个晚上把路径遍历、SQL注入、XSS、CSRF、SSRF、不安全反序列化、验证码绕过这些考点全部过了一遍。这里给出一个简化版大家可以直接做参考考点一句话原理常见利用入口笔试高频问法最稳修复关键词SQL注入未参数化的SQL拼接登录、查询、排序参数写修复代码参数化查询 / PreparedStatement、最小权限XSS未转义输出用户输入搜索框、昵称、评论反射型/存储型区别上下文感知编码、CSP、HttpOnlyCSRF浏览器自动携带Cookie敏感操作接口如何防御CSRF Token、SameSite、二次校验路径遍历路径拼接可跳出目录下载、导入导出接口找出漏洞并修复normalize 白名单 startsWith不安全反序列化不可信数据被还原为对象Java/PHP反序列化入口如何识别并加固类型白名单、签名校验这张表整理完后我对后续面试的底气提升非常明显。面试官如果问“你对Web安全怎么看”我不会傻背定义而是直接说“我习惯把每个漏洞拆成原理、利用、修复三条线来讲比如路径遍历……”对方马上会想跟你有更多交流。5.2 笔试没考好怎么办我后来总结的三个“扳回”动作并不是所有笔试分数高的人都能走到最后也不是笔试一般的人就没有机会。我身边有同学笔试时编程题没AC但简历里有CTF经历照样直接进面试。如果你对笔试结果不自信可以试试这三个动作。第一24小时内复盘错题把修正后的思路写成一篇技术笔记发布到自己的博客或私有仓库里。面试时如果被问到相关知识点你可以坦然说“这道题笔试时我没答好但后续我重新梳理了一遍”这反而是加分项。第二把简历上跟安全相关的项目描述再打磨一下加一句“对用户输入做白名单校验”“对文件下载接口做路径归一化”这类具体动作。但注意不要造假你做过的项目、用过的技术栈都要经得起深挖。第三面试时主动要求讲一道你在笔试复盘里印象最深的题。安全岗面试非常看重主动思考的能力你能把路径遍历的完整思路讲清楚比背十道概念题都管用。5.3 给下一届校招生的安全岗笔试速查清单最后给一份速查清单不保证覆盖所有公司但至少能把常见考点兜住HTTP基础GET/POST/PUT/DELETE语义状态码401/403/404/500区别Cookie与Session关系。Web漏洞SQL注入、XSS、CSRF、SSRF、路径遍历、反序列化每一类都得能说出攻击链路和修复链路。密码学RSA加解密基本公式对称与非对称区别ECB模式问题密码存储要用加盐慢哈希。编程能力字符串/数组高频题注意类型、空值、超长、Unicode边界。系统基础Linux常用命令、文件权限、日志位置安全岗不会只考Web基础系统知识也要扫一遍。我记得当年交卷前把路径遍历那道题的修复代码反复改了三遍。后来真的开始做代码审计才发现笔试里那道题其实就是日常工作的最小副本一段看似人畜无害的文件下载代码因为少了normalize和startsWith校验变成了一个可以读取任意文件的突破口。如果你正在准备奇安信或者同类安全公司的校招别把笔试当成一场考试把它当成一次模拟工作台。你在卷子上写的每一行修复代码都会是你以后写给自己的作品。
返回列表