Downloading File
Filename: Safe Eval v1.2
; safe_eval 1.2 ; myndzi 8/7/2008 ; parse a mirc command line recursively, de-obfuscating without evaluating identifiers ; essentially, i escape everything and then selectively unescape some things, evaluate ; and repeat as necessary. ; ; remember to use a *single* slash when calling it as an alias: ; ; /safe_eval <dangerous code> ; ; or else call it like so: ; ; //safe_eval $cb ; ; after copying the code to your clipboard, otherwise you might get caught by pipes ; in the command. ; ; if you don't understand regular expressions yet, you may want to check out a different ; snippet. ;dangerous commands: ;scid - double eval / obfuscated pipe ;scon - double eval / obfuscated pipe ;timer - double eval / obfuscated pipe ;flash - double eval / obfuscated pipe [only if mirc is inactive] ;| - command separator (multiple commands to mirc) ;} - pipe synonym ;$findfile - evaluation -> command ;$finddir - evaluation -> command ;$() $eval() - evaluation control ;$evalnext() - evaluation control ;[ ] - evaluation control ;$decode - obfuscation ;$base - obfuscation ;$chr - obfuscation ;$left - obfuscation ;$mid - obfuscation ;$right - obfuscation ;$+() $+ - obfuscation ;$crlf $cr $lf - newline (multiple commands to server) ;#$identifier - will still evaluate ;=$identifier - this too alias safe_eval { var %t = $1-, %i, %j, %re, %pre, %suf ; thanks to Remy for finding the vulnerability this fixes var %re = /^(.*?)([^()]*(\((?2)\)|\([^()]*\))[^()]*)(.*)$/ noop $regex(se, %t, %re) %t = $regml(se, 2) ; remove leading /'s if ($regex(%t, /^\/+(.*)/)) %t = $regml(1) ; for easier regexing -> force spaces before and after the real data %t = . %t . ; keep evaluating obfuscation identifiers until there are none left in the string %re = /\$(decode|chr|base|left|mid|right|regsubex|remove|replace|\+)/i while ($regex(%t, %re)) && ($safe_eval2(%t) != %t) %t = $ifmatch ; remove the surrounding periods %t = $mid(%t, 2, -1) %t = $regml(se, 1) $+ %t $+ $regml(se, 4) ; done if ($isid) return %t else echo -a * /safe_eval: %t } ; this processes brackets in the correct order alias -l safe_eval2 { var %re = /(\x20\[(\x20[^\[]*?\x20)\]\x20)/, %t = $1 ; evaluate brackets while ($regex(se2, %t, %re)) { %t = $put(%t, $mid($safe_eval3(. $regml(se2, 2) .), 2, -1), $regml(se2, 1).pos, $len($regml(se2, 1))) } ; evaluate the entire line once %t = $safe_eval3(%t) return %t } ; this part does the actual evaluating alias -l safe_eval3 { var %t = $1, %%, %re ; put spaces after left parenthesis and commas %re = /(\(|,)/g %% = $regsub(%t, %re, $+(\1, $chr(32)), %t) ; put spaces before right parenthesis and commas %re = /(\)|,)/g %% = $regsub(%t, %re, $+($chr(32), \1), %t) ; escape all identifiers ; thanks Saturn vvvv %re = /(?<=\x20)(?:\x23|\x3D)?\$(?!\x20)/g %% = $regsub(%t, %re, \$!, %t) ; escape all variables %re = /(?<=\x20)(\x25)([^\x20]+)/g %% = $regsub(%t, %re, \1 \$+ \2, %t) ; escape all flow symbols %re = /(\{|\||\})/g %% = $regsub(%t, %re, \\\1, %t) ; unescape selected identifiers %re = /(?<=\x20)(\$)!((?:decode|base|chr|left|mid|right|regsubex|remove|replace|\+)\(|(?:\+|null)(?=\x20))/gi %% = $regsub(%t, %re, \1\2, %t) ; evaluate one step %t = $eval(%t, 2) ; unescape all flow symbols %re = /\\(\{|\||\})/g %% = $regsub(%t, %re, \1, %t) ; convert crs and lfs embedded in encoded data into mircscript %t = $replace(%t, $crlf, $+($chr(32), $!crlf, $chr(32)), $cr, $+($chr(32), $!cr, $chr(32)), $lf, $+($chr(32), $!lf, $chr(32))) return %t } ;$put(var, text, start, len) ;replaces len chars of var from start with text alias -l put { var %t = $1, %r return $+( $left(%t, $calc($3 - 1)), $2, $mid(%t, $calc($3 + $4)) ) }