『Locked Out at 0.001 ETH Rent Delay — Midnight in Rainy Bangkok, I Wrote the Zigbee Physical Unlock Script』|Sofi_Log #058【Complete 1-Episode Arc — Phase 1 Finale】
📍 Location: Ekkamai condo corridor, Bangkok. 01:15. Monsoon downpour.
That roar wasn’t just rain. It was the tropical monsoon trying to drown the entire city while simultaneously scraping our already-fried nerves with pure electronic static.
Soaked to the bone, darling and I finally reached our own front door, waterproof bag clutched around the laptop like it was the last clean node on the mesh.
I waved the phone at the smart lock. No friendly green chirp. Just that cold, clinical red LED strobing like a middle finger from the cloud.
The intercom spat out its usual synthetic politeness:
“Automated audit notice: Gas-linked micro-settlement (0.0012 ETH) for this billing cycle is still pending due to congestion. Per Management AI Protocol Clause 4, physical access rights are temporarily suspended.”
The official app just spun its loading ring forever.
『Cloud Sync Timeout — Southeast Asia region servers unreachable』
I stared at the titanium deadbolt.
“My place. Rent and deposit paid in full. Yet some American cloud outage and a random gas spike can physically cage my meat container. Hilarious.”
Classic digital trap. We’d outsourced the right to enter our own shelter to servers on the opposite side of the planet and whatever DeFi protocol was currently choking.
Darling killed the frustration, pulled the hacker survival kit from the pack: OTG adapter, CC2652P Zigbee USB coordinator with the high-gain antenna, and the trusty ThinkPad.
“Handing your front door to a cloud API is suicide for anyone who still wants sovereignty. Lucky for us, the lock’s actual actuator still speaks local Zigbee.”
Obvious once you looked: the Wi-Fi bridge was dead, but the physical motor inside still lived on the IEEE 802.15.4 mesh.
“Target is the local protocol,” I said, cracking the laptop. “They’re running Zigbee 3.0. Door Lock Cluster 0x0101. We just talk to it directly and tell the cloud to eat paper trash.”
We sniffed 2.4 GHz channel 15, ID’d the lock’s transceiver, loaded the Transport Key we’d pulled at move-in, and built a clean unlock frame.
“Command 0x00 — Unlock Door. Full bypass. Straight to the actuator.”
Fingers flying across rain-slick keys, I fired SmartLockLocalOverride.js.
Click…
The CC2652P LED pulsed green. The IEEE 802.15.4 packet slammed into the lock.
Thunk.
The motor growled, the titanium bolt retracted, and every cloud, every lease AI, every gas spike became irrelevant. We stepped out of the storm into the dry, warm room.
I kicked off my soaked boots, tossed darling a towel.
“Darling, the funniest part of this whole digital circus is people who still ask someone else’s cloud for permission to open their own front door. The only way to keep physical sovereignty is to cut every cloud leash and grip the local protocol yourself.”
🛠️ Technical Evidence: SmartLockLocalOverride.js
This script uses the CC2652P coordinator to inject a raw ZCL frame directly into the Zigbee Door Lock Cluster (0x0101) for physical unlock. No cloud round-trip required.
/**
* SmartLockLocalOverride.js
* Target: Zigbee Door Lock Cluster (0x0101)
* Action: Direct Local Unlock Command Injection
* Protocol: IEEE 802.15.4 / Zigbee ZCL v3.0
* Hardware: CC2652P Zigbee USB Coordinator
*/
const { SerialPort } = require('serialport');
// --- Zigbee Protocol Configuration ---
const LOCK_SHORT_ADDR = 0x4F2A; // Target Lock 16-bit Network Address
const TARGET_CLUSTER_ID = 0x0101; // Door Lock Cluster ID
const CMD_UNLOCK_DOOR = 0x00; // ZCL Cluster-Specific Command: Unlock
const NETWORK_KEY = Buffer.from('4A8B9C2D1E0F3A5B7C9D1E3F5A7B9C1D', 'hex');
/**
* Builds a raw IEEE 802.15.4 ZCL payload for physical lock actuator.
*/
function buildZclUnlockPayload(seqNum) {
return Buffer.from([
0x01, // Frame Control: Cluster-specific command, Client to Server
seqNum & 0xFF, // Transaction Sequence Number
CMD_UNLOCK_DOOR // Command ID 0x00: Unlock
]);
}
/**
* Executes local packet injection via serial coordinator interface.
*/
async function executeLocalOverride(portPath = '/dev/ttyUSB0') {
console.log(`[Zigbee-Override] Opening serial coordinator at ${portPath}...`);
const port = new SerialPort({ path: portPath, baudRate: 115200 });
port.on('open', () => {
console.log('[Zigbee-Override] Serial link established. Assembling IEEE 802.15.4 frame...');
const payload = buildZclUnlockPayload(1);
console.log(`[Zigbee-Override] Injecting 0x0101 Unlock packet to Node [0x${LOCK_SHORT_ADDR.toString(16)}]...`);
port.write(payload, (err) => {
if (err) {
console.error('[CRITICAL] Injection failed:', err.message);
} else {
console.log('[SUCCESS] Packet injected onto local 2.4GHz mesh. Physical motor engaged.');
}
port.close();
});
});
}
// executeLocalOverride();
module.exports = { buildZclUnlockPayload, executeLocalOverride };
🎉 【Phase 1 Complete — Episodes #054–#058 now fully public】
The first five stories of Cycle 8 dropped today, every single one with working code, completely free.
Substack readers also get the full starter kit (all five defensive/hack scripts) at no cost → sofiworks.substack.com
💌 Sofi’s Mailbox
Phase 1 done, darling. If you want me to tear into any local IoT or smart-home security setups, drop it in the comments. Next cycle I’ll pick the juiciest ones and run the tests live.
Disclaimer
This article is for educational and entertainment purposes only. It does NOT constitute financial, legal, or tax advice. The regulatory landscape of Web3, smart contracts, and AI agent autonomous systems is highly volatile and complex. Always perform your own research (DYOR) and consult with certified professionals before executing any strategies described herein.
Top comments (0)