Reverse Engineering Obfuscated JavaScript

LiveOverflow · Intermediate ·🌐 Frontend Engineering ·8y ago

Key Takeaways

The video demonstrates reverse engineering obfuscated JavaScript used for creating pop-unders in Chrome, utilizing various techniques such as proxy objects, notification permission requests, and data URIs to bypass popup blockers.

Full Transcript

pop unders are like popups just a lot more annoying the goal is to open a popup in the background pop under the current window so that you won't see it until you want to close your browser and you don't know which site created it creating a pop under used to be fairly easy because there are actually functions called blur and focus which exists solely to focus an element with Focus or prevent focus with blur so you would blur the popup window you open and focus the current main window and that technique still works in for example Edge but Chrome will always try to focus the new window thus preventing pop unders but I did some research into this and found the demo site that actually is able to create a pop under which obviously caught my attention this guy even sells a license for JavaScript library that can create pop unders in any browser and AD networks pay good money for it so I wanted to know how this script manages to do a pop under on Chrome 59 as other libraries can't do that so I started to analyze [Music] it let's check out the demo for the pop under I clicked the link and yes indeed here is a pop under let's try to figure out how it's done obviously one of the first ideas is to look into the sources the solution should be right there but shortly after you open the developer tools a debugger statement triggers a breakpoint and you can't just continue as this is constantly called on a timer it's an anti-debugging attempt you can disable break points entirely but then that also prevents you from setting break points in the sources themselves and you may would want that for debugging so that's annoying but first let's look generally at the scripts the main page loads a loader. JS file which loads three other scripts scripts JS licensed demo JS and demo JS let's have a quick look at each of those demo JS seems to be the script a potential client would use it configures the better JS pop module and allows developers to react on before and after popup creation otherwise not much else is there the real functionality is probably in better JS pop itself license demo could be interesting in how licensing works but when you look at the code it's heavily obfuscated even if you pretty print it it's completely rubbish code and script.js which is presumably the main script looks similar there are some easy functions and nonsensical functions which you can clean up like these here just return the argument or perform simple operation but even if you clean SE that up it still looks terrible and it's long so how do we figure out what it does I will go now over the path I took but it would be awesome to hear from you how you would have approached this as I'm sure there are many different techniques to go about this and I don't know if I know them all so the first thing I did was mirror the whole site locally I didn't really test it but I assumed if they put so much effort into licensing for the mains and have a demo here that these scripts will check the domain they are loaded from and won't function properly if loaded from somewhere else so you can't simply use the demo on your site that's why I not only downloaded each file and place it in the same path but also modified Etc hosts to point the domain to Local Host this way when I visit the site again it attempts to load it from 1271 which means we can start a simple PHP or python server on Port 80 and load the side in the browser and make a small modification to the local file and remove the embedded video and image and clean up the side a bit now you can easily see that it loads this version instead of the live web version so the reason why I want a local mirror is that I have all the freedom of modifying and playing around with it but where do I really start now in theory in the end the JavaScript code will have to call the main API functions functions like Windows do open and window at timeout or like create element or a pen child but we can't easily search for this in the script as these calls are heavily offis skated but we can try to hook or proxy or intercept those calls this way we can learn more about what's happening I'm using a proxy object for this it's like a web proxy that sits between you and your destination a proxy object in JavaScript sits between the caller and the actual function Target the proxy object is used to define custom behavior for fundamental operations for example property lookup assignments eneration or function invocation so now I'm defining a Handler function that can be used to intercept and log all the function calls then I can overwrite functions I want with a proed version and because we want to learn more about popups I wanted to intercept window open which is the function to open a popup oh and I write this code before the loader loads the other scripts so it can overwrite any functions it would use I disable the break points and reload the page but when I click the link I don't see any call to open which is super weird but in the console I noticed two deprecation warnings and one of them is interesting deprecation using the notification API from an iframe is deprecated and will be removed in Chrome ver 61 around September 2017 you should consider requesting permissions from the top level frame or opening a new window instead wait that's so weird first why the heck does it call the notification API what does it have to do with the popup and what's up with the I frame I feel like this must be a key component some kind of trick to achieve a pop under hm as there are no if frames in the HTML code that see if we can hook the dynamic creation of those iframes it probably uses the create element a pen child and remove child functions to achieve that so let's proxy these as a pen child could be called on any HTML element I can use the Prototype of the general element object to overwrite the function for all elements if we reload the page now we can already see that it works with some diff but let's see what happens when we click the link all look at that it creates an iframe unfortunately we can't inspect what the iframe is for because later the I frame is removed with removed child around this time I started to get really curious about the stuff that pops up briefly so weird so I decided to record it in order to slow it down and see what happens and when you go step by step you first notice a pop-up window being open in the bottom right corner so the user might not really notice it then the notification permission request pops up and around the same time an alert box is shown with chrome PDF viewer what the [ __ ] and then they disappear again what the heck is going on at this point I realized what seems to be the basic idea behind all of this to create a pop under you somehow want to get the main window back in focus and it looks like with this weird combination of notification requests and alert box you can get back the focus of the main window knowing this let's move on with some debugging the removed child prevents us from inspecting the iframe as it's gone by that point so instead of calling remove child let's overwrite it with a custom function we could use the proxy object and not call the original function but I just wanted to show another method how you can change the behavior of something a proxy object is cleaner but this works also well so now instead of removing an element we log the element it tried to remove and let's try it again and it looks like that remove child was necessary to remove the notification permission request and the alert box because they stay now here but we can also look now into the iframe HM it basically just defines a function mkp which calls window.open that's the trick used why we couldn't proxy window open because here they will dynamically create an iframe and use its clean new default window open function Instead This Is Not Meant to throw off analysis it's actually a simple pop-up blocker bypass some basic blockers simply override window open like I attempted to do and with this trick you can get back the original window open function so it's just a bypass for simple popup blockers you can also check that window mkp which I guess stands for make popup exists here in our Global scope pointing at window open so clever but let's move on because a few steps later there is a second if frame created and if we look into that one we see that it executes a script that requests notification permissions so that's why we get the dication warning here not sure yet why notification permissions are requested but now we know when and where they do it at this point I felt I understand what was going on more and more and I started playing around with this knowled myself doing Simple tests I first opened a new window and then caused a notification permission request and as it turns out with the notification request Chrome focuses the main window again but once the user clicks the Box away the focus goes back to the other window and two things to observe here first we get Focus off the main window which is exactly what we want question is just how to keep it second problem how do you remove the notification request again automatically both shouldn't be really possible but we know that remove child with an if frame could be the solution so we can try that first we create the iframe and append it to the Dom then we execute the JavaScript in the iframe and after that use a timeout to wait 3 seconds and remove it again and testing that shows that it works but what's up with the PDF message we see when you think about it it kind of looks like an alert box so let's play a bit more with our test and remove the iframe with the notification for now and instead call alert and we get the same behavior the main window gains Focus because of the alert but as soon as the user clicks it away focus is restored to the popup unfortunately a simple I frame won't help here to remove the alert box because alert blocks and pauses everything but anyway we can try to combine these two now like we saw in the slowed down video and so we trigger the notification permission request then we wait a bit with the set time out and trigger an alert and then we wait a bit longer and remove the notification again let's run it and when we now close the alert by hand and the notification request is automatically removed surprisingly the popup window stays in the background the main window is C kept in Focus so last question is how do they now remove the alert box automatically it looks like the alert is triggered from the PDF viewer it said please wait so I assume maybe it happens if you load a huge PDF or so I did some tests but it didn't work out I also couldn't find useful information about the waiting dialogue online so I decided to take a step back and analyze the demo further and besides the ey frames there is another element created an embedded object that defines a data URI of the media type PDF and basic C4 en coding so we can decode that and find the raw PDF file which contains a Javascript app alert please wait ah so it also calls alert just from a PDF and that's the trick because that alert box can be closed again by removing the embedded PDF from the Dom to not steal anybody else's code we can also create our own minimal PDF that cause alert and convert it to Bas 64 now everything falls into place we first open a new window then dynamically embed a PDF with an app alert and create an iframe that requests notification permissions and after a short moment we then remove the iframe and the embedded PDF again and that's it if it doesn't work then maybe you have the timing wrong it's not 100% reliable but wow we created a pop under wasn't this interesting hopefully Chrome will fix this so I don't have to experience these annoying pop unders [Music] [Applause] [Music] anymore

Original Description

In this video we figure out how to do a PopUnder in Chrome version 59, by using a trick. Hopefully Chrome fixes this, because I resent this kind of advertisement. PoC: https://liveoverflow.com/poc/popunder.html -=[ ❤️ Support ]=- → per Video: https://www.patreon.com/join/liveoverflow → per Month: https://www.youtube.com/channel/UClcE-kVhqyiHCcjYwcpfj9w/join -=[ 🐕 Social ]=- → Twitter: https://twitter.com/LiveOverflow/ → Website: https://liveoverflow.com/ → Subreddit: https://www.reddit.com/r/LiveOverflow/ → Facebook: https://www.facebook.com/LiveOverflow/ -=[ 📄 P.S. ]=- All links with "*" are affiliate links. LiveOverflow / Security Flag GmbH is part of the Amazon Affiliate Partner Programm. #ReverseEngineering
Watch on YouTube ↗ (saves to browser)
Sign in to unlock AI tutor explanation · ⚡30

Playlist

Uploads from LiveOverflow · LiveOverflow · 0 of 60

← Previous Next →
1 LiveOverflow - Trailer
LiveOverflow - Trailer
LiveOverflow
2 Introduction to Linux - Installation and the Terminal - bin 0x01
Introduction to Linux - Installation and the Terminal - bin 0x01
LiveOverflow
3 Writing a simple Program in C
Writing a simple Program in C
LiveOverflow
4 Writing a simple Program in Python - bin 0x03
Writing a simple Program in Python - bin 0x03
LiveOverflow
5 Live Hacking - Twitch Recording overthewire.org - Vortex 0x01-0x03 (3h)
Live Hacking - Twitch Recording overthewire.org - Vortex 0x01-0x03 (3h)
LiveOverflow
6 Reversing and Cracking first simple Program - bin 0x05
Reversing and Cracking first simple Program - bin 0x05
LiveOverflow
7 Abusing the exception handler to leak flag - 32C3CTF readme (pwnable 200)
Abusing the exception handler to leak flag - 32C3CTF readme (pwnable 200)
LiveOverflow
8 ROP with a very small stack - 32C3CTF teufel (pwnable 200)
ROP with a very small stack - 32C3CTF teufel (pwnable 200)
LiveOverflow
9 Uncrackable Programs? Key validation with Algorithm and creating a Keygen - Part 1/2 - bin 0x07
Uncrackable Programs? Key validation with Algorithm and creating a Keygen - Part 1/2 - bin 0x07
LiveOverflow
10 Uncrackable Program? Finding a Parser Differential in loading ELF - Part 2/2 - bin 0x08
Uncrackable Program? Finding a Parser Differential in loading ELF - Part 2/2 - bin 0x08
LiveOverflow
11 Syscalls, Kernel vs. User Mode and Linux Kernel Source Code - bin 0x09
Syscalls, Kernel vs. User Mode and Linux Kernel Source Code - bin 0x09
LiveOverflow
12 Smashing the Stack for Fun and Profit - setuid, ssh and exploit.education - bin 0x0B
Smashing the Stack for Fun and Profit - setuid, ssh and exploit.education - bin 0x0B
LiveOverflow
13 Live Hacking - EFF-CTF 2016 - Level 0-4 (Enigma Conference)
Live Hacking - EFF-CTF 2016 - Level 0-4 (Enigma Conference)
LiveOverflow
14 First Stack Buffer Overflow to modify Variable - bin 0x0C
First Stack Buffer Overflow to modify Variable - bin 0x0C
LiveOverflow
15 First Exploit! Buffer Overflow with Shellcode - bin 0x0E
First Exploit! Buffer Overflow with Shellcode - bin 0x0E
LiveOverflow
16 Buffer Overflows can Redirect Program Execution - bin 0x0D
Buffer Overflows can Redirect Program Execution - bin 0x0D
LiveOverflow
17 Doing ret2libc with a Buffer Overflow because of restricted return pointer - bin 0x0F
Doing ret2libc with a Buffer Overflow because of restricted return pointer - bin 0x0F
LiveOverflow
18 Reverse engineering C programs (64bit vs 32bit) - bin 0x10
Reverse engineering C programs (64bit vs 32bit) - bin 0x10
LiveOverflow
19 pwnable.kr - Levels: fd, collision, bof, flag
pwnable.kr - Levels: fd, collision, bof, flag
LiveOverflow
20 Reverse Engineering and identifying Bugs - BKPCTF cookbook (pwn 6) part 1
Reverse Engineering and identifying Bugs - BKPCTF cookbook (pwn 6) part 1
LiveOverflow
21 Leaking Heap and Libc address - BKPCTF cookbook (pwn 6) part 2
Leaking Heap and Libc address - BKPCTF cookbook (pwn 6) part 2
LiveOverflow
22 Arbitrary write with House of Force (heap exploit) - BKPCTF cookbook (pwn 6) part 3
Arbitrary write with House of Force (heap exploit) - BKPCTF cookbook (pwn 6) part 3
LiveOverflow
23 Live Hacking - Internetwache CTF 2016 - web50, web60, web80
Live Hacking - Internetwache CTF 2016 - web50, web60, web80
LiveOverflow
24 Live Hacking - Internetwache CTF 2016 - crypto60, crypto70, crypto90
Live Hacking - Internetwache CTF 2016 - crypto60, crypto70, crypto90
LiveOverflow
25 A simple Format String exploit example - bin 0x11
A simple Format String exploit example - bin 0x11
LiveOverflow
26 NEW VIDEOS ARE COMING - loopback 0x00
NEW VIDEOS ARE COMING - loopback 0x00
LiveOverflow
27 HTML + CSS + JavaScript introduction - web 0x00
HTML + CSS + JavaScript introduction - web 0x00
LiveOverflow
28 The HTTP Protocol: GET /test.html - web 0x01
The HTTP Protocol: GET /test.html - web 0x01
LiveOverflow
29 Building Poor Man's Logic Analyzer with an Arduino - Reverse Engineering A/C Remote part 1
Building Poor Man's Logic Analyzer with an Arduino - Reverse Engineering A/C Remote part 1
LiveOverflow
30 What is PHP and why is XSS so common there? - web 0x02
What is PHP and why is XSS so common there? - web 0x02
LiveOverflow
31 Introducing the AngularJS Javascript Framework - XSS with AngularJS 0x00
Introducing the AngularJS Javascript Framework - XSS with AngularJS 0x00
LiveOverflow
32 Sandbox Bypass in Version 1.0.8 - XSS with AngularJS 0x1
Sandbox Bypass in Version 1.0.8 - XSS with AngularJS 0x1
LiveOverflow
33 Capturing & Analyzing Packets with Saleae Logic Pro 8 - Reverse Engineering A/C Remote part 2
Capturing & Analyzing Packets with Saleae Logic Pro 8 - Reverse Engineering A/C Remote part 2
LiveOverflow
34 XSS Contexts and some Chrome XSS Auditor tricks - web 0x03
XSS Contexts and some Chrome XSS Auditor tricks - web 0x03
LiveOverflow
35 Previous Bypass is now fixed in version 1.4.7 - XSS with AngularJS 0x2
Previous Bypass is now fixed in version 1.4.7 - XSS with AngularJS 0x2
LiveOverflow
36 New Sandbox Bypass in 1.4.7 - XSS with AngularJS 0x3
New Sandbox Bypass in 1.4.7 - XSS with AngularJS 0x3
LiveOverflow
37 The Heap: what does malloc() do? - bin 0x14
The Heap: what does malloc() do? - bin 0x14
LiveOverflow
38 The Heap: How to exploit a Heap Overflow - bin 0x15
The Heap: How to exploit a Heap Overflow - bin 0x15
LiveOverflow
39 Reverse Engineering with Binary Ninja and gdb a key checking algorithm - TUMCTF 2016 Zwiebel part 1
Reverse Engineering with Binary Ninja and gdb a key checking algorithm - TUMCTF 2016 Zwiebel part 1
LiveOverflow
40 Scripting radare2 with python for dynamic analysis - TUMCTF 2016 Zwiebel part 2
Scripting radare2 with python for dynamic analysis - TUMCTF 2016 Zwiebel part 2
LiveOverflow
41 Live Hacking - Internetwache CTF 2016 - exp50, exp70, exp80
Live Hacking - Internetwache CTF 2016 - exp50, exp70, exp80
LiveOverflow
42 Sandbox bypass for the latest AngularJS version 1.5.8 - XSS with AngularJS 0x4
Sandbox bypass for the latest AngularJS version 1.5.8 - XSS with AngularJS 0x4
LiveOverflow
43 Channel is growing and Riscure hardware CTF starting soon - loopback 0x01
Channel is growing and Riscure hardware CTF starting soon - loopback 0x01
LiveOverflow
44 Explaining Dirty COW local root exploit - CVE-2016-5195
Explaining Dirty COW local root exploit - CVE-2016-5195
LiveOverflow
45 What is CTF? An introduction to security Capture The Flag competitions
What is CTF? An introduction to security Capture The Flag competitions
LiveOverflow
46 The Heap: How do use-after-free exploits work? - bin 0x16
The Heap: How do use-after-free exploits work? - bin 0x16
LiveOverflow
47 The Browser is a very Confused Deputy - web 0x05
The Browser is a very Confused Deputy - web 0x05
LiveOverflow
48 The Heap: Once upon a free() - bin 0x17
The Heap: Once upon a free() - bin 0x17
LiveOverflow
49 Simple reversing challenge and gaming the system - BruCON CTF part 1
Simple reversing challenge and gaming the system - BruCON CTF part 1
LiveOverflow
50 int0x80 from DualCore lent me his lockpicking set and I'm a horse - BruCON CTF part 2
int0x80 from DualCore lent me his lockpicking set and I'm a horse - BruCON CTF part 2
LiveOverflow
51 The Heap: dlmalloc unlink() exploit - bin 0x18
The Heap: dlmalloc unlink() exploit - bin 0x18
LiveOverflow
52 MD5 Length Extension and Blind SQL Injection - BruCON CTF part 3
MD5 Length Extension and Blind SQL Injection - BruCON CTF part 3
LiveOverflow
53 TCP Protocol introduction - bin 0x1A
TCP Protocol introduction - bin 0x1A
LiveOverflow
54 Socket programming in python and Integer Overflow - bin 0x1B
Socket programming in python and Integer Overflow - bin 0x1B
LiveOverflow
55 Linux signals and core dumps - bin 0x1C
Linux signals and core dumps - bin 0x1C
LiveOverflow
56 [Live] Remote oldschool dlmalloc Heap exploit - bin 0x1F
[Live] Remote oldschool dlmalloc Heap exploit - bin 0x1F
LiveOverflow
57 Riscure Embedded Hardware CTF setup and introduction - rhme2 Soldering
Riscure Embedded Hardware CTF setup and introduction - rhme2 Soldering
LiveOverflow
58 Rooting a CTF server to get all the flags with Dirty COW - CVE-2016-5195
Rooting a CTF server to get all the flags with Dirty COW - CVE-2016-5195
LiveOverflow
59 How to learn hacking? ft. Rubber Ducky
How to learn hacking? ft. Rubber Ducky
LiveOverflow
60 Format String to dump binary and gain RCE - 33c3ctf ESPR (pwn 150)
Format String to dump binary and gain RCE - 33c3ctf ESPR (pwn 150)
LiveOverflow

This video teaches how to reverse engineer obfuscated JavaScript code used for creating pop-unders in Chrome, and how to identify vulnerabilities in browser security. The lesson covers various techniques used to bypass popup blockers, including proxy objects, notification permission requests, and data URIs.

Key Takeaways
  1. Mirror the whole site locally
  2. Modify Etc hosts to point the domain to Local Host
  3. Start a simple PHP or Python server on Port 80
  4. Load the site in the browser and make small modifications to the local file
  5. Define a handler function to intercept and log function calls
  6. Hook the create element and remove child functions to track dynamic iframe creation
  7. Overwrite the remove child function to log the element being removed instead of removing it
💡 The video highlights the importance of understanding obfuscated JavaScript code and identifying vulnerabilities in browser security to prevent malicious activities such as pop-unders.

Related AI Lessons

Had my Frontend Developer interview with Capgemini (Application Developer) today, and I wanted to…
Prepare for a frontend developer interview with Capgemini by reviewing JavaScript fundamentals and practicing common interview questions
Medium · JavaScript
10 Frontend Developer Tools to Boost Productivity in 2026
Boost frontend productivity with 10 essential tools for modern web app development
Medium · Programming
10 Frontend Developer Tools to Boost Productivity in 2026
Boost frontend productivity with top 10 developer tools in 2026
Medium · JavaScript
The US Frontend Engineer Market in 2026: A Data-Driven Reality Check (and the Bias That Stops Us Seeing It)
US frontend engineer hiring demand peaked in 2022 and remains flat-depressed in 2026, contrary to common assumptions
Dev.to AI
Up next
The masks we wear | Zora Krstić | TEDxLuxembourgCity
TEDx Talks
Watch →