WTF_ELECTRICALENGINEERING
WTF_ELECTRICALENGINEERING
Platform: Broncoctf2026 | Category: Misc | Type: Challenge | Difficulty: Hard | OS: NA | Author: D3v0o0Nu11 | Date: 2026-07-11 | Status: Solved Techniques: binary_group_to_ascii_decoding, msb_bit_plane_extraction, multi_stage_oob_link_following, radix4_booth_pp_decoder_evaluation, url_extraction_from_stego
Summary
Task: two academic Booth-multiplier paper figures (PNG) hide a multi-stage puzzle; the paper identity is misdirection. Solution: extract URLs from bit-plane 7 (MSB) of the red channel, follow tinyurl -> Google Drive to a .b input sequence, and since inputs are only 0000/1110 the radix-4 Booth PP decoder collapses to 1110->1 / 0000->0, giving 18 ASCII bytes = the flag.
Recon
Port scan
nmap -p- -sV -sC <TARGET> --min-rate 1000 -Pn
| Port | Service | Version | Notes |
|---|---|---|---|
| <PORT> | <SVC> | <VER> | <notes> |
Enumeration highlights
- Event:
broncoctf2026| ID:20260711_broncoctf2026_wtf_electricalengineering - Tags: multi_stage, ascii_decoding, misdirection, verilog, png_steganography, red_channel, bit_plane_stego, msb_stego, radix4_booth, booth_encoder_decoder, tinyurl, google_drive
- Indicators: academic IEEE/VLSI paper figures given as challenge images, normal LSB/alpha/binwalk/strings/exiftool all find nothing, hidden data lives in bit-plane 7 (MSB) of a single channel, URLs (tinyurl) extracted from stego lead to Google Drive folders, a .b binary-formatted input file plus Verilog hints imply simulating a described logic circuit
- Source:
20260711_broncoctf2026_wtf_electricalengineering.md
Foothold
Vulnerability / Misconfiguration
- Binary_group_to_ascii_decoding
- Msb_bit_plane_extraction
- Multi_stage_oob_link_following
- Radix4_booth_pp_decoder_evaluation
- Url_extraction_from_stego
<command>
Exploitation
- See original writeup content for detailed exploitation.
Privilege Escalation
Enumeration
sudo -l find / -perm -4000 2>/dev/null getcap -r / 2>/dev/null cat /etc/crontab ps aux
Exploitation
- N/A for challenge-type writeup; see exploitation above.
- Flag obtained via challenge solve.
<command>
Flags
| Flag | Location | Value |
|---|---|---|
| flag | REDACTED |
Key Takeaways / Lessons
- binary_group_to_ascii_decoding
- msb_bit_plane_extraction
- multi_stage_oob_link_following
- radix4_booth_pp_decoder_evaluation
- url_extraction_from_stego
- Tags: multi_stage, ascii_decoding, misdirection, verilog, png_steganography, red_channel, bit_plane_stego, msb_stego, radix4_booth, booth_encoder_decoder, tinyurl, google_drive
Original Writeup
<details><summary>Click to expand original content</summary>Description
I'm supposed to find the flag somewhere but this guy just sent me two images to try to find it! What the flip, I don't know anything about Electrical Engineering!!
Two files are provided:
ChallengeCircuit.png(301x250 RGBA) — a CMOS transistor-level schematic of a radix-4 Booth partial-product decoder.Challenge.png(715x396 RGBA) — "TABLE VI — Comparisons of The Radix-4 Booth Designs for Generating One Partial Product Row".
Goal: recover the bronco{...} flag hidden somewhere in/behind these images.
Analysis
Recon — the paper is a red herring
Reverse-image searching both figures identifies their common source:
Yen-Jen Chang, Yu-Cheng Cheng, Shao-Chi Liao, Chun-Huo Hsiao, "A Low Power Radix-4 Booth Multiplier With Pre-Encoded Mechanism," IEEE Access vol. 8, pp. 114842–114853, 2020, DOI 10.1109/ACCESS.2020.3003684.
ChallengeCircuit.png= Figure 9(b), the proposed low-cost decoder.Challenge.png= Table VI.
Lesson (misdirection): identifying the paper is NOT the solution. Guessing the
normalized paper title as the flag (e.g.
bronco{a_low_power_radix-4_booth_multiplier_with_pre-encoded_mechanism}) is
wrong. The paper is only context — it teaches the Booth decoder needed in the
final stage.
Failed approaches (do not repeat)
- PNG chunk inspection — no
tEXt/zTXt/trailing data. - Alpha channel — all
255. - Standard LSB (bit 0) extraction on R/G/B/A — nothing.
binwalk,strings,exiftool— nothing.- Table numeric values (transistor counts, delays, power) do NOT decode to ASCII.
- The circuit's small truth table alone is not the payload.
Breakthrough — bit-plane 7 (MSB) of the RED channel
The hidden data is in bit-plane 7 (the most significant bit) of the red channel, read row-major (top-left → bottom-right), packed 8 bits per byte, MSB-first. The key insight is to check HIGH bit-planes and single-channel extraction, not just LSB.
Extraction yields a printable URL in each image:
ChallengeCircuit.png→https://tinyurl.com/3pya79weChallenge.png→https://tinyurl.com/hnexnehb
Solution
Stage 1 — MSB bit-plane extraction
#!/usr/bin/env python3
# Extract bit-plane 7 (MSB) of the RED channel, row-major, MSB-first packing.
from PIL import Image
import numpy as np
def extract_msb_red(path):
img = np.array(Image.open(path).convert("RGBA"))
red = img[:, :, 0].flatten() # row-major
bits = (red >> 7) & 1 # bit-plane 7 (MSB)
n = (len(bits) // 8) * 8
bytes_out = np.packbits(bits[:n]) # MSB-first by default
# keep the leading printable ASCII run
s = bytes(bytes_out).split(b"\x00")[0]
printable = bytes(c for c in s if 32 <= c < 127)
return printable.decode(errors="ignore")
print(extract_msb_red("ChallengeCircuit.png")) # https://tinyurl.com/3pya79we
print(extract_msb_red("Challenge.png")) # https://tinyurl.com/hnexnehb
Stage 2 — follow the links (OOB)
tinyurl.com/3pya79we→ Google Drive folder "BroncoCTFChallengeCircuit" containinghintscircuit.txt.tinyurl.com/hnexnehb→ Google Drive folder "BroncoCtfChallengeNonCircuit" containinghintstable.txtandinputsequence.b.
Files download via https://drive.google.com/uc?export=download&id=FILE_ID.
hintscircuit.txt (circuit folder):
Here the link to where you can find the actual gate level diagram (ResearchGate publication 342326148, page 6). Use
readmembinstead of writing out all the binary yourself. On the gate-level diagram you don't need to worry aboutzero_ias it will be zero whatever you do. Use the same method (MSB stego) to grab the input sequence. Once you feed the input binary to the circuit, convert it to ASCII and you get the flag.
hintstable.txt (non-circuit folder):
The binary file is your input sequence. When feeding it into the Verilog, the order should be: MSB =
neg_i, thenx_j, thennx_{j-1}, LSB =ot_i.zero_iis always zero. Free Verilog: edaplayground; use SystemVerilog/Verilog for testbench + design, Icarus Verilog 12.
Stage 3 — the input sequence
inputsequence.b: 18 rows, each row = 8 space-separated 4-bit groups. Each 4-bit
group is {neg_i (MSB), x_j, nx_{j-1}, ot_i (LSB)}. Every group is either 0000
or 1110:
0000 1110 1110 0000 0000 0000 1110 0000
0000 1110 1110 1110 0000 0000 1110 0000
0000 1110 1110 0000 1110 1110 1110 1110
0000 1110 1110 0000 1110 1110 1110 0000
0000 1110 1110 0000 0000 0000 1110 1110
0000 1110 1110 0000 1110 1110 1110 1110
0000 1110 1110 1110 1110 0000 1110 1110
0000 1110 1110 0000 1110 1110 1110 1110
0000 1110 1110 1110 0000 1110 1110 0000
0000 0000 1110 1110 0000 0000 1110 0000
0000 1110 1110 0000 1110 0000 0000 0000
0000 1110 1110 0000 1110 0000 0000 0000
0000 1110 0000 1110 0000 1110 0000 1110
0000 0000 1110 1110 0000 1110 1110 0000
0000 1110 1110 0000 1110 1110 0000 1110
0000 1110 0000 0000 0000 0000 1110 0000
0000 1110 0000 1110 1110 0000 0000 1110
0000 1110 1110 1110 1110 1110 0000 1110
Stage 4 — the elegant shortcut (skip Verilog)
The intended path builds the gate-level radix-4 Booth partial-product (PP) decoder
in Verilog (readmemb the .b file, drive the decoder, dump PP bits). But because
only two input patterns ever appear, feeding them through the proposed PP
decoder gives:
PP(0000) = 0PP(1110) = 1
So each 4-bit group collapses to a single output bit. Eight groups per row → one byte → one ASCII character; 18 rows → 18 characters. No simulator required.
#!/usr/bin/env python3
# Radix-4 Booth PP decoder collapses to a 1-bit map on the only two inputs seen.
rows = open("inputsequence.b").read().strip().splitlines()
m = {"1110": "1", "0000": "0"} # PP(1110)=1, PP(0000)=0
flag = ""
for r in rows:
bits = "".join(m[g] for g in r.split()) # 8 groups -> 8 bits, MSB-first
flag += chr(int(bits, 2)) # 1 byte -> 1 ASCII char
print(flag) # bronco{REDACTED}
Confirmation: submitted to CTFd /api/v1/challenges/attempt (challenge_id 38) →
{"status":"correct"}.
Auto-tracked: saved to WriteUps; run
/xesor-reviseto fold lessons into XESXor_Methodology.md.
signed by XESXOR