This is the new home of the egghelp.org community forum.
All data has been migrated (including user logins/passwords) to a new phpBB version.


For more information, see this announcement post. Click the X in the top right-corner of this box to dismiss this message.

Need help with this proxy / vpn scanner

Requests for complete scripts or modifications/fixes for scripts you didn't write. Response not guaranteed, and no thread bumping!
Post Reply
User avatar
TimeRider
Voice
Posts: 27
Joined: Tue Jul 07, 2020 3:46 pm
Contact:

Need help with this proxy / vpn scanner

Post by TimeRider »

Hi, I need help with this tcl script which was posted by CrazyCat.

Code: Select all

 package require http

namespace eval pchecker {

   # isproxyip.com api key
   variable pckey "apikey"

   # gzline message
   variable gmsg "Sorry, VPN are not allowed"

   # List of IP not checked
   variable whitelist {}

   # List of blacklisted IP
   variable blacklist {}
   
   variable pcheckerwl "scripts/pcheckerwl.txt"

   # To enable on a chan, think to do
   # .chanset #chan +scanip
   setudef flag scanip

   bind join - * ::pchecker::whois
   bind raw - 378 ::pchecker::ipcheck
   bind pub - !add ::pchecker::ipadd
   bind pub - !rem ::pchecker::iprem

   proc whois {nick uhost handle chan} {
      if {![channel get $chan scanip]} { return }
      if {[isbotnick $nick]} { return }
      putquick "WHOIS $nick"
   }

   proc ipadd {nick uhost handle chan text} {
      if {[lsearch $::pchecker::whitelist $text] == -1} {
         lappend ::pchecker::whitelist $text
      }
      ::pchecker::l2file $::pchecker::whitelist $::pchecker::pcheckerwl
   }
   
   proc iprem {nick uhost handle chan text} {
      set n [lsearch $::pchecker::whitelist $text]
      if {$n != -1} {
         set ::pchecker::whitelist [lreplace $::pchecker::whitelist $n $n]
         ::pchecker::l2file $::pchecker::whitelist $::pchecker::pcheckerwl
      }
   }
   
   proc ipcheck {frm key text} {
      set ip [lindex [split $text " "] end]
      foreach w $::pchecker::whitelist {
         if {[string match $w $text]} { return }
      }
      foreach b $::pchecker::blacklist {
         if {[string match $w $text]} {
            putquick "GLINE *@$ip +316d :$::pchecker::gmsg"
            return
         }
      }
      ::pchecker::isvpn $ip
   }

   proc json2dict {JSONtext} {
      string range [string trim [string trimleft [string map {\t {} \n {} \r {} , { } : { } \[ \{ \] \}} $JSONtext] {\uFEFF}]] 1 end-1
   }

   proc isvpn {ip} {
      ::http::config -useragent "lynx"
      set pcheck [::http::geturl http://api.isproxyip.com/v1/check.php?key=$::pchecker::pckey&ip=${ip}&format=json]
      set data [json2dict [::http::data $pcheck]]
      if {[dict get $data status] eq "success"} {
         set proxy [dict get $data proxy]
         if {$proxy == 1 } {
            lappend $::pchecker::blacklist $ip
            putquick "GLINE *@$ip +316d :$::pchecker::gmsg"
         }
      }
      ::http::cleanup $pcheck
   }

   proc l2file {olist dfile} {
      set fo [open $dfile w]
      puts $fo [join $olist "\n"]
      close $fo
   }
   
   proc f2list {dfile} {
      set fi [open $dfile r]
      set olist [split [read -nonewline $fi] "\n"]
      close $fi
      return $olist
   }
   
   set ::pchecker::whitelist [::pchecker::f2list $::pchecker::pcheckerwl]
   
} 
It throws a Tcl error [::pchecker::ipcheck]: Illegal characters in URL path

CrazyCat said it's a regexp error for InspIRCD as I use it.
I set the .set errorInfo but I don't see much info.
But I figured out the regexp for InspIRCD and would be

Code: Select all

proc ipcheck {frm key text} {
   if {[string match *!*@* $frm] || ![string match -nocase "*client connecting*" $text]} { return }
   if {![regexp -nocase { CONNECT: Client connecting on port (\d+) \(class (\S+)\): ([^!]+)!([^@]+)@(\S+) \(([0-9a-f.:]+)\) \[(.*)\]} $text -> port class nick ident host ip realname]} {
      return 0;  not a connect notice
   }
How do I keep this regexp in the tcl script at the top to fix it?
User avatar
CrazyCat
Revered One
Posts: 1214
Joined: Sun Jan 13, 2002 8:00 pm
Location: France
Contact:

Post by CrazyCat »

ok, so you try to use the raw 378 (unrealircd whoishost) to match the server notice of connexion.

You must use:

Code: Select all

bind raw - NOTICE ::pchecker::ipcheck
And I think you don't really know how to use .set errorInfo (you must type that in PL just after the error occures to have detailed informations).
And using putlog to show what you get / set in another good way to debug script.
User avatar
TimeRider
Voice
Posts: 27
Joined: Tue Jul 07, 2020 3:46 pm
Contact:

Post by TimeRider »

CrazyCat wrote:ok, so you try to use the raw 378 (unrealircd whoishost) to match the server notice of connexion.

You must use:

Code: Select all

bind raw - NOTICE ::pchecker::ipcheck
And I think you don't really know how to use .set errorInfo (you must type that in PL just after the error occures to have detailed informations).
And using putlog to show what you get / set in another good way to debug script.
CrazyCat, I did put the .set errorInfo in partyline but it didn't get so much info for the debug and yes, I don't have much idea about putlog.

I am still getting the error as I put the bind you gave me too, getting: Tcl error [::pchecker::ipcheck]: Illegal characters in URL path

However, the one script you helped me build works on InspIRCD, if you could please change the proxy scanner link from the site ip-api.com to isproxyip.com here with the API key.

Code: Select all

bind PUB -|- !antivpn check:usermodes
bind PUB -|- .antivpn check:usermodes
 
set wlcountries {"NP" "FR"}
 
proc isatleasthalfop2020X3 {nick chan} { foreach type {op halfop admin owner} { if {[is$type $nick $chan]} { return 1 } }; return 0 }
 
proc check:usermodes {nick uhost hand chan text} {
   if {![isatleasthalfop2020X3 $nick $chan]} { return 0 }
 putserv "WHOIS $::botnick"
 bind raw - 379 usermode:modes
 bind raw - 318 usermode:modes2
 return 0
}
 
proc usermode:modes {from key args } {
   set text [string trim $args "{}"]
   set text  [lindex [split $text] 6]
  if {[string match "*c*" $text]} {  putserv "mode $::botnick +s -c" ; putserv "PRIVMSG #Mods :[black],15 Anti-VPN is now Disabled [end]" }
  if {![string match "*c*" $text]} {  putserv "mode $::botnick +s +c" ; putserv "PRIVMSG #Mods :[black],07 Anti-VPN is now Enabled [end]" }
}
 
 
proc usermode:modes2 {from key args } {
 unbind raw - 379 usermode:modes
 unbind raw - 318 usermode:modes2 
}
 
 
bind raw - NOTICE ipcheck
 
package require http
 
proc ipcheck {frm key text} {
   if {[string match *!*@* $frm] || ![string match -nocase "*client connecting*" $text]} { return }
   if {![regexp -nocase { CONNECT: Client connecting on port (\d+) \(class (\S+)\): ([^!]+)!([^@]+)@(\S+) \(([0-9a-f.:]+)\) \[(.*)\]} $text -> port class nick ident host ip realname]} {
      return 0;  not a connect notice
   }
   set data [getipdatas $ip]
   if {[dict get $data status] eq "success"} {
      if {[lsearch -nocase $::wlcountries [dict get $data coutryCode]]>=0} { return }
      logip $data
   }
}
proc json2dict {JSONtext} {
   string range [string trim [string trimleft [string map {\t {} \n {} \r {} , { } : { } \[ \{ \] \}} $JSONtext] {\uFEFF}]] 1 end-1
}
proc getipdatas { ip } {
   ::http::config -useragent "lynx"
   set ipq [http::geturl http://ip-api.com/json/$ip?fields=status,proxy,query,countryCode&lang=fr]
   set data [json2dict [http::data $ipq]]
   ::http::cleanup $ipq
   return $data
}
proc logip { data } {
   set ip [dict get $data query]
   if { [dict get $data proxy] eq "true"} {
      putserv "GLINE *@$ip 365d :Please connect through your regular connection as VPN/proxy are not allowed in our network. Contact admin@chatsansar.com for any errors."
      putlog "$ip is a proxy"
      putserv "privmsg #Services :$ip is a proxy"
   }
}
User avatar
CrazyCat
Revered One
Posts: 1214
Joined: Sun Jan 13, 2002 8:00 pm
Location: France
Contact:

Post by CrazyCat »

No I won't.
There are several examples on the forum, I'm trying to help (an teach) here, I won't do scripts for persons who don't even try to script by themselve.
User avatar
TimeRider
Voice
Posts: 27
Joined: Tue Jul 07, 2020 3:46 pm
Contact:

Post by TimeRider »

CrazyCat wrote:No I won't.
There are several examples on the forum, I'm trying to help (an teach) here, I won't do scripts for persons who don't even try to script by themselve.
Hello CrazyCat, okay here is what I tried, It used to work for InspIRCD but it does not seem to use the API and scan the IP now. I don't see any errors and it does not work anymore. I don't know what the bug is.

Code: Select all

 
package require http
package require json

namespace eval pchecker {

   # proxycheck.io api key
   variable pckey "api-key"
   
   # min score to ban
   variable score 10
   
   # gzline message
   variable gmsg "Sorry, VPN are not allowed."
   
   # List of IP not checked
   # they are regexp style
   variable whitelist {"192\.168\.0\.1" "10\.0\.0\.*"}
   
   # List of blacklisted IP
   # regexp too :)
   variable blacklist {}
   
   bind raw - NOTICE ::pchecker::ipcheck
   
   proc ipcheck {frm key text} {
      if {[string match *!*@* $frm] || ![string match -nocase "*client connecting*" $text]} { return }
      if {![regexp -nocase { CONNECT: Client connecting on port (\d+) \(class (\S+)\): ([^!]+)!([^@]+)@(\S+) \(([0-9a-f.:]+)\) \[(.*)\]} $text -> port class nick ident host ip realname]} { return 0 }
      if {[lsearch -regexp $::pchecker::whitelist $ip] ne -1} { return }
      if {[lsearch -regexp $::pchecker::blacklist $ip] ne -1} {
         putquick "GLINE *@$ip 30d :$::pchecker::gmsg"
         return
      }
      ::pchecker::isvpn $ip
   }
   
   proc json2dict {JSONtext} {
      string range [string trim [string trimleft [string map {\t {} \n {} \r {} , { } : { } \[ \{ \] \}} $JSONtext] {\uFEFF}]] 1 end-1
   }
   
   proc isvpn {ip} {
      ::http::config -useragent "lynx"
      set pcheck [::http::geturl http://proxycheck.io/v2/${ip}?key=$::pchecker::pckey&vpn=1&risk=1]
      set data [json2dict [::http::data $pcheck]]
      if {[dict get $data status] == "ok"} {
         set proxy [dict get [dict get $data $ip] proxy]
         set risk [dict get [dict get $data $ip] risk]
         if {[expr $risk - $::pchecker::score] >= 0 } {
            lappend $::pchecker::blacklist [string map {\. \\\.} $ip]
            putquick "GLINE *@$ip 30d :$::pchecker::gmsg"
         }
      }
      ::http::cleanup $pcheck
   }
   
}

putlog "\002ProxyCheck.io Script\002 is loaded"
If you could please shed some light on it?
Post Reply