# exploit.tcl - string check prog. by Peter Postma <mail@ask.me>
#
# This function checks the whole string for false chars.
# We need to do this when we're passing arguments from IRC to the TCL
# exec command. Without checking which characters in the string are,
# we create a huge security hole which can be easily exploited.
# I'll explain this later.
#
# I found this hole in some of my own code. I audited all my code and also
# the well known Qstat script, there are now alot versions available of
# Qstat4eggdrop and all which I've seen are exploitable.
#
# Exploit: redirect the output with the '>' char to a file which can be
# called whatever you want. It's possible to create and overwrite files.
# Like Qstat4eggdrop's "!hl" command can be exploited with:
# !hl >test : it will create the file "test" with the output from !hl
#
# This is how it looks like in IRC:
# 10:41 <Me> !hl localhost
# 10:41 <Bot> Some server (localhost) 0/16 de_dust 10ms cstrike
# 10:41 <Me> !hl >server.qstat
# 10:41 <Me> !hl localhost
# (no response)
# 10:42 <Me> !hl localhost
# (still nothing offcourse)
#
# The bot's config file got screwed up, cause of my 'corrupt' command.
# Now that anyone is able to overwrite your config file, they also can
# overwrite your documents, public html files or anything else.
#
# The redirection in the other direction "<" (read), seems to be safe, also
# the pipe "|" character, but it always better to NOT allow these characters
# to prevent possible errors/bugs or maybe exploits.
#
# Solution: Use the string_check function below. This function checks the
# whole string for false characters, the chars which will be
# checked are: > < |
#
# The function returns a 1 when no false chars are found and a 0 when a false
# character is found. Use the function like this:
# if {![string_check $text]} { return 0 }
#
# Tip: Be very carefull when calling the TCL exec command and passing
# arguments to it directly from IRC. Without checking the argument will
# create a easily exploited security hole. I've found this multiple times
# in my scripts. A good idea is to use the function below which checks if
# the string contains bad characters.
#
# The check could be better, suggestions are always welcome.
#
# That's it! (i am sorry for my poor english)
#
proc string_check {text} {
for {set i 0} {$i < [string length $text]} {incr i} {
if {[string index $text $i] == ">" || [string index $text $i] == "<" ||
[string index $text $i] == "|"} { return 0 }
}
return 1
}
Stripping off invalid characters is not very user friendly, since the scripts will return unexpected results without notification. Therefore i wrote a small, fast function that can be used to check for invalid characters and trigger messages to the user involved:
##################################################################
# Written by Minox @ #SPooKY / iRCnet #
# #
# Please report bugs: minox@spooky.homelinux.org #
# #
# If you want to change that script, please send a copy to me... #
# #
# Read the README or get busted :P #
# #
##################################################################
#--
# EDITED: 8/16/2002 by Mapherick^ApL
# PROBLEM SUMMARY:
# Fixed exec vulnerability as pointed out by Peter Postma here:
# http://forum.egghelp.org/viewtopic.php?t=2273
# User input can cause eggdrop runtime files to be overwritten
# and/or corrupted because of an unchecked variable used with
# the 'exec' command.
#
# SOLUTION:
# Added procedure mk_inptcheck and a routine in 'shoutcast' to
# call mk_inptcheck and give a proper reply to the user. Execution
# speed should be optimal.
#
# Also fixed the repetitive copyright message because that was way
# irritating ;)
#
# Questions/Suggestions should go to <mapherick at apl-productions.org>
#--
# Here you can define the prefix (trigger). E.g !audiosearch
set cmdpre "!shoutcast"
# Define the location of the binary
set searchshoutcast "~/eggdrop/scripts/searchshoutcast"
# Set exec vulnerability checking on/off (1 = ON, 0 = OFF)
set use_mk_inptcheck 1
bind pub -|- [set cmdpre] shoutcast
proc shoutcast { nick uhost hand chan args} { global cmdpre searchshoutcast
set args [lindex $args 0]
if {([mk_inptcheck [lindex $args 0]] || [mk_inptcheck [lindex $args 1]] || [mk_inptcheck [lindex $args 2]]) && $use_mk_inptcheck} {
puthelp "notice $nick : TERMINATED: Your input contains illegal characters."
puthelp "notice $nick : Unable to process '|', '<', '>' and '&'."
puthelp "notice $nick : Please modify your searchterms and try again."
return
}
set msg [split [exec -- $searchshoutcast [lindex $args 0] [lindex $args 1] [lindex $args 2] ] "\n"]
putserv "PRIVMSG $nick :Shoutcast Server Search - Copyright by Minox @ #SPooKY / iRCnet"
putserv "PRIVMSG $nick : "
foreach line $msg {putserv "PRIVMSG $nick :$line"}
}
proc mk_inptcheck {txt} {
foreach char {">" "<" "|" "&"} {
if [string match "*$char*" $txt] {return 1}
}
return 0
}
I found another script vulnerable to this while browsing google, thanks to Avi Norowitz. Bible.tcl. I walked through the bible_brs.tcl i found on bseen/ftp.eggheads.org and i think that's the one. It looks like the script is (still) vulerable but i cannot test it from my current location. I'll patch it if it is.