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)) )
}


