Closed Bug 260140 Opened 20 years ago Closed 17 years ago

multiple window.print() in timeouts crashes.

Categories

(Core :: Printing: Output, defect)

x86
Windows 98
defect
Not set
critical

Tracking

()

RESOLVED WORKSFORME

People

(Reporter: dveditz, Unassigned)

References

Details

(Keywords: crash, Whiteboard: [sg:nse])

Attachments

(1 file)

From BlackIceX (at) libero (dot) it: I wrote this mail for the Mozilla Security Bug Bounty Program. I discovered a bug that can be used to execute arbitrary code on a machine with a buffer overflow. It also causes a crash of the browser. These are the results: ####################################################### FIREFOX ha provocato un errore di pagina non valida nel modulo <sconosciuto> in 0000:e9140424. Registri: EAX=00000000 CS=018f EIP=e9140424 EFLGS=00010206 EBX=00000000 SS=0197 ESP=00c8f050 EBP=00c8f124 ECX=0097b8b8 DS=0197 ESI=01d006f0 FS=1b8f EDX=00606f36 ES=0197 EDI=80004004 GS=0000 Byte all'indirizzo CS:EIP: Immagine dello stack: 0067a2e8 00000000 00677a44 00000000 6035cfc8 01d006f0 00675d42 80004004 00000001 02137704 01d006f0 00000000 60340de0 00db5964 00000000 00c8f0d0 ####################################################### I'm using Mozilla FireFox 0.93 on Windows 98 Second Edition. Internet Explorer shows the same problem: a buffer overflow with execution of arbitrary code, system resources go down and also a crash of the machine. This is the HTML that causes the problem: ####################### cut here ###################### <html> <head> <title>Proof of concept</title> </head> <body> <script>setTimeout("window.print()", (8 * 500))</script> <script>setTimeout("window.print()", (8 * 500))</script> <script>setTimeout("window.print()", (8 * 500))</script> <script>setTimeout("window.print()", (8 * 500))</script> <script>setTimeout("window.print()", (8 * 500))</script> <script>setTimeout("window.print()", (8 * 500))</script> <script>setTimeout("window.print()", (8 * 500))</script> <script>setTimeout("window.print()", (8 * 500))</script> <script>setTimeout("window.print()", (8 * 500))</script> <script>setTimeout("window.print()", (8 * 500))</script> <script>setTimeout("window.print()", (8 * 500))</script> <script>setTimeout("window.print()", (8 * 500))</script> <script>setTimeout("window.print()", (8 * 500))</script> <script>setTimeout("window.print()", (8 * 500))</script> <script>setTimeout("window.print()", (8 * 500))</script> <script>setTimeout("window.print()", (8 * 500))</script> <script>setTimeout("window.print()", (8 * 500))</script> <script>setTimeout("window.print()", (8 * 500))</script> <script>setTimeout("window.print()", (8 * 500))</script> <script>setTimeout("window.print()", (8 * 500))</script> <script>setTimeout("window.print()", (8 * 500))</script> <script>setTimeout("window.print()", (8 * 500))</script> <script>setTimeout("window.print()", (8 * 500))</script> <script>setTimeout("window.print()", (8 * 500))</script> <script>setTimeout("window.print()", (8 * 500))</script> <script>setTimeout("window.print()", (8 * 500))</script> <script>setTimeout("window.print()", (8 * 500))</script> <script>setTimeout("window.print()", (8 * 500))</script> <script>setTimeout("window.print()", (8 * 500))</script> <script>setTimeout("window.print()", (8 * 500))</script> <script>setTimeout("window.print()", (8 * 500))</script> <script>setTimeout("window.print()", (8 * 500))</script> <script>setTimeout("window.print()", (8 * 500))</script> <script>setTimeout("window.print()", (8 * 500))</script> <script>setTimeout("window.print()", (8 * 500))</script> <script>setTimeout("window.print()", (8 * 500))</script> <script>setTimeout("window.print()", (8 * 500))</script> <script>setTimeout("window.print()", (8 * 500))</script> <script>setTimeout("window.print()", (8 * 500))</script> <script>setTimeout("window.print()", (8 * 500))</script> <script>setTimeout("window.print()", (8 * 500))</script> <script>setTimeout("window.print()", (8 * 500))</script> <script>setTimeout("window.print()", (8 * 500))</script> <script>setTimeout("window.print()", (8 * 500))</script> <script>setTimeout("window.print()", (8 * 500))</script> </body> </html> ####################### cut here ###################### Explanation: <script>setTimeout("window.print()", (8 * 500))</script> causes the opening of the Print Form. If you press the "Cancel" button for more than two times, the browser causes a buffer overflow and so this can permit the execution of arbitrary code from an attacker. For contacts: Sabino Amoroso
Attached file testcase from bug (deleted) —
Assignee: general → dveditz
Status: UNCONFIRMED → ASSIGNED
Stack trace of access violation in debugger: nsCOMPtr<nsITimer>::get() line 693 + 3 bytes nsCOMPtr<nsITimer>::operator nsDerivedSafe<nsITimer> *() line 706 nsPagePrintTimer::Stop() line 144 + 11 bytes nsPrintEngine::CleanupOnFailure(unsigned int 2147500036, int 1) line 2196 nsPrintEngine::Print(nsPrintEngine * const 0x036e78a8, nsIPrintSettings * 0x03abe2b8, nsIWebProgressListener * 0x00000000) line 787 + 14 bytes DocumentViewerImpl::Print(DocumentViewerImpl * const 0x03b38d98, nsIPrintSettings * 0x03abe2b8, nsIWebProgressListener * 0x00000000) line 3171 + 26 bytes GlobalWindowImpl::Print(GlobalWindowImpl * const 0x03694b04) line 2640 XPTC_InvokeByIndex(nsISupports * 0x03694b04, unsigned int 73, unsigned int 0, nsXPTCVariant * 0x0012e9e8) line 102 XPCWrappedNative::CallMethod(XPCCallContext & {...}, XPCWrappedNative::CallMode CALL_METHOD) line 2028 + 43 bytes XPC_WN_CallMethod(JSContext * 0x03694dc0, JSObject * 0x0358ee40, unsigned int 0, long * 0x03ba8f78, long * 0x0012ecb8) line 1287 + 14 bytes js_Invoke(JSContext * 0x03694dc0, unsigned int 0, unsigned int 0) line 941 + 23 bytes js_Interpret(JSContext * 0x03694dc0, long * 0x0012f53c) line 2972 + 15 bytes js_Execute(JSContext * 0x03694dc0, JSObject * 0x0358ee40, JSScript * 0x036eff68, JSStackFrame * 0x00000000, unsigned int 0, long * 0x0012f654) line 1159 + 13 bytes JS_EvaluateUCScriptForPrincipals(JSContext * 0x03694dc0, JSObject * 0x0358ee40, JSPrincipals * 0x03ba8e3c, const unsigned short * 0x037c5420, unsigned int 14, const char * 0x03a8df48, unsigned int 7, long * 0x0012f654) line 3649 + 25 bytes nsJSContext::EvaluateString(const nsAString & {...}, void * 0x0358ee40, nsIPrincipal * 0x03ba8e38, const char * 0x03a8df48, unsigned int 7, const char * 0x100b9430, nsAString & {...}, int * 0x0012f77c) line 946 + 67 bytes GlobalWindowImpl::RunTimeout(nsTimeoutImpl * 0x037c55b8) line 5066 + 113 bytes GlobalWindowImpl::TimerCallback(nsITimer * 0x037c56a8, void * 0x037c55b8) line 5445 nsTimerImpl::Fire() line 382 + 17 bytes nsTimerManager::FireNextIdleTimer(nsTimerManager * const 0x02e5cb48) line 616 nsAppShell::Run(nsAppShell * const 0x028b0e10) line 142 nsAppShellService::Run(nsAppShellService * const 0x028b0d50) line 495 xre_main(int 1, char * * 0x003d6fe8, const nsXREAppData * 0x0041d01c kAppData) line 1918 + 35 bytes main(int 1, char * * 0x003d6fe8) line 58 + 18 bytes mainCRTStartup() line 338 + 17 bytes KERNEL32! 77e814c7() Registers: EAX = DDDDDDF9 EBX = 7FFDF000 ECX = DDDDDDF9 EDX = 036E78A8 ESI = 003D6FE8 EDI = 00150000 EIP = 011CCE4A ESP = 0012E548 EBP = 0012E54C EFL = 00000296 In an optimized build the stack was much shorter, I'll post as soon as the talkback submission is processed.
After the second or third cancel it looks like the nsPrintEngine object has already been freed when we try to clean up. Looks more like a race condition than a buffer overflow.
Component: Browser-General → Printing
Some tests of the same bug with the last version of Internet Explorer: ******************* IEXPLORE ha provocato un errore di stack nel modulo KERNEL32.DLL in 0187:bff7429f. Registri: EAX=817ab650 CS=0187 EIP=bff7429f EFLGS=00000287 EBX=00000018 SS=018f ESP=02179f88 EBP=00008f80 ECX=c1587cc0 DS=018f ESI=00000000 FS=18bf EDX=00025384 ES=018f EDI=0217ffff GS=0000 Byte all'indirizzo CS:EIP: eb 95 8b 54 24 04 50 e8 04 00 00 00 58 c2 04 00 Immagine dello stack: bff71547 02179ff4 00006062 0217a03e 02179fec 7029c334 00000001 00000854 00000000 0000001c 00000000 fff19a29 02179ff4 00006062 0217a03e 00000000 Memoria insufficiente per eseguire il programma. Uscire da uno o più programmi e riprovare. (insufficient memory to execute the program. Exit from one or more programs and retry.) Risorse di sitema: 5% (system resources 5%) ******************** IEXPLORE ha provocato un errore di pagina non valida nel modulo <sconosciuto> in 0000:a00000c9. Registri: EAX=02b79620 CS=0187 EIP=a00000c9 EFLGS=00010202 EBX=0418e05c SS=018f ESP=0418dff4 EBP=0418e008 ECX=02b79620 DS=018f ESI=00008080 FS=4cd7 EDX=00443cf8 ES=018f EDI=0418e010 GS=4d1f Byte all'indirizzo CS:EIP: Immagine dello stack: bfb957e9 0000078c 00000082 00000000 00000000 0418e028 bff7363b 0000078c 00000082 00000000 00000000 805a4d67 0000018f 0418e03c bff94407 4d1f8080 Stack overflow at line: 1 (this message in a small window) ********************* IEXPLORE ha provocato un errore di pagina non valida nel modulo OLE32.DLL in 0187:7ff29917. Registri: EAX=00550018 CS=0187 EIP=7ff29917 EFLGS=00010206 EBX=02c47e00 SS=018f ESP=00550000 EBP=00550000 ECX=005500a2 DS=018f ESI=8002801d FS=1b4f EDX=02c47e00 ES=018f EDI=00550170 GS=430f Byte all'indirizzo CS:EIP: 53 56 33 db 57 8b 7d 08 3b fb 74 2f 6a 10 57 ff Immagine dello stack: 00550068 7713b61e 02c47e00 00550018 00000027 8002801d 00000000 00000000 00000000 00000000 00000000 00550060 bff7d0b0 81c53404 005500da 005500da ********************** IEXPLORE ha provocato un errore di pagina non valida nel modulo <sconosciuto> in 0000:82940366. Registri: EAX=00000000 CS=0187 EIP=82940366 EFLGS=00010202 EBX=000002a8 SS=018f ESP=0054fe2c EBP=00000000 ECX=00000003 DS=018f ESI=00550900 FS=1b4f EDX=80000000 ES=018f EDI=02f6fe04 GS=0000 Byte all'indirizzo CS:EIP: 53 8b 9c 24 0c 04 00 00 55 8b ac 24 0c 04 00 00 Immagine dello stack: *********************** IEXPLORE ha provocato un errore di pagina non valida nel modulo RPCRT4.DLL in 0187:7fbd09d1. Registri: EAX=00550010 CS=0187 EIP=7fbd09d1 EFLGS=00010246 EBX=7ff31f40 SS=018f ESP=0054fedc EBP=0055015c ECX=7ff31f08 DS=018f ESI=00428dc0 FS=297f EDX=00000000 ES=018f EDI=03077e58 GS=628f Byte all'indirizzo CS:EIP: 53 89 45 b4 56 8b 5d 10 66 8b 4b 10 57 89 65 e8 Immagine dello stack: ************************
Ben Bucksch wrote: Trying to prove a buffer overflow in Mozilla using a stack of MSIE doesn't make much sense. Even if so, you didn't answer Daniel's question: Where is *your* data executed? Not all overflows (or crashs) are exploitable per se. Esp. in this case, where you merely open the Print dialog many times, I don't see where your program would come in (and get executed). ################### From http://www.mozilla.org/security/bug-bounty-faq.html: I don't have the time or desire to work with you further in investigating and fixing the bug; can I still get a bug bounty reward? Yes. Again, we're rewarding you for finding a bug, not trying to buy your cooperation. However we do invite you to work together with us, and we hope that you'll accept that offer in the spirit in which it was intended. ################### I discovered a critical bug in Mozilla browser, my cooperation is that to find a critical bug and to report it directly to Mozilla developers. Now you know that in the browser there is a security problem, so you have to fix it. I don't want to make public the exploit, or to give informations about it. I reported the critical bug and I hope it will be fixed as soon as possible. If you are interested in the exploit, try to look at the EBP and the ESP (Base and Stack Pointer), the return address saved in the stack and the CALL instruction. I want to have information about the reward of the Mozilla Bug Bounty Program. Sabino Amoroso
I don't think this is a buffer overrun. I stumbled across this when I did the following: javascript: for (prop in someObject) { print(prop); } Was thinking of something else and errantly put print in there. Hitting cancel a couple of times blew it up. So I don't think it has anything to do with the number of timers setup as suggested by the original example. I suspect this is just an object lifetime issue for Mozilla, couldn't say the same for IE, though ;-) Timeless had a talkback crash TB3560267G Basically the same type of stack.
Even simpler javascript: print(window); print(window); will crash. Looks like a race condition on the window shutdown and the print window starting up in the second print.
The last version of the browser is bugged. ;)
We do not believe this is exploitable, clearing confidential flag to increase visibility and improve chances of a fix.
Assignee: dveditz → printing
Group: security
Status: ASSIGNED → NEW
QA Contact: general
Summary: multiple window.print() in timeouts crashes. Exploitable? → multiple window.print() in timeouts crashes.
Whiteboard: [sg:nse]
See also bug 218623, which does have an exploitable-looking stack trace.
on Mozilla/5.0 (Windows; U; Windows NT 5.2; en-US; rv:1.9a9pre) Gecko/2007092305 Minefield/3.0a9pre ID:2007092305 i get a lot of printing dialogs and i was needed to shutdown Firefox via the process manager.
Flags: blocking1.9?
Flags: blocking1.9? → blocking1.9+
I can't reproduce the crash on trunk, just lots of print dialogs (~50), but that is what the testcase should do. Isn't that what you Tomcat see too? Can anyway reproduce the crash or has this become WFM.
er, s/way/one/
Status: NEW → RESOLVED
Closed: 17 years ago
Resolution: --- → WORKSFORME
You need to log in before you can comment on or make changes to this bug.

Attachment

General

Created:
Updated:
Size: