[{"data":1,"prerenderedAt":174},["ShallowReactive",2],{"posts-doc:/posts/log-analysis":3},{"id":4,"title":5,"body":6,"date":158,"description":159,"extension":160,"img":161,"meta":162,"navigation":163,"path":164,"seo":165,"stem":166,"tags":167,"type":172,"__hash__":173},"posts/posts/Log Analysis.md","Log Analysis",{"type":7,"value":8,"toc":152},"minimark",[9,14,18,26,36,43,49,56,62,77,83,86,90,100,106,109,115,118,122,134,140,143,149],[10,11,13],"h2",{"id":12},"shit-we-got-hit","Shit, We Got Hit",[15,16,17],"p",{},"Bud, they are on to us. I just received an e-mail from our SIEM saying that we got hit. What happened? What do you mean \"you don't know\"? Ok, ok, it's not a good time to fight. Let's try to figure it out.",[15,19,20,21,25],{},"Download the file. It's a really bad idea, but our web-dev team chose to leave the log file directly at our website ",[22,23,24],"code",{},"http://businesscorp.com.br/access.log",". At least we just have to cURL from there:",[27,28,33],"pre",{"className":29,"code":31,"language":32},[30],"language-text","bud@myawesomepc:~/$ curl -O http://businesscorp.com.br/access.log\n  % Total    % Received % Xferd  Average Speed   Time    Time     Time  Current\n                                 Dload  Upload   Total   Spent    Left  Speed\n100 6628k  100 6628k    0     0   156k      0  0:00:42  0:00:42 --:--:--  117k\n\n","text",[22,34,31],{"__ignoreMap":35},"",[15,37,38,39,42],{},"Holy shit, this is bad. Look at that file size. Ok, let's delve into it. ",[22,40,41],{},"cat"," file.",[27,44,47],{"className":45,"code":46,"language":32},[30],"bud@myawesomepc:~/$ head access.log\n182.118.53.93 - - [08/Feb/2015:08:10:21 -0200] \"GET / HTTP/1.1\" 200 2477 \"-\" \"Mozilla/5.0 (Macintosh; Intel Mac OS X 10_10_1) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/41.0.2251.0 Safari/537.36\"\n149.129.173.104 - - [08/Feb/2015:19:46:49 -0200] \"GET /tmUnblock.cgi HTTP/1.1\" 400 522 \"-\" \"-\"\n82.213.78.2 - - [08/Feb/2015:22:04:52 -0200] \"GET /cgi-bin/test-cgi HTTP/1.1\" 404 532 \"-\" \"the beast\"\n82.138.16.125 - - [08/Feb/2015:23:09:41 -0200] \"GET /manager/html HTTP/1.1\" 404 502 \"-\" \"Mozilla/5.0 (Windows NT 5.1; rv:5.0) Gecko/20100101 Firefox/5.0\"\n189.36.234.53 - - [09/Feb/2015:06:33:24 -0200] \"GET / HTTP/1.1\" 200 2533 \"-\" \"Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/40.0.2214.111 Safari/537.36\"\n...\n\n",[22,48,46],{"__ignoreMap":35},[15,50,51,52,55],{},"Not so ufesul, but this gave me an idea. Try to filter by IP using ",[22,53,54],{},"cut"," to separate the columns.",[27,57,60],{"className":58,"code":59,"language":32},[30],"bud@myawesomepc:~/$ cut -d \" \" -f 1 access.log \n182.118.53.93\n149.129.173.104\n82.213.78.2\n82.138.16.125\n189.36.234.53\n189.36.234.53\n...\n",[22,61,59],{"__ignoreMap":35},[15,63,64,65,68,69,72,73,76],{},"Ok, not so useful again. Too many IPs, but I can see some of them are duplicates. Too many actually. Ok, let's check how many request each of them made. Firstly, sort the IPs using ",[22,66,67],{},"sort",". This will help the ",[22,70,71],{},"uniq -c"," count exactly how many times each of them appeared. Sort them again using ",[22,74,75],{},"sort -r"," so the higher numbers are listed first.",[27,78,81],{"className":79,"code":80,"language":32},[30],"bud@myawesomepc:~/$ cut -d \" \" -f1 access.log | sort | uniq -c | sort -nr\n  37038 177.138.28.7\n    161 189.36.234.53\n     49 187.101.118.104\n     45 191.181.5.157\n     32 199.193.251.194\n     31 85.236.52.212\n     29 187.38.19.108\n     26 201.46.150.143\n\n",[22,82,80],{"__ignoreMap":35},[15,84,85],{},"We found them. Let's see what this script kiddie was doing.",[10,87,89],{"id":88},"script-kiddies-fall","Script Kiddie's Fall",[15,91,92,93,96,97],{},"Since we found his IP, we can begin checking what he tried exactly. Filter the requests by his IP and put another filter with tools like ",[22,94,95],{},"nmap"," and ",[22,98,99],{},"nikto",[27,101,104],{"className":102,"code":103,"language":32},[30],"bud@myawesomepc:~/$ cat access.log | grep 177.138.28.7 | egrep \"nmap|nikto\"\n177.138.28.7 - - [13/Feb/2015:02:12:07 -0200] \"HEAD /js/jquery-1.10.2.min.js~ HTTP/1.1\" 404 182 \"-\" \"Mozilla/5.0 (compatible; Nmap Scripting Engine; http://nmap.org/book/nse.html)\"\n177.138.28.7 - - [13/Feb/2015:02:12:08 -0200] \"GET /?test=38 HTTP/1.1\" 200 7136 \"-\" \"Mozilla/5.0 (compatible; Nmap Scripting Engine; http://nmap.org/book/nse.html)\"\n177.138.28.7 - - [13/Feb/2015:02:12:08 -0200] \"HEAD /favicon.png HTTP/1.1\" 200 255 \"-\" \"Mozilla/5.0 (compatible; Nmap Scripting Engine; http://nmap.org/book/nse.html)\"\n177.138.28.7 - - [13/Feb/2015:08:21:14 -0200] \"PUT /nikto-test-CkRmtvCL.html HTTP/1.1\" 405 609 \"-\" \"Mozilla/5.00 (Nikto/2.1.6) (Evasions:None) (Test:put_del_test: PUT)\"\n...\n",[22,105,103],{"__ignoreMap":35},[15,107,108],{},"Yeah, it's definitely a script kiddie. Didn't even try to spoof the HTTP request agent. It seems he let some default scripts running to see what happens. It seems harmless, but, just to be sure, filter his requests with our sitemap to see if he found out about something critical. Don't worry about the command, just run the damn thing.",[27,110,113],{"className":111,"code":112,"language":32},[30],"bud@myawesomepc:~/$ grep -f \u003C(grep -oP '(?\u003C=\u003Cloc>).*?(?=\u003C/loc>)' sitemap.xml) access.log\n177.138.28.7 - - [13/Feb/2015:05:26:36 -0200] \"GET /AcessoRestrito HTTP/1.1\" 301 590 \"-\" \"Mozilla/5.0 (X11; Linux x86_64; rv:31.0) Gecko/20100101 Firefox/31.0 Iceweasel/31.4.0\"\n177.138.28.7 - - [13/Feb/2015:05:26:36 -0200] \"GET /AcessoRestrito/ HTTP/1.1\" 200 660 \"-\" \"Mozilla/5.0 (X11; Linux x86_64; rv:31.0) Gecko/20100101 Firefox/31.0 Iceweasel/31.4.0\"\n177.138.28.7 - - [13/Feb/2015:05:26:36 -0200] \"GET /icons/blank.gif HTTP/1.1\" 200 437 \"http://www.grandbusiness.com.br/AcessoRestrito/\" \"Mozilla/5.0 (X11; Linux x86_64; rv:31.0) Gecko/20100101 Firefox/31.0 Iceweasel/31.4.0\"\n...\n",[22,114,112],{"__ignoreMap":35},[15,116,117],{},"Shit. It's bad. This little bastard got access to our restricted portal. It's time for damage control.",[10,119,121],{"id":120},"damage-control","Damage Control",[15,123,124,125,129,130,133],{},"Ok, first of all, ",[126,127,128],"strong",{},"BLOCK HIS ASS",". Like now. Enter our ",[22,131,132],{},"/etc/apache2/apache2.conf","file and make sure that his IP is blocked globally",[27,135,138],{"className":136,"code":137,"language":32},[30],"...\n\u003CDirectory /var/www/>\n        Options Indexes FollowSymLinks\n        AllowOverride None\n\n        \u003CRequireAll>\n                Require all granted\n                Require not ip 177.138.28.7\n        \u003C/RequireAll>\n\u003C/Directory>\n...\n",[22,139,137],{"__ignoreMap":35},[15,141,142],{},"Ok, ok. Restart the server now. Some users might complain, but we don't have time for this. In the mean time, I'll contact blue team to block his IP at firewall level too.",[27,144,147],{"className":145,"code":146,"language":32},[30],"bud@myawesomepc:~/$ sudo systemctl reload apache2\n",[22,148,146],{"__ignoreMap":35},[15,150,151],{},"Done? Good. Now we should add some silly agent blocking, just to avoid these script kiddies. Better hackers might spoof the request agent, for them we add WAF later on. We might aswell set a better logging alternative. Since we have a SIEM, why the hell are we downloading log files directly from the web? And why are these log files public at the first place? Sometimes I don't even know why I work here. Maybe it's because of you, Bud. You did good.",{"title":35,"searchDepth":153,"depth":153,"links":154},2,[155,156,157],{"id":12,"depth":153,"text":13},{"id":88,"depth":153,"text":89},{"id":120,"depth":153,"text":121},"2026-03-17","Shit, they are on to us. Read these logs and find the attacker.","md",null,{},true,"/posts/log-analysis",{"title":5,"description":159},"posts/Log Analysis",[168,169,170,171],"Linux","OffSec","Apache2","BlueTeam","Article","7YbJ1Nq3sbUWLIlbZaSsnxrO91t-JsSji9jyfXOol1w",1774877257580]