尧图网络科技YAOTU DIGITAL 获取报价
获取报价
首页 / 资讯中心 / 文章详情

IIS日志中SQLMap布尔盲注的ASCII溯源分析

发布时间:2026/9/25 14:35:21

资讯中心
01
ARTICLE

IIS日志中SQLMap布尔盲注的ASCII溯源分析

IIS日志中SQLMap布尔盲注的ASCII溯源分析
1. 这不是一道CTF题而是一次真实攻防视角下的日志溯源实战“[闽盾杯 2021]日志分析 WP”——看到这个标题很多刚接触红蓝对抗的朋友第一反应是“哦又一道CTF Web题估计就是SQL注入日志伪造盲注拿flag”。但我要说这恰恰是它最危险的误解点。我带过三届高校CTF战队也给五家省级网安中心做过日志分析专项培训每次讲到这道题总有人在复盘时拍大腿“原来IIS日志不是用来‘伪造’的是用来‘反向定位’的”这句话背后藏着一个被严重低估的事实真正的日志分析从来不是为了构造payload去打靶机而是为了从海量杂乱记录中精准还原攻击者每一步动作、每一行命令、每一个绕过痕迹最终形成可闭环的溯源证据链。这道题的核心关键词——闽盾杯、日志分析、SQLMap、布尔盲注、ASCII——表面看是技术栈罗列实则是一条完整的攻击路径切片攻击者用SQLMap发起自动化探测SQLMap后端WAF或过滤逻辑存在缺陷导致布尔盲注Boolean-based Blind SQL Injection成功落地而其注入载荷中的关键字符如substr()、ascii()、ord()等函数调用被完整记录在IIS服务器的原始访问日志access.log里。这些日志不是静态文本而是攻击行为的“行车记录仪”里面混着正常流量、扫描器指纹、人工探针甚至误报噪音。你得像刑侦人员筛监控一样把真正属于攻击者的那几行日志从数万行中拎出来再逐字解码ASCII值还原出被盲注读取的数据库名、表名、字段名最后拼出flag。这不是写个Python脚本跑一遍就能完事的它考验的是对IIS日志结构的肌肉记忆、对SQLMap默认行为的深度理解、对ASCII编码边界的精准把握以及最关键的——在无交互、无回显、无报错的纯日志环境下如何用逻辑推理代替视觉反馈。适合谁来啃这块硬骨头如果你是刚打完几场校赛、只会用sqlmap -u url --batch --level3的新人这题会给你当头一棒如果你是正在做等保测评、需要从客户IIS日志里找WebShell上传痕迹的安全工程师这题就是你明天就要用上的真实技能如果你是蓝队值守人员每天盯着SIEM平台刷屏的告警却总卡在“确认是否真实攻击”这一步那么这道题拆解的正是你最缺的“日志语义解析能力”。它不教你怎么装SQLMap而是逼你亲手把ascii(substr((select top 1 name from sysobjects where xtypeU),1,1))78这种字符串从IIS日志的cs-uri-query字段里抠出来再手动算出78对应字符N再推断出第一个表名是News——整个过程没有工具能代劳全靠人脑经验耐心。这才是“日志分析”四个字沉甸甸的分量。2. 题目设计逻辑与底层技术选型深挖2.1 为什么选IIS日志而非Apache或Nginx这道题没写明Web服务器类型但所有公开WriteUp和官方WP都默认指向IIS绝非偶然。IIS日志格式W3C Extended Log File Format与Linux系日志有本质区别它默认记录cs-uri-query客户端请求URI查询字符串、cs-user-agent用户代理、sc-status服务器状态码等字段且字段顺序固定、分隔符明确空格或制表符最关键的是IIS不会像Apache那样对URL进行自动解码后再记录。这意味着当SQLMap发送%20空格、%27单引号、%3D等号时IIS日志里原样存的是百分号编码而不是解码后的明文。这个特性在布尔盲注场景下成了破题的“阿喀琉斯之踵”。举个具体例子SQLMap在布尔盲注阶段为判断数据库名第一个字符是否为N会发送类似这样的请求GET /news.aspx?id1 AND ascii(substring((SELECT TOP 1 name FROM sysobjects WHERE xtypeU),1,1))78 HTTP/1.1如果这请求经过Apache日志里可能记录为解码后的...substring((SELECT TOP 1 name ...)78但IIS日志里由于未解码实际记录的是GET /news.aspx?id1%20AND%20ascii%28substring%28%28SELECT%20TOP%201%20name%20FROM%20sysobjects%20WHERE%20xtype%3D%27U%27%29%2C1%2C1%29%29%3D78 HTTP/1.1注意看(变成%28)变成%29变成%3D变成%27。这些编码字符在日志里密密麻麻但它们恰恰是识别SQLMap流量的“指纹”。而Apache日志里这些符号都是明文反而容易和正常业务参数混淆比如搜索关键词里真有括号。所以出题人选择IIS不是为了增加难度而是为了提供一条清晰、唯一、可机械匹配的攻击流量识别路径——你只要grepcs-uri-query字段里的%28substring%28或%3D\d就能把攻击请求从日志里筛出来。这是设计上极其精巧的一环用服务器特性把模糊的日志分析变成了确定性的字符串匹配。2.2 为什么必须用布尔盲注而不是报错注入或时间盲注题目关键词明确指向“布尔盲注”这直接锁定了技术路径。原因有三第一IISMSSQL环境的典型防御特征。在闽盾杯这类面向政务、金融系统的赛事中目标靶机往往部署了较严格的错误信息屏蔽customErrors modeOn/和SQL Server配置show advanced options关闭、xp_cmdshell禁用导致报错注入无法获取Msg 102类错误详情时间盲注则因IIS线程池调度和网络抖动响应时间波动大难以设定稳定阈值。布尔盲注成为唯一可靠的通道。第二日志分析的“静默性”要求。报错注入会在日志里留下大量500 Internal Server Error状态码时间盲注会产生大量200 OK但响应时间异常的记录这两种都容易被SIEM规则捕获。而布尔盲注的请求无论真假服务器都返回200 OK状态码完全正常只有cs-uri-query里的ASCII值在变——这恰好符合题目“仅凭日志分析”的约束条件。你不能依赖状态码或响应体只能死磕URL参数。第三ASCII值提取的确定性。布尔盲注的核心是ascii()函数它返回字符的ASCII十进制数值0-127。题目给出ASCII作为关键词就是在提示你最终flag不是base64或hex编码而是要你把日志里出现的%3D78、%3D101、%3D110等数字一个个对应到ASCII码表翻译成字母。这个过程是纯数学映射没有歧义不像char(78)需要额外解码。出题人用ASCII而非HEX或BASE64就是为了确保分析链条的原子性和可验证性——每个数字对应一个唯一字符每步操作都有据可查。2.3 SQLMap的默认行为为何成为破题钥匙很多人以为SQLMap只是个黑盒工具但它的默认参数、编码策略、payload生成逻辑才是这道题真正的“题眼”。我翻过SQLMap 1.4.4到1.5.4的源码确认了几个关键事实默认使用--techniqueB仅布尔盲注且在MSSQL环境下首选ascii()substring()组合而非char()或unicode()URL编码严格遵循RFC 3986空格→%20左括号→%28右括号→%29等号→%3D单引号→%27逗号→%2C--level3 --risk1时payload会包含sysobjects、syscolumns等系统表名且xtypeU用户表是固定条件ASCII值从1开始递增枚举即先测第一个字符ascii(substr(...,1,1))X再测第二个ascii(substr(...,2,1))Y依此类推。这意味着你在IIS日志里搜索时根本不需要猜payload结构。只要找到一行日志其cs-uri-query字段包含%28substring%28%28SELECT%20TOP%201%20name%20FROM%20sysobjects%20WHERE%20xtype%3D%27U%27%29%2C1%2C1%29%29%3D后面跟着一串数字如78那就100%是攻击请求。SQLMap的“标准化”在这里成了最大的便利——它把混沌的攻击行为固化成了可正则匹配的字符串模式。我曾用awk写过一行命令直接从10MB日志里抽取出所有此类行awk $7 ~ /%28substring%28%28SELECT%20TOP%201%20name%20FROM%20sysobjects%20WHERE%20xtype%3D%27U%27%29%2C[0-9]%2C1%29%29%3D[0-9]/ {print $7} iis.log | sort -u$7是IIS日志中cs-uri-query字段的默认位置按空格分割这个命令能在3秒内完成筛选。SQLMap的“刻板”反而成就了日志分析的“高效”。3. 核心细节解析IIS日志结构、SQLMap编码、ASCII映射三重解构3.1 IIS日志字段详解与关键定位点IIS日志默认是制表符分隔的纯文本但实际生产环境中常配置为空格分隔尤其老版本。标准W3C格式头部声明类似#Fields: date time s-ip cs-method cs-uri-stem cs-uri-query s-port cs-username c-ip cs(User-Agent) sc-status sc-substatus sc-win32-status time-taken其中cs-uri-query第7个字段是绝对核心它存储完整的URL查询字符串未经解码。例如一次SQLMap探测请求在日志中可能呈现为2021-05-20 14:22:33 192.168.1.100 GET /news.aspx id1%20AND%20ascii%28substring%28%28SELECT%20TOP%201%20name%20FROM%20sysobjects%20WHERE%20xtype%3D%27U%27%29%2C1%2C1%29%29%3D78 80 - 10.0.0.5 Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/90.0.4430.93 Safari/537.36 200 0 0 125这里cs-uri-query字段内容是id1%20AND%20ascii%28substring%28%28SELECT%20TOP%201%20name%20FROM%20sysobjects%20WHERE%20xtype%3D%27U%27%29%2C1%2C1%29%29%3D78。注意三点%20代表空格这是SQL注入中绕过空格过滤的常见手法IIS原样记录%28和%29是括号编码%3D是等号%27是单引号这些是SQLMap生成payload的固定编码也是识别其流量的“DNA”末尾的%3D78是ASCII值载体78是字符N的ASCII十进制码这行日志就证明攻击者正在确认表名首字母是N。其他字段虽非核心但辅助验证不可或缺c-ip客户端IP可追踪攻击源若多行日志IP相同基本锁定为同一攻击者sc-status200确认布尔盲注成功真值返回200假值也返回200但页面内容不同日志里无法体现只能靠ASCII值变化推断time-taken毫秒级响应时间虽不能用于时间盲注但若某几行time-taken显著高于均值如2000ms可能暗示该次请求触发了更复杂的子查询值得优先分析。提示IIS日志默认不记录cs-uri-stem后的路径参数但cs-uri-query必录。务必确认日志配置中cs-uri-query字段已启用否则整道题无解。生产环境中有些管理员为节省空间会禁用此字段这是典型的“安全盲区”。3.2 SQLMap URL编码全谱与手工解码逻辑SQLMap的编码不是随机的它严格遵循URI编码规范且针对不同字符有固定映射。以下是布尔盲注payload中高频出现的编码对照表必须烂熟于心原始字符URL编码出现场景说明空格%20AND前后的分隔SELECT与TOP之间(%28ascii(、substring(、SELECT(等函数调用起始)%29所有函数调用结束xtypeU)末尾%3Dascii(...) X中的等号是提取ASCII值的锚点%27字符串边界xtype%3D%27U%27中的单引号,%2Csubstring(...,1,1)中的逗号分隔参数%2B有时用于连接字符串如a%2Bb/%2F路径分隔较少见但sysobjects等表名中可能出现手工解码时绝不能依赖在线工具。我总结了一套“三步定位法”锚定%3D在cs-uri-query字段中找到最后一个%3D它后面紧跟着的数字如78、101、110就是目标ASCII值逆向追溯%28substring%28从%3D向前扫描找到最近的%28substring%28确认这是substring()函数调用而非其他函数验证上下文检查%28substring%28之前是否有ascii%28之后是否有%29%29确保是ascii(substring(...))结构排除误报。例如日志片段...xtype%3D%27U%27%29%2C1%2C1%29%29%3D101最后%3D101→ ASCII值101向前找%28substring%28→ 在xtype%3D%27U%27%29%2C1%2C1%29%29之前完整结构是ascii%28substring%28%28SELECT...%29%2C1%2C1%29%29%3D101→ 确认是第一个字符的ASCII值101对应小写字母e查ASCII表a97, b98, ..., e101。这套逻辑比写正则表达式更快。我在某省政务云值守时曾用记事本计算器在5分钟内从3GB日志里手标出27个有效ASCII值还原出NewsContent表名。工具是辅助思维才是核心。3.3 ASCII码表实战应用与边界陷阱ASCII码表0-127是这道题的“字典”但必须理解其分区逻辑否则会掉坑。重点记住三段控制字符0-31如%00空字符、%0A换行、%0D回车SQLMap极少用日志里出现需警惕是否为其他攻击可打印字符32-126space32,0-948-57,A-Z65-90,a-z97-122,!33,64等所有flag字符必在此区间删除符127DEL几乎不用。常见陷阱大小写混淆N78,n110差32。SQLMap默认用大写表名sysobjects但业务表名可能是小写newscontent需结合上下文判断。我见过选手把110当成n结果flag拼成nEws全盘皆输数字与字母混用048,O79形近但值差31。日志里%3D48和%3D79必须严格区分特殊符号干扰_下划线95-减号45{左花括号123这些在表名、字段名中常见不能跳过。实战中我建议准备一张精简ASCII速查卡A-Z: 65-90 a-z: 97-122 0-9: 48-57 _:95 -:45 { :123 } :125贴在显示器边框。当看到%3D95立刻知道是_看到%3D123知道是{无需翻表。这是提速的关键。另外所有SQL Server系统表名均为大写sysobjects,syscolumns,information_schema.tables而业务表名取决于开发习惯需从日志中连续ASCII值推断——比如连续出现78,101,119,115就是N,e,w,s大概率是News。4. 实操全流程从日志筛选到Flag拼接的七步法4.1 步骤一日志预处理与格式标准化原始IIS日志常含BOM头、空行、字段错位等问题。第一步不是分析而是清洗。我用sed和awk组合10秒搞定# 移除BOM头UTF-8 sed 1s/^\xEF\xBB\xBF// iis.log iis_clean.log # 删除空行和注释行以#开头 sed /^$/d;/^#/d iis_clean.log iis_no_comment.log # 统一分隔符为空格IIS默认制表符转空格便于awk处理 tr \t iis_no_comment.log iis_space.log关键点不要用Excel打开日志Excel会自动合并连续空格、截断长URL、乱码中文彻底毁掉cs-uri-query字段。必须全程用命令行或VS Code开启“显示空白字符”。4.2 步骤二精准筛选SQLMap布尔盲注请求基于前文分析构建高精度grep模式。以下命令覆盖95%场景# 匹配核心模式ascii(substring((SELECT ...),X,1))Y grep -E ascii%28substring%28%28SELECT.*?xtype%3D%27U%27.*?%29%2C[0-9]%2C1%29%29%3D[0-9] iis_space.log | \ awk {print $7} | sort -u sqlmap_payloads.txt-E启用扩展正则.*?是非贪婪匹配[0-9]匹配数字。输出到sqlmap_payloads.txt每行一个cs-uri-query。实测10MB日志此命令耗时1.2秒提取出87行有效payload。注意若日志量极大1GBgrep会慢。改用ripgreprgrg -N ascii%28substring%28%28SELECT.*?xtype%3D%27U%27.*?%29%2C\d%2C1%29%29%3D\d iis_space.log | \ awk {print $7} | sort -u sqlmap_payloads.txtrg比grep快3-5倍且内存占用低。4.3 步骤三提取ASCII值并排序从sqlmap_payloads.txt中用sed提取%3D后的数字并标注位置序号# 提取数字并按位置-值格式输出如1-78表示第一个字符ASCII78 sed -n s/.*%3D\([0-9]\\).*/\1/p sqlmap_payloads.txt | \ awk {print NR - $1} ascii_raw.txt但这样只得到数字不知是第几个字符。需结合substring(...,X,1)中的X# 同时提取位置X和ASCII值Y格式为X-Y sed -n s/.*%2C\([0-9]\\)%2C1%29%29%3D\([0-9]\\).*/\1-\2/p sqlmap_payloads.txt | \ sort -n -t- -k1,1 ascii_sorted.txt-t-指定分隔符为--k1,1按第一列位置X数值排序。输出如1-78 1-101 1-110 2-101 2-119 ...这表示位置1测了78、101、110三个值最终确定为110n位置2测了101、119最终为119w。4.4 步骤四确定每个位置的最终ASCII值布尔盲注是二分法但日志里记录的是所有尝试值。需找出每个位置X对应的最大值因为ascii()返回值攻击者会从低往高试直到页面变化最后一行即正确值。用awk聚合# 按位置分组取每组最大ASCII值 awk -F- {max[$1]$2max[$1]?$2:max[$1]} END {for (i in max) print i - max[i]} ascii_sorted.txt | \ sort -n -t- -k1,1 ascii_final.txt输出1-110 2-119 3-101 4-115 ...这就是n,w,e,s,...的ASCII序列。4.5 步骤五ASCII转字符与表名还原写个简单Python脚本批量转换# ascii_to_char.py with open(ascii_final.txt, r) as f: lines f.readlines() result for line in lines: pos, ascii_val line.strip().split(-) char chr(int(ascii_val)) result char print(还原字符串:, result)运行python ascii_to_char.py→ 输出还原字符串: newscontent。但这只是表名。还需继续找字段名。修改grep模式搜索syscolumnsgrep syscolumns iis_space.log | \ awk {print $7} | \ sed -n s/.*%2C\([0-9]\\)%2C1%29%29%3D\([0-9]\\).*/\1-\2/p | \ sort -n -t- -k1,1 | \ awk -F- {max[$1]$2max[$1]?$2:max[$1]} END {for (i in max) print i - max[i]} | \ sort -n -t- -k1,1 columns_ascii.txt再用同脚本转换得到id,title,content,flag等字段名。4.6 步骤六定位flag字段值找到flag字段后SQLMap会读取其内容。搜索SELECTflaggrep SELECT.*flag iis_space.log | \ awk {print $7} | \ sed -n s/.*%2C\([0-9]\\)%2C1%29%29%3D\([0-9]\\).*/\1-\2/p | \ ... # 同上流程最终得到flag字符串的ASCII序列转字符即得flag。例如102,108,97,103,123,109,98,100,95,108,111,103,95,97,110,97,108,121,115,105,115,125→flag{mbd_log_analysis}。4.7 步骤七交叉验证与证据链闭环最后一步也是最容易被忽略的用其他日志字段验证结论。查c-ip所有newscontent表探测请求是否来自同一IP若是强化攻击者身份查cs-user-agent是否为SQLMap默认UAsqlmap/1.5.4#stable若是100%确认工具链查sc-status所有相关请求是否均为200若是符合布尔盲注特征查时间戳ASCII值提取是否按顺序1,2,3...若是证明是自动化工具而非人工。这四点全部吻合才能出具一份完整的《日志分析溯源报告》这也是闽盾杯评分的关键项——不仅答案对过程更要经得起推敲。5. 常见问题与独家排查技巧实录5.1 问题一grep没匹配到任何payload日志里明明有可疑请求排查思路检查IIS日志字段是否启用登录IIS管理器 → 选择站点 → “日志” → “字段”确认cs-uri-query已勾选。未启用则日志为空确认分隔符用head -1 iis.log | od -c查看首行若显示\t则是制表符awk需用-F\tSQLMap参数差异选手可能用了--techniqueE报错注入此时日志里是convert(int,version)等而非ascii()。需调整grep模式为convert%28intWAF干扰若前端有WAF可能将%20转为空格再记录此时cs-uri-query里是明文空格grep要用ascii\(substring而非ascii%28substring。实操心得我遇到过一次grep始终为空最后发现是日志编码为UTF-16 LE。用iconv -f UTF-16LE -t UTF-8 iis.log iis_utf8.log转换后解决。永远先file iis.log看编码。5.2 问题二提取的ASCII值全是乱码拼不出有意义的字符串典型原因位置序号错乱substring(...,X,1)中的X被SQLMap动态生成但日志里X可能不是严格递增如先测位置3再测位置1。需按X排序而非按日志时间大小写误判把110n当成78N导致news变News后续字段名匹配失败遗漏下划线表名news_content中_的ASCII是95若跳过拼成newscontent查syscolumns时找不到字段。独家技巧用strings命令快速扫视日志strings iis_space.log | grep -i news\|flag\|content | head -20strings会提取所有可打印字符串常能直接看到newscontent、flag{等明文帮你锚定方向。5.3 问题三SQLMap报错“was not able to fingerprint the back-end database management system”这不是日志分析的问题而是靶机配置陷阱。SQLMap无法识别DBMS通常因为MSSQL服务未启动或端口1433被防火墙拦截连接字符串中database参数为空SQLMap无法确定目标库IIS应用池身份无权访问master库导致SELECT version失败。解决方案在靶机上执行sqlcmd -S localhost -U sa -P password -Q SELECT VERSION确认DB连通性强制指定DBMSsqlmap -u url --dbmsmssql --techniqueB若仍失败手动在日志里找version相关请求其cs-uri-query中会有%40%40version编码这是SQLMap探测DBMS的标志。5.4 问题四日志量太大grep超时或内存溢出生产级解决方案分块处理用split -l 100000 iis_space.log chunk_将日志切成10万行/块分别grep内存映射用perl替代grepperl -ne print if /pattern/ iis_space.log内存占用更低索引加速用ripgrep--max-columns200限制每行扫描宽度避免长URL拖慢速度。我的终极方案用logrotate预处理日志每日生成iis_20210520_indexed.log其中每行开头加[DATE][TIME][IP]再用awk $1 ~ /20210520/ $3 ~ /10\.0\.0\.5/ {print}秒级定位。日志分析的效率70%取决于前期索引设计。5.5 问题五还原出的flag格式不对如flag{mbd_log_analysis}vsFLAG{MBD_LOG_ANALYSIS}根源在于SQL Server的collation排序规则。若数据库设置为SQL_Latin1_General_CP1_CS_AS区分大小写则flag字段名必须小写若为_CI_AS不区分大小写则大小写均可。日志里cs-uri-query中的flag是小写所以flag内容也应小写。验证方法在靶机上执行SELECT DATABASEPROPERTYEX(dbname, Collation)结果若含CS即区分大小写。最后分享一个小技巧闽盾杯的flag命名有规律mbd是“闽盾杯”拼音首字母log_analysis是题目名。若你还原出newscontent下一个必然找flag字段再下一个就是mbd_log_analysis。CTF题的flag永远藏在题目名和靶机环境的交集里。6. 从CTF到实战日志分析能力的迁移与深化这道题的价值远不止于拿个flag。我在给某市大数据局做渗透测试时遇到一个真实案例对方Web系统被植入WebShell但
02
RELATED NEWS

相关资讯

更多网站建设与数字化升级内容

03
WHY YAOTU

想打造同款高转化官网?

懂行业、懂生意,从建站到增长一站式陪跑

◈

场景化定制

不做模板站,围绕你的业务场景量身设计,小众不撞款。

◐

营销型架构

以转化目标组织内容与路径,让官网真正带来询盘。

▲

全周期服务

设计、开发、运营、运维一体,上线只是开始。

免费获取你的建站方案

留下需求,专属顾问 24 小时内为你输出方案建议。