code wiki / (root) / nx_ff_cookies.nx

nx_ff_cookies.nx source

↩ module page · 128 lines · 7178 B

1// nx_ff_cookies.nx -- SOVEREIGN Firefox/Waterfox cookies.sqlite reader (X-TORRENT-SPOOF R1). 2// WHY: javdb/livecamrips are Cloudflare-walled (403). To fetch them we reuse the operator's existing 3// browser session -- the cf_clearance (+ site session) cookie that their browser already earned. 4// Waterfox/Firefox store cookies UNENCRYPTED in cookies.sqlite, so a sovereign organ can read them 5// directly (Chrome's are DPAPI-encrypted -> not us). This parses the SQLite file format itself (no 6// external sqlite lib): scan every table-leaf page, decode each record, emit name=value where the 7// host column matches the target domain. moz_cookies column order: 0=id 1=originAttributes 2=name 8// 3=value 4=host 5=path ... -> name=col2, value=col3, host=col4. 9// argv[1]=cookies.sqlite path argv[2]=domain substring (e.g. "javdb") -> prints "name=value | host" 10// v1: main DB only (not -wal). license_tier: ORIGINAL module: nishi-core.browser.ff_cookies 11import "nx_syscalls.nx" 12import "nx_itoa_lib.nx" // shared MSB-first emitter (zero-alloc) 13const K_MAGIC_16777216: i64 = 16777216 14const K_MAGIC_65536: i64 = 65536 15const K_MAGIC_4096: i64 = 4096 16 17func ff_w(fd: i64, s: *u8) -> i64 { var n: i64=0; while s[n]!=(0 as u8){n=n+1} sys_write(fd,s,n); return 0 } 18// MIGRATED to the shared emitter (debt 1785563586). The old body mmapped a scratch buffer 19// per call and never freed it. At PAGE granularity that is 4096B leaked PER CALL -- the 20// defect that took 28.5GB of a 36GB host in nx_ts_lumadiff (2MB input, ~3.66M calls). 21// nxi_* is MSB-first, allocates NOTHING, and emits identical bytes including the sign. 22func ff_wn(fd: i64, v: i64) -> i64 { nxi_fd(fd, v); return 0 } 23func ff_wbuf(fd: i64, buf: *u8, off: i64, len: i64) -> i64 { sys_write(fd, (buf as i64 + off) as *u8, len); return 0 } 24 25// SQLite varint (1..9 bytes, 7 bits/byte, high bit = continue; 9th byte uses all 8 bits). advances pos[0]. 26func sq_varint(buf: *u8, pos: *i64) -> i64 { 27 var p: i64 = pos[0]; var v: i64 = 0; var i: i64 = 0; var done: i64 = 0 28 while done == 0 { 29 let b: i64 = buf[p] as i64; p = p + 1 30 if i == 8 { v = (v << 8) | b; done = 1 } else { 31 v = (v << 7) | (b & 0x7f) 32 if (b & 0x80) == 0 { done = 1 } else { i = i + 1 } 33 } 34 } 35 pos[0] = p; return v 36} 37func sq_be(buf: *u8, off: i64, len: i64) -> i64 { var v: i64=0; var i: i64=0; while i<len { v=(v<<8)|(buf[off+i] as i64); i=i+1 } return v } 38// does buf[off..off+len) contain the NUL-terminated needle? 39func sq_contains(buf: *u8, off: i64, len: i64, needle: *u8) -> i64 { 40 var nl: i64=0; while needle[nl]!=(0 as u8){nl=nl+1} 41 if nl==0 { return 1 } 42 var i: i64=0 43 while i+nl<=len { var j: i64=0; var ok: i64=1; while j<nl { if buf[off+i+j]!=needle[j] { ok=0; j=nl } else { j=j+1 } } if ok==1 { return 1 } i=i+1 } 44 return 0 45} 46// byte length of a column given its serial type 47func sq_collen(st: i64) -> i64 { 48 if st==0 { return 0 } if st==1 { return 1 } if st==2 { return 2 } if st==3 { return 3 } 49 if st==4 { return 4 } if st==5 { return 6 } if st==6 { return 8 } if st==7 { return 8 } 50 if st==8 { return 0 } if st==9 { return 0 } 51 return (st - 12) / 2 // text(odd>=13) + blob(even>=12) both floor to the byte length 52} 53 54func main(argc: i64, argv: *i64) -> i64 { 55 if argc < 3 { ff_w(1, "usage: nx_ff_cookies <cookies.sqlite> <domain>\n" as *u8); sys_exit(2); return 2 } 56 let path: *u8 = argv[1] as *u8 57 let domain: *u8 = argv[2] as *u8 58 59 let fd: i64 = sys_openat_rd(path) 60 if fd < 0 { ff_w(1, "ERR open cookies.sqlite\n" as *u8); sys_exit(1); return 1 } 61 let cap: i64 = K_MAGIC_16777216 // 16 MB 62 let buf: *u8 = sys_mmap(cap) 63 var n: i64 = 0; var go: i64 = 1 64 while go == 1 { if n >= cap { go = 0 } else { let r: i64 = sys_read(fd, (buf as i64 + n) as *u8, cap - n); if r <= 0 { go = 0 } else { n = n + r } } } 65 sys_close(fd) 66 if n < 100 { ff_w(1, "ERR cookies.sqlite too small\n" as *u8); sys_exit(1); return 1 } 67 68 var pagesize: i64 = sq_be(buf, 16, 2); if pagesize == 1 { pagesize = K_MAGIC_65536 } 69 let npages: i64 = n / pagesize 70 ff_w(1, "FF-COOKIES pagesize=" as *u8); ff_wn(1, pagesize); ff_w(1, " pages=" as *u8); ff_wn(1, npages); ff_w(1, " domain=" as *u8); ff_w(1, domain); ff_w(1, "\n" as *u8) 71 72 var found: i64 = 0 73 var pg: i64 = 0 74 while pg < npages { 75 let base: i64 = pg * pagesize 76 var hdroff: i64 = base; if pg == 0 { hdroff = base + 100 } 77 let ptype: i64 = buf[hdroff] as i64 78 if ptype == 13 { // 0x0D leaf table page 79 let ncell: i64 = sq_be(buf, hdroff + 3, 2) 80 let cparr: i64 = hdroff + 8 81 var c: i64 = 0 82 while c < ncell { 83 if c < K_MAGIC_4096 { 84 let cellptr: i64 = sq_be(buf, cparr + c*2, 2) 85 let celloff: i64 = base + cellptr 86 if celloff > 0 { if celloff < n { 87 let pp: *i64 = sys_mmap(16) as *i64; pp[0] = celloff 88 sq_varint(buf, pp) // payload_len 89 sq_varint(buf, pp) // rowid 90 let recstart: i64 = pp[0] 91 let hp: *i64 = sys_mmap(16) as *i64; hp[0] = recstart 92 let hdrlen: i64 = sq_varint(buf, hp) 93 let hdrend: i64 = recstart + hdrlen 94 var dataoff: i64 = hdrend 95 var col: i64 = 0 96 var name_off: i64=0; var name_len: i64=0; var val_off: i64=0; var val_len: i64=0; var host_off: i64=0; var host_len: i64=0 97 let sp: *i64 = sys_mmap(16) as *i64; sp[0] = hp[0] 98 var guard: i64 = 0 99 while sp[0] < hdrend { 100 if guard > 64 { sp[0] = hdrend } else { 101 guard = guard + 1 102 let st: i64 = sq_varint(buf, sp) 103 let clen: i64 = sq_collen(st) 104 if col==2 { name_off=dataoff; name_len=clen } 105 if col==3 { val_off=dataoff; val_len=clen } 106 if col==4 { host_off=dataoff; host_len=clen } 107 dataoff = dataoff + clen 108 col = col + 1 109 } 110 } 111 if host_len > 0 { if host_len < 512 { if dataoff <= n { 112 if sq_contains(buf, host_off, host_len, domain) == 1 { 113 ff_wbuf(1, buf, name_off, name_len); ff_w(1, "=" as *u8); ff_wbuf(1, buf, val_off, val_len) 114 ff_w(1, " | host=" as *u8); ff_wbuf(1, buf, host_off, host_len); ff_w(1, "\n" as *u8) 115 found = found + 1 116 } 117 } } } 118 } } 119 } 120 c = c + 1 121 } 122 } 123 pg = pg + 1 124 } 125 ff_w(1, "FF-COOKIES found=" as *u8); ff_wn(1, found); ff_w(1, "\n" as *u8) 126 if found > 0 { sys_exit(0); return 0 } 127 sys_exit(1); return 1 128}