# Hacking with the Browser's Web Console


## TL;DR

I'll just talk about the cool things you can do with just the web console without the target having no knowledge about what you are doing or discovering and then you can later write everything that would allow you to exploit what you'd have discovered.

## Introduction

Hi, I'm Jiab77 and known as Doctor Who in the [THC Telegram Channel](https://t.me/thcorg).

## Da web console

![image](https://cdn.hashnode.com/res/hashnode/image/upload/v1665958576123/gnSETESsh.png)

To open the console, simply hit the `[F12]` key. It should work on every platforms and every browsers. You can also use `[Ctrl + Shift + I]` to open the web console.

> Even if all modern browsers have a web console, it's implementation may vary. So depending on what you are using, you might see some differences.
>
> In this article, I've used Chromium.

## Best tabs to know

There are many tabs in the web console. The most useful ones for hacking are:

* __Elements__ - Shows the dynamic source code (includes the one generated by Javascript) and modify it locally
* __Console__ - Allows you to access to all websites and applications code but also inject some
* __Sources__ - Shows the source files of websites and applications
* __Network__ - Shows all the requests made by the websites and applications
* __Application__ - Shows all data stored by the websites and applications in the browser

> Some names are different in Firefox:
>
> * _Elements_ -> __Inspector__
> * _Sources_ -> __Debugger__
> * _Application_ -> __Storage__

### Elements

One of the simplest thing that you can do with the __Elements__ tab is to reveal the passwords hidden by the dots:

* Normal password display

![image](https://cdn.hashnode.com/res/hashnode/image/upload/v1665958577796/LTuov8kPG.png)

* Password revealed

![image](https://cdn.hashnode.com/res/hashnode/image/upload/v1665958578986/F2MvsSnz-.png)

But you can do many things as you can edit any elements loaded in your browser. In this case, I just changed the element type from `password` to __`text`__. The result is that the browser now shows the entered password in clear instead of `*******`!

![image](https://cdn.hashnode.com/res/hashnode/image/upload/v1665958579885/s2hzgMAKi.png)

To revert it as password display, simply set the element type back to `password`:

![image](https://cdn.hashnode.com/res/hashnode/image/upload/v1665958580763/xKedkUd2U.png)

### Console

To use this one, you'll have to know about Javascript programming. Without it, you'd not be able to do anything in the console tab but if you know it, then you can find some nice things that developers stores in the global `window` context.

![image](https://cdn.hashnode.com/res/hashnode/image/upload/v1665958581738/Gy66ImiId.png)

Simply type `window` then hit enter and expand the displayed object properties.

Here you can see few things that comes from the developer of the website I'm using for the screenshots, these are not part of the default `window` object content:

![image](https://cdn.hashnode.com/res/hashnode/image/upload/v1665958582926/zy_wTegAQ.png)

In the picture you can see the `__meteor_runtime_config__` object that contains some interesting things, for example some details about the Sentry tool used to diagnose issues in the code:

![image](https://cdn.hashnode.com/res/hashnode/image/upload/v1665958584475/-CRmXrM2W.png)

So yeah nothing really juicy here but try it on different websites or applications that uses the browser, you'd be surprised. I could find some application secrets stored loosely in the global context (_the `window` object_).

I said earlier that can also inject some code directly in the website, I'll show you a basic example:

![image](https://cdn.hashnode.com/res/hashnode/image/upload/v1665958585547/iXJuuKS4N.png)

And the code injected from the console tab:

```js
window.alert('THC is the best hacking group!!');
```

It's just a basic example but if the website or the application is not protected against code injection with a `CSP` (_Content Security Policy_), you can basically inject everything you want, modify any elements in the page and so on.

#### Color differences

Someone in the group asked me what was the differences between the two colors:

![image](https://cdn.hashnode.com/res/hashnode/image/upload/v1665958586570/B5kuPggDR.png)

> Example from Chromium

Long story short:

* Light blue ones - Those that you can modify / alter. (_dynamic_)
* Darker blue ones - Those that you __can't__ modify / alter. (_static_)

In detail:

* Light blue ones:

  Every global and third party code will appear that way:

  ```js
  window.thc = 'best hacking group';
  ```

  Will appear like that:

  ![image](https://cdn.hashnode.com/res/hashnode/image/upload/v1665958588413/AT2iOI-u0.png)

* Darker blue ones:

  As said in the short answer, these are static objects, methods and properties that comes with your browser whatever it can be.

  You can call them in your web projects but keep in mind that some of them are not standardized so if you're using them, your code will be specific for the targeted browser only.

As I said in the beginning, the implementation may vary. For example, this is how Firefox is showing the difference:

![image](https://cdn.hashnode.com/res/hashnode/image/upload/v1665958589617/qFtcjg29X.png)

You'll have expand `<default properties>` to see them.

### Sources

This one might sounds not really interesting but again you might be surprised by what some developers can leave in clear in their source files so don't hesitate to waste some hours digging into them, you might find some golden nuggets.

![image](https://cdn.hashnode.com/res/hashnode/image/upload/v1665958590667/MW7qk5lyH.png)

To make the code more readable, click on the `{}` button at the bottom to get this:

![image](https://cdn.hashnode.com/res/hashnode/image/upload/v1665958592356/2WcTV2_fZ.png)

So yeah, again nothing really juicy here, it's just an example. I'll try to show some stuffs later that might be more interesting, just keep reading ;)

### Network

This one is one of my favorite and I've discovered so many things with it just by observing and learning what data are exchanged on the websites and applications. This allowed me to discover and later exploit many weaknesses.

Here is a practical example from the website [speedlight.io](https://speedlight.io/my). They will give you a lifetime gold membership if you contact them with this code:

![image](https://cdn.hashnode.com/res/hashnode/image/upload/v1665958594073/XjwL2LpPj.png)

So here the secret code is: `IFOUNDSECRET` xD

> I know already that at least two persons already contacted them so it might left 8 places or less... (these two persons are me and a friend of mine)

Summary:

* Access URL: <https://speedlight.io/my>
* URL that contains the secret code: <https://widget.userpowered.io/init?uuid=[REDACTED]>

Honestly, this one was pretty easy to find but many ones will be in the `Fetch/XHR` sub tab and dynamic websites uses it a lot so finding good stuffs means analyzing a lot of requests... but you can find cool things when you get lucky. I'll show you later so keep reading ;)

### Application

This one is the one that will often contain the most sensible details about you that the website or application will store to recognize you during your future visits.

![image](https://cdn.hashnode.com/res/hashnode/image/upload/v1665958595173/DypHPgxf0.png)

Everyone knows about cookies so I won't really go in details about them but more about the other storage types that you might not know about them:

* __Local Storage__ - Persistent storage limited to 5MB per domains or more depending on the victim browser (can be [abused](https://feross.org/fill-disk/))
* __Session Storage__ - Volatile storage, it's content will disappear once you close the tab or the browser
* __IndexedDB__ - Bigger persistent storage, it works just like a classical `SQL` database with some minor differences

You might have noticed that I've changed the content of the stored data in the __Local Storage__ section. You can basically modify every data stored in your browser, reload the page and see the result.

As I said, I won't go in details about __cookies__ but the cookie stealing technique is basically just noting somewhere the cookie of someone else, get back to your home, go on the same website and change your cookie value by the one you've stolen and you will be logged as the person you've stolen the cookie.

In this case, `speedlight.io` are not using the __cookies__ to store the session tokens but __Local Storage__ instead.

## Concrete use and discoveries

If you are still there, thanks a lot for your patience.

I'll now show you some concrete examples from some discoveries I've made on my side:

### Display hidden features from the web interface of my router

Initially, I just wanted to access to my router logs because as every routers that runs on Linux, they must have logs, right?! But I searched everywhere inside that damn router and could not find anything regarding the logs and after some digging and analysis of the `JS` files of the interface, I found one that has some interesting constants:

![image](https://cdn.hashnode.com/res/hashnode/image/upload/v1665958597009/NjAWJ-WC9.png)

```js
var MENU_LVL=0;
var MENU_TITL=1;
var MENU_NAME=2;
var MENU_URL=3;
var MENU_ON=4;
var MENU_TARGET=5;
var MENU_GRP=6;
var MENU_ELM=7;
var MENU_USER=5;
var MENU_EXP=7;
var MENU_SUPER=10;
```

Then I analysed the `HTML` source of the user mode selector and found something that could linked to these constants:

![image](https://cdn.hashnode.com/res/hashnode/image/upload/v1665958597878/1t0n1W3FK.png)

The selector code is the following:

![image](https://cdn.hashnode.com/res/hashnode/image/upload/v1665958599372/x3cTuBxL6.png)

So, what do we have here?

* Standard = `MENU_USER=5`

  ![image](https://cdn.hashnode.com/res/hashnode/image/upload/v1665958600398/BEJ8_TlZG.png)

* Expert = `MENU_EXP=7`

  ![image](https://cdn.hashnode.com/res/hashnode/image/upload/v1665958601563/ymk0-Q8nH.png)

  > Interesting, no? And what if I change the value of the radio input from `7` to __`10`__ before clicking on it? Will it show something cool? Yeah, baby!

* Super User (hidden) = `MENU_SUPER=10` (_sounds logical, right?_)

  ![image](https://cdn.hashnode.com/res/hashnode/image/upload/v1665958602782/PZlJl0QJU.png)

  > Yesss, finally a __Log__ tab!!

Let's see what we can find in this __Log__ tab!

![image](https://cdn.hashnode.com/res/hashnode/image/upload/v1665958603722/ghPYjOJ2b.png)

WTF?! Are you kidding me? :(

Let's have a look at the web console to see what we got:

![image](https://cdn.hashnode.com/res/hashnode/image/upload/v1665958605030/4KenPAG3b.png)

Damn it...

> Long story short, I must configure my local network connection to be in the right `VLAN` to be able to display the hidden content... It sucks...

### Hacking web radios

What I'll show here is mostly valid for any web radios whatever they ask you to pay something each months to get it or not:

* Open up the web console
* Go to the __Network__ tab
* Filter by `pls`, `hls`, `m3u`

![image](https://cdn.hashnode.com/res/hashnode/image/upload/v1665958606064/UslPpb0Sv.png)

And enjoy the direct streaming URL that you can later play in __VLC__ for example:

* URL: <https://hydra.shoutca.st:2199/tunein/tunitup2020.pls>
* Example with __VLC__:

![image](https://cdn.hashnode.com/res/hashnode/image/upload/v1665958607620/7lJpmNdaw.png)

* Example with `ffplay`:

![image](https://cdn.hashnode.com/res/hashnode/image/upload/v1665958608776/rE9NNoD0L.png)

> The executed command was: `ffplay "http://148.251.43.149:8321/stream"`
>
> This address has been found in the logs from __VLC__.
>
> ![image](https://cdn.hashnode.com/res/hashnode/image/upload/v1665958610013/pJ6zrEooh.png)

Basically, most streaming servers based on `shoutcast` or `icecast` does not support the `HTTPS` protocol so they are using `HTTP` only most of the time...

### Steal session cookies

![image](https://cdn.hashnode.com/res/hashnode/image/upload/v1665958611175/PV1x8D2Hb.png)

If you can get your hands on the `session-token` (_or any similar names_) of someone else, just connect on the same website, replace the generated `session-token` by the one you could catch and reload the page, you'll be logged in.

Basically, if the user as not logged off, the `session-token` will be valid for a various range of days depending on the website until it gets revoked.

### Abusing adult streaming websites

This one will be probably the most interesting for you as they clearly don't give a fuck about security or they just don't know how to put it in place correctly or whatever but their weakness are quite obvious and [easy](https://github.com/DgSe95/porn-proxyfy) to [exploit](https://github.com/DgSe95/porn-dump-cli).

> The following will be related to _stripchat_ but it's also valid for every similar websites that use the `HLS` streaming format or have a `WebRTC` based service as both are often misconfigured.

#### Connected models

* Open up the web console
* Go to the __Network__ tab
* Select the `Fetch/XHR` sub tab

![image](https://cdn.hashnode.com/res/hashnode/image/upload/v1665958612423/D1w84K98P.png)

* Change the URL from:
  * <https://stripchat.com/api/front/v2/models?limit=24&topLimit=61&favoritesLimit=24&primaryTag=girls&device=desktop&uniq=ingyts30bj1qc6da>
* To:
  * <https://stripchat.com/api/front/v2/models?limit=10000>

Now enjoy, you have the details about all the connected models at that time ;)

#### WebRTC servers credentials

If you take the URL from the previous section and do the following:

* From: <https://stripchat.com/api/front/v2/models?limit=10000>
* To: <https://stripchat.com/api/front/v2/config>

You'll get the complete website config in `JSON` and this include something juicy:

```json
"webRTCOriginTurnServersPortMap":{"servers":[]},"webRTCTurnServersConfig":{"servers":["eu11","eu14","as1","as2","eu1","eu2","eu3","eu4","eu5","eu6","eu7","eu8","eu9","eu10","eu11","eu12","eu13","eu14","eu15","eu16","eu17","eu18","eu19","eu20","eu21","eu22","eu23","eu24","eu25","eu26","eu27","eu28","as1","as2","as3","as4","as5","as6","as7","as8","as9","as10","us1","us2","us3","us4","us5","us6","us7","us8","us9","us10","us11","us12","us13","us14","us15","us16","us17","us18","us19","us20","us21","us22","us23","us24","us25","us26","us27","us28"],"iceServersTemplate":{"iceServers":[{"url":"turn:b-{server}.stripcdn.com:2083?transport=udp","username":"johndoe","credential":"j8Hkl0UYqwW4r"},{"url":"turn:b-{server}.stripcdn.com:2083?transport=tcp","username":"johndoe","credential":"j8Hkl0UYqwW4r"}],"iceTransportPolicy":"relay"}}
```

More precisely:

```json
"username":"johndoe","credential":"j8Hkl0UYqwW4r"
```

So if you reconstruct the data from just the `WebRTC` servers part you get more than 40 servers with the same credentials applied to them:

* From:
  * `turn:b-{server}.stripcdn.com:2083?transport=udp`
  * `turn:b-{server}.stripcdn.com:2083?transport=tcp`
* To:
  * `turn:b-eu11.stripcdn.com:2083?transport=udp`
  * `turn:b-eu11.stripcdn.com:2083?transport=tcp`

And so on.

If you combine them with [turner](https://github.com/staaldraad/turner)... It will gives you the same amount of web proxies that you can use to hide your trafic behind the stripchat servers.

#### Live streams recording

* Click on any model stream
* Disable the low latency mode (_click on the "lightening" icon to toggle it off_)
* Open up the web console
* Go to the __Network__ tab
* Filter with `m3u8`

![image](https://cdn.hashnode.com/res/hashnode/image/upload/v1665958614948/gljwzftcO.png)

Here the interesting URL is:

* <https://b-hls-19.doppiocdn.com/hls/17085196/master/17085196_auto.m3u8>

This is the direct stream URL of the model that you can play in __VLC__ or `ffplay` but not just that, you can also record it and/or restream it with `ffmpeg`.

```console
$ ffplay -hide_banner "https://b-hls-19.doppiocdn.com/hls/17085196/master/17085196_auto.m3u8"
[hls @ 0x7fb624000bc0] Skip ('#EXT-X-VERSION:6')B sq=    0B f=0/0   
[hls @ 0x7fb624000bc0] Opening 'https://b-hls-16.doppiocdn.com/hls/17085196/17085196_160p.m3u8' for reading
[hls @ 0x7fb624000bc0] Skip ('#EXT-X-VERSION:6')B sq=    0B f=0/0   
[hls @ 0x7fb624000bc0] Skip ('#EXT-X-INDEPENDENT-SEGMENTS')
[hls @ 0x7fb624000bc0] Skip ('#EXT-X-DISCONTINUITY-SEQUENCE:2')
[hls @ 0x7fb624000bc0] Skip ('#EXT-X-PROGRAM-DATE-TIME:2022-08-28T23:22:38.407+0000')
[hls @ 0x7fb624000bc0] Skip ('#EXT-X-PROGRAM-DATE-TIME:2022-08-28T23:22:40.385+0000')
[hls @ 0x7fb624000bc0] Skip ('#EXT-X-PROGRAM-DATE-TIME:2022-08-28T23:22:42.411+0000')
[https @ 0x7fb624015980] Opening 'https://b-hls-16.doppiocdn.com/hls/17085196/17085196_240p.m3u8' for reading
[hls @ 0x7fb624000bc0] Skip ('#EXT-X-VERSION:6')B sq=    0B f=0/0   
[hls @ 0x7fb624000bc0] Skip ('#EXT-X-INDEPENDENT-SEGMENTS')
[hls @ 0x7fb624000bc0] Skip ('#EXT-X-DISCONTINUITY-SEQUENCE:2')
[hls @ 0x7fb624000bc0] Skip ('#EXT-X-PROGRAM-DATE-TIME:2022-08-28T23:22:36.257+0000')
[hls @ 0x7fb624000bc0] Skip ('#EXT-X-PROGRAM-DATE-TIME:2022-08-28T23:22:38.317+0000')
[hls @ 0x7fb624000bc0] Skip ('#EXT-X-PROGRAM-DATE-TIME:2022-08-28T23:22:40.323+0000')
[https @ 0x7fb624015980] Opening 'https://b-hls-16.doppiocdn.com/hls/17085196/17085196_480p.m3u8' for reading
[hls @ 0x7fb624000bc0] Skip ('#EXT-X-VERSION:6')B sq=    0B f=0/0   
[hls @ 0x7fb624000bc0] Skip ('#EXT-X-INDEPENDENT-SEGMENTS')
[hls @ 0x7fb624000bc0] Skip ('#EXT-X-DISCONTINUITY-SEQUENCE:2')
[hls @ 0x7fb624000bc0] Skip ('#EXT-X-PROGRAM-DATE-TIME:2022-08-28T23:22:36.288+0000')
[hls @ 0x7fb624000bc0] Skip ('#EXT-X-PROGRAM-DATE-TIME:2022-08-28T23:22:38.247+0000')
[hls @ 0x7fb624000bc0] Skip ('#EXT-X-PROGRAM-DATE-TIME:2022-08-28T23:22:40.300+0000')
```

> Nope, I won't show you nice pictures of the captured stream :D

I won't go in detail about it as it will be quite off topic but maybe in another wiki article.

## Thanks

Thanks for reading. Please share your thoughts in the [Telegram Channel](https://t.me/thcorg).

## References

* <https://developers.google.com/web/tools/chrome-devtools/console/console-reference>
* <https://developer.mozilla.org/en-US/docs/Web/API/console>
* <https://developer.mozilla.org/en-US/docs/Web/API/Web_Storage_API>
* <https://developer.mozilla.org/en-US/docs/Web/API/IndexedDB_API>
* <https://feross.org/fill-disk/>
* <https://github.com/staaldraad/turner>

