Sign in to follow this  
Followers 0
Morthawt

Script to convert CIDR networks or IP ranges to REGEX ban rules for use in TeamSpeak etc

2 posts in this topic

#1 ·  Posted (edited)

(Will work for any application that checks only an IP address, as in a whole string that is nothing but just an IP, since this regex is condensed and does not check to make sure it is a valid IP address it just checks what should already be a valid IP given to it's checking system)

The script creates files in the directory where it is run from. You can put CIDR networks (one per line) like 192.168.0.0/16 in the CIDR file and process them to IP ranges, which you can then alter the ranges to manually combine running ranges and then process the ranges file. Or you can just work in ranges to begin with like 192.168.0.0 - 192.168.255.255

This is especially useful when banning VPN company IP blocks. You can put the person's IP address into this site: http://bgp.he.net/ and google the company and if it is a dedicated server/VPS server/Hosting/VPN then take a list of all those CIDR networks owned by the company (you can type the company in the search box but don't add any punctuation so just keep it to a word or two to help you find the company's IP blocks) and process them into creating regular expression ban entries in the REGEX file like this: ^176.227.(2(1[45])).[0-9]+$

#Region ;**** Directives created by AutoIt3Wrapper_GUI ****
#AutoIt3Wrapper_Outfile=CIDR network to REGEX ban entry for TS.exe
#AutoIt3Wrapper_Compression=4
#AutoIt3Wrapper_UseUpx=y
#AutoIt3Wrapper_Run_Au3Stripper=y
#EndRegion ;**** Directives created by AutoIt3Wrapper_GUI ****
#include <String.au3>
#include <Array.au3>

#cs

    First paste CIDR networks in the "CIDRList.txt" text file and process them, then manually combine (if needed/desired) the IP ranges in the "IPRangesList.txt" file
    Then process the IP ranges.

    Alternatively you can create just a list of IP ranges in the "IPRangesList.txt" file and process them directly.

#ce

Global $RangesList = @ScriptDir & '\IPRangesList.txt', $REGEXList = @ScriptDir & '\REGEXList.txt'
If Not FileExists(@ScriptDir & '\CIDRList.txt') Then FileWrite(@ScriptDir & '\CIDRList.txt', '')
If Not FileExists($RangesList) Then FileWrite($RangesList, '')

$user = MsgBox(4, 'Morthawt''s IP Block Regexizer', 'Process ranges? (Press no to process raw CIDR)')
If $user = 7 Then
    If FileRead(@ScriptDir & '\CIDRList.txt') = '' Then
        MsgBox(0, 'Error', 'You need to add some CIDR networks in the file, one per line.')
        Exit
    EndIf
    CIDRListToRanges()
    MsgBox(0, 'Morthawt''s IP Block Regexizer', 'Operation has bee completed... Please modify the range file (if needed) and process the ranges by running this program again.')
    Exit
EndIf

If FileRead($RangesList) = '' Then
    MsgBox(0, 'Error', 'You need to add some IP ranges eg 192.168.0.1 - 192.168.0.128 in the file, one per line.')
    Exit
EndIf

If FileExists($RangesList) Then
    $RangeArray = FileReadToArray($RangesList)
Else
    MsgBox(0, 'Error', 'Ranges file (IPRangesList.txt) does not exist. Process CIDR rules first or add ranges to the range file.')
    Exit
EndIf
If FileExists($REGEXList) Then FileDelete($REGEXList)

For $a In $RangeArray
    $split = StringSplit($a, ' - ', 3)
    FileWriteLine($REGEXList, CIDRtoRegex($split[0], $split[1]))
Next
MsgBox(0, 'Morthawt''s IP Block Regexizer', 'Operation has bee completed... Please check the regex file for your completed list of IP block rules.')

Func CIDRListToRanges()

    $CIDRlist = FileReadToArray(@ScriptDir & '\CIDRList.txt')

    _ArraySort($CIDRlist)

    Local $bestnetwork, $networkip, $trashlist[0]

    For $a = 0 To UBound($CIDRlist) - 1
        $netip = StringMid($CIDRlist[$a], 1, StringInStr($CIDRlist[$a], '/') - 1)
        $net = StringMid($CIDRlist[$a], StringInStr($CIDRlist[$a], '/') + 1, StringInStr($CIDRlist[$a], '/'))
        If $netip = $networkip Then
            ReDim $trashlist[UBound($trashlist) + 1]
            $trashlist[UBound($trashlist) - 1] = $a
        EndIf
        $networkip = $netip
    Next

    If UBound($trashlist) Then
        Local $trashing
        For $a = 0 To UBound($trashlist) - 1
            $trashing &= $trashlist[$a] & (($a = (UBound($trashlist) - 1)) ? ('') : (';'))
        Next
        _ArrayDelete($CIDRlist, $trashing)
    EndIf


    Local $ranges[UBound($CIDRlist)]
    $count = 0
    For $a In $CIDRlist
        $temp = CIDRtoRegex($a, 1)
        $ranges[$count] = $temp[0] & ' - ' & $temp[1]
        $count += 1
    Next

    _ArraySort($ranges)
    Local $allranges
    Local $FullStartRange[UBound($CIDRlist)][4], $FullEndRange[UBound($CIDRlist)][4]
    For $a = 0 To UBound($ranges) - 1
        ConsoleWrite($ranges[$a] & @CRLF)
        $allranges &= $ranges[$a] & (($a = UBound($ranges) - 1) ? ('') : (@CRLF))
        $currentFull = StringSplit($ranges[$a], ' - ', 3)
        $currentStart = StringSplit($currentFull[0], '.', 3)
        $currentEnd = StringSplit($currentFull[1], '.', 3)

        For $z = 0 To 3
            $FullStartRange[$a][$z] = $currentStart[$z]
            $FullEndRange[$a][$z] = $currentEnd[$z]
        Next
    Next

    Local $FinalList[0]

    FileDelete($RangesList)
    FileWrite($RangesList, $allranges)

EndFunc   ;==>CIDRListToRanges

Func CIDRtoRegex($_CIDRNet, $rangeonly = False)
    $slashPos = StringInStr($_CIDRNet, '/')
    Local $LastIP[4]

    $networkNumber = StringMid($_CIDRNet, $slashPos + 1, StringLen($_CIDRNet) - $slashPos)
    $networkRemainder = 32 - $networkNumber
    $FirstIP = StringSplit($_CIDRNet, '.', 3)
    If $slashPos Then
        $FirstIP[3] = StringReplace($FirstIP[3], '/' & $networkNumber, '')

        $binpos = 128
        $bintotal = 0
        $currentOctet = 0
        $deductamount = 0
        For $a = 1 To 32
            If $a > $networkNumber Then
                $deductamount += $binpos
            EndIf

            $binpos /= 2
            If IsInt($a / 8) Then
                $LastIP[$currentOctet] = $FirstIP[$currentOctet] + $deductamount
                If $LastIP[$currentOctet] > 255 Then
                    Return SetError(1, 0, 0)
                EndIf
                $deductamount = 0
                $binpos = 128
                $currentOctet += 1
            EndIf
        Next
    Else ; If the first param is not a CIDR network, then the first and second params will be a start and end IP address.
        $LastIP = StringSplit($rangeonly, '.', 3)
    EndIf

    If $rangeonly And $slashPos > 0 Then
        Local $range[2]
        For $go = 0 To 3
            $range[0] &= $FirstIP[$go] & (($go = 3) ? ('') : ('.'))
            $range[1] &= $LastIP[$go] & (($go = 3) ? ('') : ('.'))
        Next

        Return $range
    EndIf

    $finalregex = '^'
    For $go = 0 To 3
        If $FirstIP[$go] <> $LastIP[$go] Then
            $finalregex &= IPRegex($FirstIP[$go], $LastIP[$go])
        Else
            $finalregex &= $FirstIP[$go]
        EndIf
        $finalregex &= (($go = 3) ? ('$') : ('\.'))
    Next
    Return $finalregex
EndFunc   ;==>CIDRtoRegex

Func IPRegex($start, $ender)
    If $start = 0 And $ender = 255 Then Return '[0-9]+'

    Local $realender = $ender, $realstart = $start

    Local $regex, $previousprocessing = 0
    Local $currentnumreached = 0, $was1digit = 0, $was2digits = 0
    If StringLen($start) = 1 Then
        $regex &= '(' ; Now 1 digit
        $regex &= '[' & $start & ((StringLen($ender) = 1) ? ('-' & $ender & ']') : ('-9]'))
        If StringLen($ender) = 1 Then
            $regex &= ')'
            Return RegexCleanup($regex)
        EndIf
        $previousprocessing = 1
        $was1digit = 1
        If StringLen($start) = 1 Then $start = 10

    EndIf

    If StringLen($start) = 2 Or $previousprocessing = 1 Then
        $regex &= (($previousprocessing = 1) ? ('|') : ('(')) ; Now 2 digits
        If $was1digit Then $previousprocessing = 0

        If StringLen($ender) > 2 And $previousprocessing = 1 Or $ender >= 99 And StringMid($start, 2, 1) = 0 Then
            $regex &= '[' & (($previousprocessing = 1) ? (1) : (StringMid($start, 1, 1))) & '-9][0-9]'
        Else
            If StringLen($ender) = 2 And StringMid($ender, 1, 1) > StringMid($start, 1, 1) And $previousprocessing = 0 Then

                $regex &= StringMid($start, 1, 1) & '[' & StringMid($start, 2, 1) & '-9]|'
                If StringMid($ender, 1, 1) - StringMid($start, 1, 1) > 1 Then
                    $regex &= '[' & StringMid($start, 1, 1) + 1 & '-' & StringMid($ender, 1, 1) - 1 & ']' & '[0-9]|' & StringMid($ender, 1, 1) & '[0-' & StringMid($ender, 2, 1) & ']'
                Else
                    $regex &= '[' & StringMid($start, 1, 1) + 1 & '-' & StringMid($ender, 1, 1) & ']' & '[0-' & StringMid($ender, 2, 1) & ']'
                EndIf

            ElseIf StringLen($ender) > 2 Then

                $regex &= StringMid($start, 1, 1) & '[' & StringMid($start, 2, 1) & '-9]|'
                If StringMid($start, 1, 1) < 9 Then
                    $regex &= '[' & StringMid($start, 1, 1) + 1 & '-' & 9 & ']' & '[0-9]' ; I had to restrict this to initial digits under 9 to prevent problems
                EndIf

            Else
                $regex &= StringMid($start, 1, 1) & '[' & StringMid($start, 2, 1) & '-' & StringMid($ender, 2, 1) & ']'
            EndIf

        EndIf

        If StringLen($ender) = 2 Then
            $regex &= ')'
            Return RegexCleanup($regex)
        EndIf
        $previousprocessing = 1
        $was2digits = 1
    EndIf

    If StringLen($start) = 3 Or $previousprocessing = 1 Then
        $regex &= (($previousprocessing = 1) ? ('|') : ('(')) ; Now 3 digits
        If $previousprocessing Then $start = 100 ; If we are building up from a smaller than 3 digit number but going up to 3 digits, we start at the 1st 3 digit number

        If StringMid($start, 1, 1) = StringMid($ender, 1, 1) Then ; If the 1st digits are the same
            $regex &= StringMid($start, 1, 1) & '('

            If StringMid($start, 2, 1) = StringMid($ender, 2, 1) Then ; If the second digits are the same

                $regex &= StringMid($start, 2, 1) & '[' & StringMid($start, 3, 1) & '-' & StringMid($ender, 3, 1) & '])'

            Else ; If the second digits are not the same
                If StringMid($start, 3, 1) = 0 Then ; If the starter third digit is a 0
                    $regex &= '[' & StringMid($start, 2, 1) & '-' & (StringMid($ender, 2, 1) - 1) & '][0-9]|'
                    $regex &= '' & StringMid($ender, 2, 1) & '[0-' & StringMid($ender, 3, 1) & '])'

                Else ; The third starter digit is not 0
                    $regex &= StringMid($start, 2, 1) & '[' & StringMid($start, 3, 1) & '-9]'
                    If StringMid($ender, 2, 1) - StringMid($start, 2, 1) > 1 Then ; There is a second digit gap of more than 1 digit
                        $regex &= '|[' & StringMid($start, 2, 1) + 1 & '-' & StringMid($ender, 2, 1) - 1 & ']' & '[0-9]'
                        $regex &= '|' & StringMid($ender, 2, 1) & '[0-' & StringMid($ender, 3, 1) & '])'
                    Else
                        $regex &= '|[' & StringMid($start, 2, 1) + 1 & '-' & StringMid($ender, 2, 1) & ']' & '[0-' & StringMid($ender, 3, 1) & '])'
                    EndIf

                EndIf

            EndIf

            $regex &= ')'
        Else ; The first digits are not the same

            If StringMid($start, 2, 1) = 0 And StringMid($start, 3, 1) = 0 Then ; If 100 start just run through all up to 199 ready for starting at 200
                $regex &= StringMid($start, 1, 1) & '[0-9]' & '[0-9]|'

            Else

                Local $realender = $ender, $realstart = $start
                $ender = 199
                $regex &= StringMid($start, 1, 1) & '('

                If StringMid($start, 2, 1) = StringMid($ender, 2, 1) Then ; If the second digits are the same

                    $regex &= StringMid($start, 2, 1) & '[' & StringMid($start, 3, 1) & '-' & StringMid($ender, 3, 1) & '])'

                Else ; If the second digits are not the same
                    If StringMid($start, 3, 1) = 0 Then ; If the starter third digit is a 0
                        $regex &= '[' & StringMid($start, 2, 1) & '-' & (StringMid($ender, 2, 1) - 1) & '][0-9]|'
                        $regex &= '' & StringMid($ender, 2, 1) & '[0-' & StringMid($ender, 3, 1) & '])'

                    Else ; The third starter digit is not 0
                        $regex &= StringMid($start, 2, 1) & '[' & StringMid($start, 3, 1) & '-9]'
                        If StringMid($ender, 2, 1) - StringMid($start, 2, 1) > 1 Then ; There is a second digit gap of more than 1 digit
                            $regex &= '|[' & StringMid($start, 2, 1) + 1 & '-' & StringMid($ender, 2, 1) - 1 & ']' & '[0-9]'
                            $regex &= '|' & StringMid($ender, 2, 1) & '[0-' & StringMid($ender, 3, 1) & '])|'
                        Else
                            $regex &= '|[' & StringMid($start, 2, 1) + 1 & '-' & StringMid($ender, 2, 1) & ']' & '[0-' & StringMid($ender, 3, 1) & '])|'
                        EndIf

                    EndIf

                EndIf

            EndIf
            $ender = $realender
            $start = 200
            $regex &= '|' & StringMid($ender, 1, 1) & '('

            If StringMid($start, 2, 1) = StringMid($ender, 2, 1) Then ; If the second digits are the same

                $regex &= StringMid($start, 2, 1) & '[' & StringMid($start, 3, 1) & '-' & StringMid($ender, 3, 1) & '])'

            Else ; If the second digits are not the same
                If StringMid($start, 3, 1) = 0 Then ; If the starter third digit is a 0
                    $regex &= '[' & StringMid($start, 2, 1) & '-' & (StringMid($ender, 2, 1) - 1) & '][0-9]|'
                    $regex &= '' & StringMid($ender, 2, 1) & '[0-' & StringMid($ender, 3, 1) & '])'

                Else ; The third starter digit is not 0
                    $regex &= StringMid($start, 2, 1) & '[' & StringMid($start, 3, 1) & '-9]'
                    If StringMid($ender, 2, 1) - StringMid($start, 2, 1) > 1 Then ; There is a second digit gap of more than 1 digit
                        $regex &= '|[' & StringMid($start, 2, 1) + 1 & '-' & StringMid($ender, 2, 1) - 1 & ']' & '[0-9]'
                        $regex &= '|' & StringMid($ender, 2, 1) & '[0-' & StringMid($ender, 3, 1) & '])'
                    Else
                        $regex &= '|[' & StringMid($start, 2, 1) + 1 & '-' & StringMid($ender, 2, 1) & ']' & '[0-' & StringMid($ender, 3, 1) & '])'
                    EndIf

                EndIf

            EndIf

            $regex &= ')'

        EndIf

        Return RegexCleanup($regex)

    EndIf

EndFunc   ;==>IPRegex

Func RegexCleanup($_input, $no = 0)
    If $no Then Return $_input

    For $a = 0 To 9
        $_input = StringReplace($_input, '[' & $a & '-' & $a & ']', $a)
        If $a < 9 Then
            $_input = StringReplace($_input, '[' & $a & '-' & $a + 1 & ']', '[' & $a & $a + 1 & ']')
        EndIf
    Next

    For $a = 1 To 10
        $_input = StringReplace($_input, '||', '|')
    Next

    Local $temp_input = $_input

    $sections = StringRegExp($temp_input, '\(.*\)', 4)
    For $a In $sections
        ConsoleWrite($a & @CRLF)
    Next

    $_input = $temp_input

    Return $_input
EndFunc   ;==>RegexCleanup

Updated to fix a problem. All regex appears to be valid.

Edited by Morthawt

Share this post


Link to post
Share on other sites



Sadly this isn't working... I put in my CIDRList of 10.121.88.0/16 and it fails with 

"Z:\AutoIT\Test\RangeToRegex.au3" (84) : ==> Subscript used on non-accessible variable.:
$ranges[$count] = $temp[0] & ' - ' & $temp[1]
$ranges[$count] = $temp^ ERROR

 

Share this post


Link to post
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!


Register a new account

Sign in

Already have an account? Sign in here.


Sign In Now
Sign in to follow this  
Followers 0