├── .gitignore ├── README.md ├── auto_ossec.bin ├── auto_ossec.exe ├── auto_ossec.py ├── auto_server.bin ├── auto_server.py ├── readme ├── CHANGELOG.txt └── LICENSE.txt ├── requirements.txt └── wxs ├── Create-AutoOssecMsi.ps1 └── auto_ossec.wxs /.gitignore: -------------------------------------------------------------------------------- 1 | *.msi 2 | *.wixobj 3 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 2 | Binary Defense Systems Auto-Enroll for OSSEC 3 | Written by: David Kennedy - Binary Defense 4 | Twitter: @HackingDave @BinaryDefense 5 | Supported Systems: Linux, OS X, Windows 6 | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 7 | 8 | The auto ossec enrollment will automatically provision OSSEC agents for both Linux and Windows. This is accomplished through a customized protocol 9 | that interfaces with the ossec server and the automatic pairing of the server. 10 | 11 | 12 | Descriptions: 13 | 14 | auto_server.py - this file contains the server to house the protocol - the port needed for this is 9654. The agents will communicate with the agents to this server script that is running. This server script should be placed in an automatic init script and through watchdog in order to ensure its always running. This script needs to be placed on the OSSEC server itself. 15 | 16 | auto_ossec.exe and auto_ossec.py - auto_ossec.exe is to run on Windows, and auto_ossec.py to run on Linux and OS X. When running the tool you will need to issue auto_ossec.exe - this will be the IP address of the server itself. 17 | 18 | auto_ossec.bin - precompiled for Linux with all libraries bundies in (including python-crypto) 19 | 20 | Deployment Instructions: 21 | 22 | Install OSSEC server on a system. Ensure that auto_server.py is automatically started when reboot occurs, and watchdog in order to ensure its always running. Also ensure no iptables conflict with port 9654 - this port is needed for the two way communication. 23 | 24 | Install OSSEC on a Linux or Windows system as an agent. Then run auto_ossec.exe, auto_ossec.bin, or auto_ossec.py with the IP address of the SERVER that is running auto_server.py. This will automatically pair the instances of OSSEC. 25 | 26 | NOTE THAT ALL OF THESE NEED TO BE PERFORMED WITH ROOT OR ADMINISTRATIVE LEVEL PERMISSIONS. THIS WILL FAIL IF IT IS NOT INSTALLED WITH ADMIN PRIVS. 27 | 28 | Mass Deployment Instructions: 29 | 30 | Create a deployment package that first installs the OSSEC binary or tar ball from (http://www.ossec.net/?page_id=19). Once the install completes, run the auto_ossec and you are finished. Services will automatically restart. 31 | 32 | Ports Needed: 9654 33 | 34 | What the server should look like when you run it in an interactive interface: 35 | 36 | Client connected with ('192.168.170.165', 50662) 37 | [*] Provisioned new key for hostname: STRONGHOLD-WIN8 with IP of: 192.168.170.165 38 | [*] Sending new key to 192.168.170.165: 8zlUouJ7yVOvt06Er8yx1zTchy5VQklfovu4SXW3GX7X8gH5tPIZ1104wvleQoZmJ9Hod++ByQtgNSLrQV7Z7rsRZLhCS9hFxPwRTZu6JC80EUXJ4yuTqFPHf9L2QuDjelP0yUvFFExf0xm7czlmDVH6/VKRdms1nL8+mwC9S81aZ0IOGpZuIMbIwiyeVxyBpctCk0Qd5CHoVZaKpAWTtA== 39 | Pairing complete. Terminating connection to client. 40 | 41 | ## Linux Automatic Installation 42 | 43 | You can now automatically install Linux as part of the auto_ossec.bin and auto_ossec.py installer. If the proper variable is specified, auto_ossec will automatically download OSSEC from the Internet, install it for you as an agent, and configure the server and keypairs for you. 44 | 45 | In order to automatically install Linux, run the following command as root/sudo: 46 | 47 | ./auto_ossec.bin url=urlto/ossec.tar.gz 48 | 49 | The server IP address is the IP address of your OSSEC server installation. The url= specifies that you want to automatically install. You can also specify a wildcard for your hostname of the AGENT. To do this you can type: 50 | 51 | ./auto_ossec.bin 0.0.0.0/0 url=https://bintray.com/artifact/download/ossec/ossec-hids/ossec-hids-2.8.3.tar.gz 52 | 53 | This will automatically install OSSEC through the Internet and specify a wildcard for the IP address of the agent. This is useful when installing agents on dynamic IP addresses. 54 | 55 | ## Regular Linux Installation 56 | 57 | If you install OSSEC regularly on Linux, you can just install OSSEC normally on Linux. Be sure to specify the right server IP address of where your OSSEC server is at and the IP address of where auto_server.py is running (the server enroller). 58 | 59 | ./auto_ossec.bin 60 | 61 | For the Python version, use: 62 | 63 | pip3 install -r requirements.txt 64 | 65 | This will install python-crypto (for AES support) and pexpect. 66 | 67 | Then: 68 | 69 | python auto_ossec.py 70 | 71 | ## Install on Windows 72 | 73 | For Windows, install OSSEC normally - since it is an MSI you should install this silently. Once OSSEC is installed, run: 74 | 75 | auto_ossec.exe 76 | 77 | This will automatically update your OSSEC config file with the server IP address and do the magic needed to pair them. You can also use a 0.0.0.0/0 (wildcard): 78 | 79 | auto_ossec.exe 0.0.0.0/0 80 | 81 | This will be useful if your system changes IP addresses frequently (dynamic DNS) 82 | 83 | ## Compile on Windows (auto_ossec.py) 84 | 85 | If you want to compile your own auto_ossec.py (instead of the auto_ossec.exe provided), follow the steps below on Windows 86 | 87 | 1. Download http://aka.ms/vcpython2 (Microsoft Visual C++ 9.0 for Python) 88 | 2. Download and Install: https://www.microsoft.com/en-us/download/details.aspx?id=5555 89 | 3. Download pyinstaller.org (latest version) 90 | 4. Download Python and Install (python.org) 91 | 5. Open up a command prompt, type: PATH=C:\Python27 (or 2 or 3 whatever) 92 | 6. python -m easy_install pycrypto 93 | 7. Unzip pyinstaller, navigate to the directory and type python pyinstaller --onefile auto_ossec.py - this will generate a binary under auto_ossec\dist 94 | 95 | ## Supported Operating Systems 96 | 97 | Linux, OS X, Windows 98 | -------------------------------------------------------------------------------- /auto_ossec.bin: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/BinaryDefense/auto-ossec/c5f914f36bc61daafe0cfd43540a3554a08d5907/auto_ossec.bin -------------------------------------------------------------------------------- /auto_ossec.exe: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/BinaryDefense/auto-ossec/c5f914f36bc61daafe0cfd43540a3554a08d5907/auto_ossec.exe -------------------------------------------------------------------------------- /auto_ossec.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/python 2 | # 3 | # Auto-OSSEC Client 4 | # 5 | # This is the client piece to the client/server pair (ossec_server.py). Auto-OSSEC will create a protocol 6 | # and allow automatic deployment of OSSEC keys through an enterprise. One of the biggest challenges with 7 | # OSSEC is the key management pieces which auto-ossec tries to solve. When run, this will pair with the 8 | # auto_server.py which has OSSEC server installed on it and request a key and pass it through an AES 9 | # encrypted tunnel. Once the exchange completes, auto_ossec will integrate the key and rewrite the conf 10 | # file for you to incorporate the server IP address. View the README.md for usage and how to effecitvely 11 | # use auto-ossec. This also works with AlienVault pairing. 12 | # 13 | # Written by: Dave Kennedy and the Binary Defense Systems (BDS) Team 14 | # Twitter: @HackingDave, @Binary_Defense 15 | # Website: https://www.binarydefense.com 16 | # 17 | # Usage: python auto_ossec.py - this will show you the flag options to pair. Read the README.md for more 18 | # information. 19 | # 20 | 21 | import platform 22 | import base64 23 | import socket 24 | import sys 25 | import os 26 | import subprocess 27 | import time 28 | try: import urllib.request as urllib 29 | except: import urllib 30 | import traceback 31 | 32 | # try to import python-crypto 33 | 34 | ### TO COMPILE THIS ON WINDOWS AND NOT USE THE EXE PROVIDED IN GITHUB #### 35 | 36 | ## FIRST: Download http://aka.ms/vcpython2 (Microsoft Visual C++ 9.0 for Python) 37 | ## NEXT: Download and Install: https://www.microsoft.com/en-us/download/details.aspx?id=5555 38 | ## NEXT: Download pyinstaller.org (latest version) 39 | ## NEXT: Download Python and Install (python.org) 40 | ## NEXT: Open up a command prompt, type: PATH=C:\Python27 (or 2 or 3 whatever) 41 | ## NEXT: python -m easy_install pycrypto 42 | ## NEXT: Unzip pyinstaller, navigate to the directory and type python pyinstaller --onefile auto_ossec.py - this will generate a binary under auto_ossec\dist 43 | 44 | try: 45 | from Crypto.Cipher import AES 46 | 47 | except ImportError as e: 48 | print ("[!] You need python-crypto in order for this module to work. If this is Ubuntu/Redhat - package name is python-crypto") 49 | print(e) 50 | sys.exit() 51 | 52 | # check platform specific installs 53 | installer = "" 54 | if platform.system() == "Linux": 55 | installer = "Linux" 56 | 57 | if platform.system() == "Darwin": 58 | installer = "Darwin" 59 | 60 | if platform.system() == "Windows": 61 | installer = "Windows" 62 | 63 | if installer == "": 64 | print ("[!] Unable to determine operating system. Only supports Linux and Windows. Exiting..") 65 | sys.exit() 66 | 67 | 68 | # 69 | # NEED TO DEFINE THIS AS THE OSSEC SERVER HOST THAT IS RUNNING SERVER.PY 70 | # 71 | star = "" 72 | autoinstall = "" 73 | version_name = "" 74 | try: 75 | host = sys.argv[1] 76 | try: 77 | if "0.0.0.0/0" in sys.argv[2]: star = sys.argv[2] 78 | else: autoinstall = sys.argv[2] 79 | 80 | except: pass 81 | 82 | try: 83 | if "0.0.0.0/0" in sys.argv[3]: star = sys.argv[3] 84 | else: autoinstall = sys.argv[3] 85 | 86 | except: pass 87 | 88 | except IndexError: 89 | print (""" 90 | Binary Defense Systems (BDS) OSSEC Auto Enrollment 91 | https://www.binarydefense.com 92 | Written by: The BDS Crew: Dave Kennedy, Charles Yost, Jimmy Byrd, Jason Ashton, Eric Itangata 93 | 94 | In order for this to work, you need to point auto_ossec.exe to the OSSEC server that is listening. Note that default port is 9654 but this can be changed in the source. 95 | 96 | Note that if you specify optional 0.0.0.0/0, this will place a star for the IP address in the config and allow any IP address (for dynamic IP addresses). 97 | 98 | Also note if you specify url= at the end, this is for Linux only, it will automatically download and install OSSEC for you and configure it based on the server-ip. You do not need to do a 0.0.0.0/0 before 99 | 100 | Example: auto_ossec.exe/.bin 192.168.5.5 0.0.0.0/0 url=https://bintray.com/etc/etc/ossec-hids.tar.gz 101 | Example2: auto_ossec.bin 192.168.5.5 url=https://somewebsite.com/ossec-hids-2.8.3.tar.gz 102 | Usage: auto_ossec.exe 103 | 104 | Example URL: https://bintray.com/artifact/download/ossec/ossec-hids/ossec-hids-2.8.3.tar.gz 105 | 106 | """) 107 | sys.exit() 108 | 109 | # url for OSSEC HERE 110 | if "url=" in autoinstall: 111 | url = autoinstall.replace("url=", "").replace('"', "", 2) 112 | version_name = url.split("/ossec-hids/")[1].replace(".tar.gz", "") 113 | 114 | if "path=" in autoinstall: 115 | path = autoinstall.replace("path=", "").replace('"', "", 2) 116 | if "/" in path: 117 | _, path_filename = os.path.split(path) 118 | else: 119 | path_filename = path 120 | version_name = path_filename.replace(".tar.gz", "") 121 | 122 | # download ossec 123 | def _download_ossec(url): 124 | ossec_file = urllib.urlopen(url).read() 125 | filewrite = open("/tmp/ossec.tar.gz", "wb") 126 | filewrite.write(ossec_file) 127 | filewrite.close() 128 | 129 | # MODIFY THIS IF YOU NEED TO CHANGE SOME OF THE BASE OSSEC INSTALL CONFIG OPTIONS 130 | def _pull_ossec_config(hostname): 131 | ossec_config = (r""" 132 | 133 | 134 | 135 | 136 | Application 137 | eventlog 138 | 139 | 140 | 141 | Security 142 | eventlog 143 | 144 | 145 | 146 | System 147 | eventlog 148 | 149 | 150 | 151 | 152 | 153 | ./shared/win_audit_rcl.txt 154 | ./shared/win_applications_rcl.txt 155 | ./shared/win_malware_rcl.txt 156 | 157 | 158 | 159 | 160 | 161 | 162 | 165 | 72000 166 | 167 | 170 | no 171 | 172 | 173 | 174 | %WINDIR%/win.ini 175 | %WINDIR%/system.ini 176 | C:\autoexec.bat 177 | C:\config.sys 178 | C:\boot.ini 179 | %WINDIR%/System32/CONFIG.NT 180 | %WINDIR%/System32/AUTOEXEC.NT 181 | %WINDIR%/System32/at.exe 182 | %WINDIR%/System32/attrib.exe 183 | %WINDIR%/System32/cacls.exe 184 | %WINDIR%/System32/debug.exe 185 | %WINDIR%/System32/drwatson.exe 186 | %WINDIR%/System32/drwtsn32.exe 187 | %WINDIR%/System32/edlin.exe 188 | %WINDIR%/System32/eventcreate.exe 189 | %WINDIR%/System32/eventtriggers.exe 190 | %WINDIR%/System32/ftp.exe 191 | %WINDIR%/System32/net.exe 192 | %WINDIR%/System32/net1.exe 193 | %WINDIR%/System32/netsh.exe 194 | %WINDIR%/System32/rcp.exe 195 | %WINDIR%/System32/reg.exe 196 | %WINDIR%/regedit.exe 197 | %WINDIR%/System32/regedt32.exe 198 | %WINDIR%/System32/regsvr32.exe 199 | %WINDIR%/System32/rexec.exe 200 | %WINDIR%/System32/rsh.exe 201 | %WINDIR%/System32/runas.exe 202 | %WINDIR%/System32/sc.exe 203 | %WINDIR%/System32/subst.exe 204 | %WINDIR%/System32/telnet.exe 205 | %WINDIR%/System32/tftp.exe 206 | %WINDIR%/System32/tlntsvr.exe 207 | %WINDIR%/System32/drivers/etc 208 | C:\Documents and Settings/All Users/Start Menu/Programs/Startup 209 | C:\Users/Public/All Users/Microsoft/Windows/Start Menu/Startup 210 | .log$|.htm$|.jpg$|.png$|.chm$|.pnf$|.evtx$ 211 | 212 | 213 | HKEY_LOCAL_MACHINE\Software\Classes\batfile 214 | HKEY_LOCAL_MACHINE\Software\Classes\cmdfile 215 | HKEY_LOCAL_MACHINE\Software\Classes\comfile 216 | HKEY_LOCAL_MACHINE\Software\Classes\exefile 217 | HKEY_LOCAL_MACHINE\Software\Classes\piffile 218 | HKEY_LOCAL_MACHINE\Software\Classes\AllFilesystemObjects 219 | HKEY_LOCAL_MACHINE\Software\Classes\Directory 220 | HKEY_LOCAL_MACHINE\Software\Classes\Folder 221 | HKEY_LOCAL_MACHINE\Software\Classes\Protocols 222 | HKEY_LOCAL_MACHINE\Software\Policies 223 | HKEY_LOCAL_MACHINE\Security 224 | HKEY_LOCAL_MACHINE\Software\Microsoft\Internet Explorer 225 | HKEY_LOCAL_MACHINE\System\CurrentControlSet\Services 226 | HKEY_LOCAL_MACHINE\System\CurrentControlSet\Control\Session Manager\KnownDLLs 227 | HKEY_LOCAL_MACHINE\System\CurrentControlSet\Control\SecurePipeServers\winreg 228 | HKEY_LOCAL_MACHINE\Software\Microsoft\Windows\CurrentVersion\Run 229 | HKEY_LOCAL_MACHINE\Software\Microsoft\Windows\CurrentVersion\RunOnce 230 | HKEY_LOCAL_MACHINE\Software\Microsoft\Windows\CurrentVersion\RunOnceEx 231 | HKEY_LOCAL_MACHINE\Software\Microsoft\Windows\CurrentVersion\URL 232 | HKEY_LOCAL_MACHINE\Software\Microsoft\Windows\CurrentVersion\Policies 233 | HKEY_LOCAL_MACHINE\Software\Microsoft\Windows NT\CurrentVersion\Windows 234 | HKEY_LOCAL_MACHINE\Software\Microsoft\Windows NT\CurrentVersion\Winlogon 235 | HKEY_LOCAL_MACHINE\Software\Microsoft\Active Setup\Installed Components 236 | 237 | 238 | 239 | HKEY_LOCAL_MACHINE\Security\Policy\Secrets 240 | HKEY_LOCAL_MACHINE\Security\SAM\Domains\Account\Users 241 | \Enum$ 242 | 243 | 244 | 245 | yes 246 | 247 | 248 | 249 | REPLACEHERE 250 | 251 | """) 252 | 253 | return ossec_config.replace("REPLACEHERE", "%s" % (host)) 254 | 255 | # install ossec once downloaded 256 | def _installossec(serverip,version_name): 257 | cwd = os.getcwd() 258 | os.chdir("/tmp/") 259 | subprocess.Popen("tar -zxvf ossec.tar.gz;rm ossec.tar.gz", shell=True).wait() 260 | 261 | ##### 262 | ##### 263 | ##### CHANGE THESE IF YOU WANT DIFFERENT CONFIG OPTIONS - read: http://ossec-docs.readthedocs.io/en/latest/manual/installation/install-source-unattended.html 264 | ##### 265 | ##### 266 | ossec_preload = (''' 267 | USER_LANGUAGE="en" 268 | USER_NO_STOP="y" 269 | USER_INSTALL_TYPE="agent" 270 | USER_DIR="/var/ossec" 271 | USER_ENABLE_ACTIVE_RESPONSE="n" 272 | USER_ENABLE_SYSCHECK="y" 273 | USER_ENABLE_ROOTCHECK="y" 274 | USER_UPDATE_RULES="y" 275 | USER_AGENT_SERVER_IP="%s" 276 | USER_ENABLE_EMAIL="n" 277 | USER_ENABLE_FIREWALL_RESPONSE="n" 278 | ''' % (serverip)) 279 | 280 | filewrite = open("/tmp/%s/etc/preloaded-vars.conf" % (version_name), "w") 281 | filewrite.write(ossec_preload) 282 | filewrite.close() 283 | subprocess.Popen("cd %s;chmod +x;./install.sh" % (version_name), shell=True).wait() 284 | subprocess.Popen("rm -rf /tmp/%s" % (version_name), shell=True).wait() 285 | 286 | # this is the auto installation process here 287 | if installer in "Linux|Darwin": 288 | if "url=" in autoinstall: 289 | print("[*] Automatically installing OSSEC on Linux for you with version: " + (version_name)) 290 | _download_ossec(url) 291 | _installossec(host,version_name) 292 | 293 | if "path=" in autoinstall: 294 | print("[*] Automatically installing OSSEC on Linux for you with version: " + (version_name)) 295 | from shutil import copyfile 296 | copyfile(path, '/tmp/ossec.tar.gz') 297 | _installossec(host,version_name) 298 | 299 | 300 | def aescall(secret, data, format): 301 | # padding and block size 302 | PADDING = '{' 303 | BLOCK_SIZE = 32 304 | # one-liner to sufficiently pad the text to be encrypted 305 | pad = lambda s: s + (BLOCK_SIZE - len(s) % BLOCK_SIZE) * PADDING 306 | 307 | # random value here to randomize builds 308 | a = 50 * 5 309 | 310 | # one-liners to encrypt/encode and decrypt/decode a string 311 | encryptaes = lambda c, s: base64.b64encode(c.encrypt(pad(s))) 312 | decryptaes = lambda c, e: str(c.decrypt(base64.b64decode(e)), 'UTF-8').rstrip(PADDING) 313 | 314 | decryptaes_py2 = lambda c, e: c.decrypt(base64.b64decode(e)).rstrip(PADDING) 315 | 316 | cipher = AES.new(secret) 317 | 318 | if format == "encrypt": 319 | aes = encryptaes(cipher, data) 320 | return aes 321 | 322 | if format == "decrypt": 323 | try: aes = decryptaes(cipher, data) 324 | except TypeError: aes = decryptaes_py2(cipher, data) 325 | return str(aes) 326 | 327 | # this will grab the hostname and ip address and return it 328 | def grab_info(): 329 | try: 330 | hostname = socket.gethostname() 331 | return hostname # + " " + ipaddr 332 | 333 | except Exception: 334 | sys.exit() 335 | try: 336 | # secret key - if you change this you must change on ossec_auto server - 337 | # would recommend this is the default published to git 338 | secret = "(3j+-sa!333hNA2u3h@*!~h~2&^lk 14 | 15 | [CmdletBinding()] 16 | Param( 17 | [Parameter(Mandatory=$False, Position=1)] 18 | [string]$Address = $(Read-Host "What is the IP Address where you will be running auto_server.py?") 19 | ) 20 | 21 | If ([string]::IsNullOrEmpty(${Address})) { 22 | Write-Host "FAIL: An IP Address must be specified." 23 | Exit 3 24 | } 25 | 26 | $AddressParsed = $Null 27 | $AddressIsWildcard = (0 -Eq $Address.CompareTo('0.0.0.0/0')) 28 | $AddressIsValid = ($AddressIsWildcard -Or [System.Net.IPAddress]::tryparse($Address,[ref] $AddressParsed)) 29 | If (-Not $AddressIsValid) { 30 | Write-Host "FAIL: A Valid IP Address or Wildcard (0.0.0.0/0) must be specified." 31 | Exit 2 32 | } 33 | 34 | $OutputPrefix = "auto_ossec" 35 | $OutputExtension = "msi" 36 | If ($AddressIsWildcard) { 37 | # Windows doesn't apperciate slashes in filenames. 38 | $OutputName = "${OutputPrefix}-0.0.0.0.${OutputExtension}" 39 | } Else { 40 | $OutputName = "${OutputPrefix}-${Address}.${OutputExtension}" 41 | } 42 | Write-Host "Creating MSI: ${OutputName}" 43 | If ($True) { 44 | Write-Host -NoNewLine " Locating WiX Toolset... " 45 | If (Test-Path 'C:\Program Files\WiX Toolset v3.10\bin') { 46 | $WiX_BinRoot = 'C:\Program Files\WiX Toolset v3.10\bin' 47 | } ElseIf (Test-Path 'C:\Program Files (x86)\WiX Toolset v3.10\bin') { 48 | $WiX_BinRoot = 'C:\Program Files (x86)\WiX Toolset v3.10\bin' 49 | } Else { 50 | Write-Host "FAIL: Unable to locate WiX Toolset." 51 | Exit 1 52 | } 53 | Write-Host "located." 54 | 55 | Write-Host -NoNewLine " Compiling... " 56 | & "${WiX_BinRoot}\candle.exe" -dServerAddress="${Address}" .\auto_ossec.wxs | Out-Null 57 | Write-Host "compiled." 58 | 59 | Write-Host -NoNewLine " Linking... " 60 | & "${WiX_BinRoot}\light.exe" -spdb -out "${OutputName}" auto_ossec.wixobj | Out-Null 61 | Write-Host "linked." 62 | 63 | Write-Host -NoNewLine " Cleaning up... " 64 | Remove-Item auto_ossec.wixobj | Out-Null 65 | Write-Host "cleaned up." 66 | } 67 | Write-Host "created." 68 | -------------------------------------------------------------------------------- /wxs/auto_ossec.wxs: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 16 | 17 | 25 | 26 | 27 | 28 | 29 | 30 | 35 | 36 | 37 | 44 | 52 | 53 | 54 | 55 | 56 | 57 | 58 | 59 | 67 | 68 | 69 | 70 | 71 | 72 | 73 | 74 | 75 | 76 | 77 | 78 | 86 | 87 | 88 | 89 | 90 | 91 | 92 | 93 | 94 | 95 | --------------------------------------------------------------------------------