Repository navigation
Starchorus 0.1.1
Most of what changed in 0.1.1 is the page showing less. A Pager on a desk heard one nearby device that changed its address every forty-odd seconds, and 0.1.0 drew it faithfully: a couple of hundred satellites at the same signal strength, a private Milky Way across the middle of the sky. The data was correct and the picture was wrong. A visualiser earns its keep by knowing the difference, so a device like that is now one cloud, named for what it is, and a key shows or hides the addresses behind it for anyone who wants to count them.
The same instinct runs through the rest. When a phone walked out of the Pager's Wi-Fi the chip said 'Stale', which blamed the capture for the page's own deafness; it now says 'Offline' when the Pager cannot be reached and keeps 'Stale' for a Pager that answers with an old capture. On a phone the panels used to sit on top of the sky; the sky now has the whole screen and the panels live in a sheet you pull up when you want them. The Pager's own menu has two rows at rest, Start and Settings, and a QR code that opens the page on your phone, on the view that a menu which needs explaining has too much in it. The Overview on the small screen used to redraw itself every few seconds and listen for keys only in between; it now draws when asked and then waits, so a press is never lost.
Underneath, the collector does about a quarter less work per cycle on the Pager's one core, the Overview on the small screen runs one jq pass per screen where it ran seventeen, and the page polls in step with the collector instead of every five seconds. The version number is 0.1.1 because nothing you knew how to do is different. What has gone is the part you had to put up with.
What changed
Added
- Pager menu: 'Starchorus: Stopped' offers 'Start' and 'Settings', and 'Starchorus: Running' offers 'Overview', 'Open on Phone', 'Stop' and 'Settings', worked out afresh at every draw from the processes themselves.
- 'Open on Phone' shows the page's address as a QR code, and 'Start Web Page' takes its place while the page server is not up.
- Phone layout: the sky keeps the screen under a narrow status bar, and the controls move into a bottom sheet with three heights: a peek, half and full.
- On a phone held on its side, the status bar and the sheet form a column on the left, and every edge keeps clear of the device's safe areas.
- Hide panels (key U, at any screen size) leaves the sky alone with a small status pill that brings the panels back.
- Random clouds: free randomised addresses heard in one signal band, in bursts that recur at a steady period, are drawn as one cloud with its count, and its detail gives the period and lists the addresses. A period counts only when it stands clear of what unrelated bursts in that band would give by chance, so two devices of different periods at one signal are two clouds, and bands whose periods match are merged; a band is judged on its newest 1,500 bursts.
- A cloud whose bursts keep no one rhythm (a rhythm share below 0.6) is mixed: its detail reads 'no one rhythm' in place of a period, and the page words it 'possibly one or more nearby devices' where it would say 'probably one nearby device'.
- Random (key X,
?random=cloud|show|hide) cycles between clouds, the addresses one by one, and hidden; the legend reads 'n randomised MAC · k in m clouds', and the randomised and cloud counts also appear in the statistics and the inventory. - The Overview counts clouds by the same rule, capture by capture, in its summary ('Clients 247 free (245 random, 1 cloud)') and shows each one as a single line on the Stations screen.
- The Overview shows 'No new scan for …' in red, on every screen, when the collector has not written a capture for more than three of its intervals.
- A setting that an environment variable fixes shows '(locked)' in Settings, and its row opens a note instead of changing.
- Page query parameters
?phone=1|0,?panels=0|1and?random=cloud|show|hide. - The page's favicon is inline, so the page still fetches nothing but
starchorus.json. - The payload compares the version and the new
# Contract:header of the installed collector and Overview with its own, and says so once in a dialogue when they differ. - The collector's log says when the vendor cache grows and, once per episode, why a merge into it did not happen.
- The opt-in
STARCHORUS_SOURCE=pineapreads the AP service's own recon list with one bounded read-only command,RECON DEVICES(withSTARCHORUS_PINEAP_CALLS=full,RECON APSandRECON DEVICESunbounded); it is experimental and not cheaper on the Pager than the database path, which stays the default. - New environment variables for the collector:
STARCHORUS_TMPDIR(where the work copy ofrecon.dblives,/tmpby default),STARCHORUS_SKIP_UNCHANGED(0turns the skipping of unchanged cycles off) andSTARCHORUS_PINEAP_CALLS(recentorfull, for thepineapsource only).
Changed
- The Pager menu is shorter: 'Start' and 'Stop' ask nothing, and the rows Dashboard, Services, Options, Status and Exit are gone.
- Settings rows flip in place ('Web Page: ON'), a change made while Starchorus runs is applied when you leave Settings (except 'Web Page', which takes effect at once), and only 'Reset to Defaults' asks first.
- The 'Refresh' and 'Show Last' lists have no 'Other' row. They offer 10 s, 30 s, 1 min and 2 min, and 2 min, 10 min, 1 h, 6 h and 'All (may be slow)'; other values go through
payload.sh set. - Every menu title and row is in Title Case, as in the Pager's own settings.
- Own radios, opening the Overview after 'Start' and switching the collector off are no longer settings: they remain the environment variables
STARCHORUS_OWN,STARCHORUS_DASHBOARDandSTARCHORUS_COLLECTOR, and an old line for them insettings.confis skipped. - 'Start' keeps its spinner up until the first scan since that 'Start' has been written (up to 20 seconds) and then opens the Overview on its summary; key B in the Overview goes up one level, from a screen to the list of screens and from the list to the menu.
- The Overview's first line is 'Overview'. It draws a screen and then waits for a key with no time limit, and never redraws by itself: key A draws the screen again, key B goes up one level (a screen, then the list of the seven screens, then the menu), Left and Right step through the screens, and Up and Down are ignored. 'Reading...' shows while a scan is read, each screen ends with the time of its scan ('Last scan 12:04:31 (42 s ago)') and the keys ('A: Refresh B: Back'), and it reads 'Waiting for the first scan.' until the first scan after 'Start'.
- The page turns 'Stale' when no new capture has come for twice the interval the file announces plus 15 seconds (at least 30 seconds), where it used to count six polls.
- The page says 'Offline' (WarGames 'Link down', Whitehall 'No link') where it said 'Stale' when the Pager has not answered the last three polls by then, as when a phone leaves its Wi-Fi; 'Stale' stays for a Pager that answers with an old capture.
- The page polls in step with the collector, shortly before the next capture is due and then every 2 seconds until it arrives, about three requests per 30-second capture where it made six.
- The replay banner counts captures, not polls, and the signal-over-time axis follows the observed spacing of the captures.
- The page keeps the history of a vanished station for 300 seconds of capture time instead of 60 polls, and an announced interval is capped at 600 seconds.
- The Random switch starts on 'clouds', so a busy sky shows fewer single dots than before.
- The CSV export gains a trailing
cloudcolumn. With clouds present, the JSON export gains acloudsarray, a station in a cloud carriescloud, andstation_countsaddsrandomisedandin_clouds; the SITREP lists the stations outside clouds. - The collector works on a copy of
recon.dbin RAM instead of on flash, and reads it with onesqlite3process per cycle instead of four to seven. - The collector skips a cycle whose database has not changed since the last full pass, and republishes that pass with a new
generated. - A collector cycle takes 265 to 266 ticks of 10 ms of the Pager's CPU where 0.1.0 took 369 to 376, about 28 per cent less, measured one straight after the other on the same data (29 access points, about 299 stations, vendor cache warm).
- A new vendor prefix costs about half a second where it cost about 14 s, because the OUI file is split once by first octet and a lookup reads only the files it needs. The split is made when the collector first starts with the new version (about 8 to 10 s of CPU; 512 files, 2.2 MB, under
cap/oui-indexbesidestarchorus.json), so the first capture after an upgrade comes later than usual. - The security label is decoded from the encryption bits in one walk that stops at the highest bit set, instead of a separate test for each possible bit.
- The Overview runs one
jqprocess per screen and reuses the result while the capture is unchanged, so a screen costs CPU (1.8 s for the summary) only when it is drawn on a new capture and nothing while the Overview waits for a key (0.1.0: 4.6 s every 4 s). A scan that takesjqmore than 20 seconds to read ends as 'This scan took over 20 s to read.' with the hint 'Try Settings > Show Last: 1 h.'. - The collector, the page server and the Overview, as the payload starts them, run at nice 19, so that the Pager's own services come first.
- The netcat page server sends the page with
Cache-Control: max-age=60andstarchorus.jsonwithno-store, where both used to beno-store. tools/install.shreads the six files back and compares them byte for byte, and no longer counts the Pager's missingcksumas a warning.- Documentation: the netcat server is described as the normal page server on an updated Pager, and the Quick Start, the installation guide and the payload's READMEs go through the payload.
- Documentation: the notes on the device record the AP service's recon lists, the OUI file, and the last field of the beacon lines, which is Management Frame Protection and not encryption.
Fixed
- 'Stop' waits until the collector has really ended, and ends its
sleepbetween passes so that it does not wait for the next one. - After a reboot, a pidfile whose process id now belongs to another program no longer shows a false 'Running' or receives a signal.
- Temporary files of a pass that was cut short (
starchorus.json.tmp.<pid>) are removed at the next start. - The netcat page server sends each answer from a copy of the file made in RAM, so the
Content-Lengthmatches the bytes even when the collector replacesstarchorus.jsonmeanwhile. - A client that connects to the netcat page server and sends nothing no longer holds it: it is dropped after 15 seconds, a client that stalls in the request headers is answered after 10 (where the shell has
read -t), and a whole request is ended after 60. - The Overview no longer redraws itself every 4 seconds, a loop that listened for keys only between redraws and so could miss a press; it draws when asked and then waits for a key, and nothing runs while it waits.
- The payload stops its spinner when it is ended while one shows, instead of leaving it on the display.
- The Overview no longer keeps the payload's output open: a payload that is ended while the Overview waits for a key lets go of its runner at once, and the Overview itself ends at its next key press.
Removed
- The page's separate small-screen mode below 720 px, replaced by the phone layout.
- The Overview's own menu with its Summary, Collector and Exit rows.
- The unverified
monitorcommand from the collector's list of read-only AP-service calls, which now holdsRECON APSandRECON DEVICESonly.
Security
- The netcat page server no longer sends
Access-Control-Allow-Origin: *, so a web page open in someone else's browser cannot readstarchorus.jsonfrom the Pager, with every MAC address and SSID in it. - The payload and the collector count a process id from a pidfile as theirs only while
/proc/PID/cmdlinestill names what they started, so no foreign process is ever signalled. - The transmit counters of the Pager's wireless interfaces stayed unchanged across the new code, the opt-in
pineapsource included.
Upgrading
Stop Starchorus, then replace all six files: run tools/install.sh, or, with the Hak5 library copy, replace the payload directory and delete /root/loot/starchorus/starchorus-collect.sh, so that the payload copies its bundle again. The payload now compares the installed files' Contract with its own and says so in a dialogue when they differ, so a payload replaced on its own is noticed. Files from 0.1.0 carry no Contract line and count as contract 1. Your settings in /root/loot/starchorus/settings.conf are kept. Details: INSTALL.md.
Installing
starchorus-0.1.1-pager.tar.gz holds the payload directory as submitted to the Hak5 payload library (hak5/wifipineapplepager-payloads#369): unpack it and copy starchorus/ to /root/payloads/user/reconnaissance/ on the Pager, then start it from the Payloads menu; or run sh tools/install.sh from a checkout (see INSTALL.md). Settings and captures survive the upgrade.
Checksums
8d0364b8767c19c0a7278380211cce3050e349e7cd478f751bf40f822a82e845 starchorus-0.1.1-pager.tar.gz
3972dc9744f6499f0f9b2dbf76696f2ae7ad8af9b23dde66d6af86c9dfb36986 starchorus/LICENSE
3cbad659f549388e0e7cf65a6caa0b2e596f22b910cd6310536ef695cd95c236 starchorus/README.md
a318f640912f5f029c5375c87b38ae0dfaa5e92dee4cad9f3f8d28dec8712193 starchorus/index.html
a24878e263ed604af98660d9d29f273366b9652d0a5442c70a74ffe4095426c0 starchorus/payload.sh
49a06e06a712634def1df2323d0f7f8be4375d3fc7f4e076989ea9ffcd957249 starchorus/starchorus-collect.sh
d283b817042a932e0ed2ef6722fd93a3badc2688a360baaccb3a8cfd1324fcdb starchorus/starchorus-display.sh
ad80a5b4f52b4b9d507a48e6be3bdb69db9528c06454e4c9c09021d164dfe38b starchorus/starchorus-serve.sh