Verizon Fios G3100 and E3200 Research - FiosFiend - 04-03-2025
I recently discovered how easy it was to crack my Netgear default password. That thrill led me to turn my attention to my Fios G3100. However, this has turned out to be a much worthier adversary. Boredom and a bit of tenacity has led me down a winding path, but here is where I am at so far in my research.
The G3100 and E3200 routers are distributed by Verizon. Per usual, the sticker on the back of the unit has the necessary information. I wrote a small python script to scrape Ebay and FB listings and collect all of the associated images. A second script sorts the images using computer vision and OCR to detect the QR code or relevant text. I then personally process the good images to collect the useful information, whenever possible I use the QR code as it is the most trustworthy data to read. Thus far, I have collected over 230+ complete records, as well as saving the images for verification.
FiosG3100andE3200.xlsx (Size: 43.08 KB / Downloads: 7)
Link to Ref_Images.zip (this is a temporary free file sharing link, dm me if it expires)
From this sample we can gain some info on the G3100 key space:- MAC address starting with 04.A2.22 are the oldest and have 16 character passwords
SSID is Fios-XXXXX where X is any char <a-z><A-Z><0-9>
SSID Passwords follow <word><number><word><number><word> format (ex: met8sonata868elm)
Admin Passwords are 16 characters and follow a <word><number><word> format (ex: stubble16crowded)
- MAC address starting with B8:F8:53 are mixed and may have 15 or 16 character passwords
SSID is Fios-XXXXX where X is any char <a-z><A-Z><0-9>
SSID Passwords follow <word><number><word><number><word> format (ex: moat288nit48pug)
Admin Passwords are 16 characters and follow a <word><number><word> format (ex: chopper86notably)
- MAC address starting with 3C.BD.C5 are the newest and have 15 character passwords
SSID is Fios-XXXXX where X is any char <a-z><A-Z><0-9>
or Verizon_XXXXXX where X is any char <A-Z><0-9>
SSID Passwords for “Fios” networks follow <word><number><word><number><word> format (ex: range36vex77toy)
or “Verizon” networks follow <word>-<word>-<word> with a single digit at the end of one word (ex: miry9-elm-north)
- Admin Passwords for “Fios” network are 16 characters and follow a <word><number><word> format (ex: unusual53smelter)
or “Verizon” networks are 9 characters that are <A-Z><0-9> (ex: Z79KGSX4T)
Note: 0 and 1 are not seen in sample
From this sample we can gain some info on the E3200 key space:- MAC address starting with 04.A2.22 are the oldest and have 16 character passwords
SSID is E3200-XXXXX where X is any char <a-z><A-Z><0-9>
SSID Passwords follow <word><number><word><number><word> format (ex: nylon88wit657aye)
Admin Passwords are 16 characters and follow a <word><number><word> format (ex: ritual236auction)
- MAC address starting with B8:F8:53 are mixed and may have 15 or 16 character passwords
SSID is E3200-XXXXX where X is any char <a-z><A-Z><0-9>
SSID Passwords follow <word><number><word><number><word> format (ex: mach92see36flat)
Admin Passwords are 16 characters and follow a <word><number><word> format (ex: seraph497lantern)
- MAC address starting with 3C.BD.C5 have 15 character passwords
SSID is Verizon_XXXXXX where X is any char <A-Z><0-9>
SSID Passwords follow <word>-<word>-<word> with a single digit at the end of one word (ex: tenth-ben6-vend)
Admin Passwords are are 9 characters that are <A-Z><0-9> (ex: 3JB94H6CQ)
Note: 0 and 1 are not seen in sample
- MAC address starting with DC.F5.1B are the newest and have 15 character passwords
SSID is Verizon_XXXXXX where X is any char <A-Z><0-9>
SSID Passwords follow <word>-<word>-<word> with a single digit at the end of one word (ex: plush-fast3-con)
Admin Passwords are are 9 characters that are <A-Z><0-9> (ex: QVB734TKL)
Note: 0 and 1 are not seen in sample
From this sample we can gain some other info:- Password <word> are between 3-7 characters for SSID Password
- Password <number> are between 1-4 digits
- There are 3 HW version (1102, 1103, 1104)
- Serial #’s are 16 digits (except for the most recent E3200 which have 11)
- Shipped firmware ranges from 1.3.5.1 to 3.1.1.16
- There are the 568 unique words extracted from the passwords:
Code: add
aft
ago
aim
air
ait
alp
ape
ark
art
ash
ask
awe
aye
bat
bay
bed
bee
beg
ben
bet
bid
biz
boa
bog
bot
bow
bug
bun
bus
bye
cat
caw
cif
cob
con
cot
cub
cud
cup
cut
dab
dad
dam
daw
day
del
dew
dia
did
dig
dit
doe
dos
due
dun
ear
eeg
ego
eke
elk
elm
end
fad
fat
fax
fay
fed
fee
fen
few
fez
fib
fig
fin
fir
fit
fob
fog
fop
for
fox
fro
gad
gap
gel
gem
gen
gig
gin
gnp
gnu
got
gut
had
han
has
hat
hew
hey
hid
hie
him
hin
hit
hod
hub
hue
hum
ice
icy
jab
jag
jam
jaw
jet
jib
jog
joy
jus
lab
law
lay
let
mad
may
met
mil
mix
mod
mow
mud
mug
mum
nag
naw
new
nib
nip
nit
nod
non
not
now
oak
oar
odd
ode
oil
one
ope
opt
ork
out
owl
pal
paw
pay
pea
pet
pit
pod
pug
pun
pup
put
ram
ran
rap
raw
ray
ree
ret
rid
rna
roe
rug
run
rut
rye
sat
say
see
set
sew
sir
sit
six
sly
sou
sow
soy
spa
sum
sun
sup
tag
tap
tax
tee
too
tot
toy
tun
ush
vex
vie
vim
wad
was
wax
web
wed
why
wig
win
wit
woe
won
woo
wry
yak
yam
yea
yes
yet
yon
you
zap
zoo
abbe
aery
agog
alas
alga
allo
arms
atom
back
bake
beak
been
beep
bits
boar
bolt
bone
book
boss
bred
brew
brow
cafe
cape
cart
cast
cene
cere
cham
char
cloy
copy
crib
cuff
dark
dear
deny
dewy
dial
dine
dint
dock
doff
dory
doth
drub
dump
dust
each
ever
exam
fade
fame
fare
fast
fawn
feet
felt
fine
flat
flaw
flit
form
fund
fuss
gage
gain
gall
gate
gent
golf
grab
gray
grey
grim
hair
hake
halt
hasp
have
hawk
held
hide
high
holm
hone
hoot
hour
huff
hung
ibis
iron
jibe
jill
june
kale
kidd
kirk
knit
knot
lack
lead
lean
lend
lens
less
lump
mach
mama
mass
meat
mica
mint
miry
moat
mood
myth
nail
name
nice
nigh
nite
oboe
oily
ouch
over
paid
pail
pant
pelf
pell
pelt
pert
plan
plot
plus
pool
pram
push
quiz
raze
rill
ripe
roar
rome
roof
rook
ruby
rush
sage
sale
self
shed
sign
sill
skim
slop
slue
slug
soap
solo
spin
stir
swam
swap
tare
tele
tell
than
then
they
tidy
tier
ting
tout
tram
trod
tron
tune
type
upon
vain
vane
vend
vide
vine
wain
wait
wake
wane
want
wash
wavy
what
whom
will
wind
wing
wire
wisp
wood
yard
yeah
yell
yelp
yond
zest
acute
amaze
angel
apace
basic
begot
bough
brush
camel
carry
chase
clean
clump
coach
cocky
combe
comet
coney
could
crate
creak
credo
cress
crock
crone
demur
deter
divan
douse
drily
eater
elope
enact
endow
favor
fifth
fifty
finny
flock
floor
floss
flown
focal
focus
forte
froth
fuzzy
games
gorse
guise
hoary
hobby
hutch
inapt
inner
jewel
mayor
meant
mense
mixed
moose
muddy
mulct
niter
north
nylon
order
papal
pivot
plait
plumy
plush
poser
price
quard
quell
quest
range
rapid
rayon
sales
salon
salty
scend
scope
scour
sense
shack
sixty
smack
snips
snort
spark
spent
steep
stiff
swell
synod
taper
tarry
tempt
tenth
thank
tinge
today
trace
track
tract
trade
trawl
trend
tweet
tyler
vague
verse
vetch
vital
whose
witty
woman
worse
wrist
behove
bethel
german
iodine
pallor
remove
sonata
bloated
sweater
Although there is a lot of useful information collected in the sample, it is still a fairly large key space. With that in mind I decided to take my first dives into firmware analysis, which of course requires some firmware. Looking online, I was able to find a single reddit post that linked to g3100 firmware version 3.2.0.15. With a lot more digging, I was able to find posts with links to firmware for other devices. Using this information I wrote another script to try to find additional firmware. Here’s what I've found, many of these are the first time posted online I believe.
https://cpe-ems34.verizon.com/firmware/g3100_fw_2.0.0.6.bin
https://cpe-ems34.verizon.com/firmware/g3100_fw_3.1.1.17.bin
https://cpe-ems34.verizon.com/firmware/g3100_fw_3.1.1.18.bin
https://cpe-ems34.verizon.com/firmware/g3100_fw_3.2.0.11.bin
https://cpe-ems34.verizon.com/firmware/BHRx/g3100_fw_3.2.0.13.bin
https://cpe-ems34.verizon.com/firmware/BHRx/g3100_fw_3.2.0.14.bin
https://cpe-ems34.verizon.com/firmware/BHRx/g3100_fw_3.2.0.15.bin
https://cpe-ems34.verizon.com/firmware/BHRx/g3100_fw_3.4.0.4_loader.bin
https://cpe-ems34.verizon.com/firmware/BHRx/g3100_fw_3.4.0.6_loader.bin
https://cpe-ems34.verizon.com/firmware/BHRx/g3100_fw_3.4.0.8_loader.bin
https://cpe-ems34.verizon.com/firmware/BHRx/g3100_fw_3.4.0.9_loader.bin
All of the links I found online for Verizon G3100, E3200, and CR1000 all used the cpe-ems34 link. I did find some other routers that were using different servers such as cpe-ems20 and cpe-ems31. Further investigation lead to this site showing all of the Verizon subdomains, which there are a ton of cpe-ems domains.
I tried my script with a few such as 31, 33, 43, however nothing new was turned up.
https://cpe-ems33.verizon.com/firmware/g3100_fw_3.1.1.17.bin
https://cpe-ems34.verizon.com/firmware/g3100_fw_3.2.0.15.bin
I tried binwalk on the first firmware I found (3.2.0.15), and while it extracts the file system, none of the files were readable for me. The entropy graph shows that only a small part is encrypted, so I am a bit confused. My next step is to try to mount it in a VM Linux since I only have Mac and RPI for testing.
g3100_fw_3.2.0.15.bin.png (Size: 75.17 KB / Downloads: 2)
This is what led me to looking for older firmware, however using binwalk on 2.0.0.6 gives me similar results. I know that there should be at least 2 more older firmware 1.3.6.27 and 1.5.0.10 but I have not been able to locate them.
g3100_fw_2.0.0.6.bin.png (Size: 79.38 KB / Downloads: 1)
The possibility of firmware encryption led me to look at physical access of the device. After some quick soldering, I connected to the UART. Unfortunately this did not lead to a shell either, but did provide a bit more information. Referencing some of the output online, I found someone else who also connected this way and had a longer output (possibly because of older firmware?).
Code: BTRM
V1.0
R1.0
L1CD
MMUI
MMU9
DATA
ZBBS
MAIN
OTP?
REF?
REFP
RTF?
RTFP
OTPP
FSBT
NAND
IMG?
IMGL
UHD?
UHDP
RLO?
RLOP
AHD?
ROT?
ROTA
MID?
MIDP
AHDP
SBI?
SBIA
PASS
----
U-Boot SPL 2019.07 (Oct 31 2023 - 03:52:42 -0400)
Strap register: 0x53008176
Board is FLD secure
$SPL: 5.04L.02@419765 $
nand flash device id 0x98d39126, total size 1024MB
block size 256KB, page size 4096 bytes, spare area 216 bytes
ECC BCH-8
FFinit done
find magic number 0x75456e76 at address 0x100000
FFinit find magic number 0xcb00cb at address 0x114000
reading blob from 0x114000 offset 0x26c len 608
digest sha256 OK
FFinit find magic number 0x64447233 at address 0x105000
reading blob from 0x105000 offset 0xc len 59888
digest sha256 OK
mcb selector 0x1427 checksum 0x722c322d safe_mode 0
U-Boot DDR standalone 2019.07 (Jul 25 2021 - 18:43:37 -0700) Build: 5.04L.02@348603
MemsysInit hpg0_generic_aarch64 3.5.1.1 20171009
DDR3
8267D980 80180000 801A0000 00000000 00000000 0020476E
MCB rev=0x00000501 Ref ID=0x0476E Sub Bld=0x002
Dram Timing 11-11-11
start of memsys_begin
mc_cfg_init(): Initialize the default values on mc_cfg
init_memc_dram_profile(): Initializing MEMC DRAM profile
---------------------------------------------------------------
MEMC DRAM profile (memc_dram_profile_struct) values:
dram_type = DDR3
====================================================
PART values:
part_speed_grade = 1600 CL11
part_size_Mbits = 4096 (DRAM size in MegaBits)
part_row_bits = 15 (number of row bits)
part_col_bits = 10 (number of column bits)
part_ba_bits = 3 (number of bank bits)
part_width_bits = 16 (DRAM width in bits)
NUMER OF PARTS:
part_num = 1 (Number of parts)
TOTAL values:
total_size_Mbits = 4096 (DRAM size in MegaBits)
total_cs_bits = 0 (number of cs bits, for dual_rank mode)
total_width_bits = 16 (DRAM width in bits)
total_burst_bytes = 16 (Number of bytes per DRAM access)
total_max_byte_addr = 0x1fffffff (Maximum/last DRAM byte address)
(Number of bits in total_max_byte_addr is 29)
(i.e. total_max_byte_addr goes from bit 0 to bit 28)
ddr_2T_mode = 0
ddr_hdp_mode = 1
large_page = 1
ddr_dual_rank = 0
cs_mode = 0
MEMC timing (memc_dram_timing_cfg_struct) values:
====================================================
MC_CHN_TIM_TIM1_0 register fields:
tCwl = 8
tRP = 11
tCL = 11
tRCD = 11
MC_CHN_TIM_TIM1_1 register fields:
tCCD_L = 4
tCCD = 4
tRRD_L = 6
tRRD = 6
MC_CHN_TIM_TIM1_2 register fields:
tFAW = 32
tRTP = 6
tRCr = 39
MC_CHN_TIM_TIM1_3 register fields:
tWTR_L = 6
tWTR = 6
tWR_L = 12
tWR = 12
MC_CHN_TIM_TIM2 register fields:
tR2R = 0
tR2W = 2
tW2R = 2
tW2W = 0
tAL = 0
tRFC = 208
====================================================
%1 SSC enabled
Poll PHY Status register
PHY Status= 1
Disable Auto-Refresh
[0000000080180200] = 0x00000305
End of memsys_begin
Add/Ctl Alignment
Coarse Adj=0x087 deg, cmd steps=0x0DC
reg 0x801A0090 set to VDL 0x054 with Fine Adj=0x01 deg
reg 0x801A0094 set to VDL 0x054 with Fine Adj=0x01 deg
reg 0x801A0098 set to VDL 0x054 with Fine Adj=0x01 deg
reg 0x801A009C set to VDL 0x054 with Fine Adj=0x01 deg
reg 0x801A00A0 set to VDL 0x054 with Fine Adj=0x01 deg
reg 0x801A00A4 set to VDL 0x054 with Fine Adj=0x01 deg
reg 0x801A00A8 set to VDL 0x054 with Fine Adj=0x01 deg
reg 0x801A00AC set to VDL 0x054 with Fine Adj=0x01 deg
reg 0x801A00B0 set to VDL 0x054 with Fine Adj=0x01 deg
reg 0x801A00B4 set to VDL 0x054 with Fine Adj=0x01 deg
reg 0x801A00B8 set to VDL 0x054 with Fine Adj=0x01 deg
reg 0x801A00BC set to VDL 0x054 with Fine Adj=0x01 deg
reg 0x801A00C0 set to VDL 0x054 with Fine Adj=0x01 deg
reg 0x801A00C4 set to VDL 0x054 with Fine Adj=0x01 deg
reg 0x801A00C8 set to VDL 0x054 with Fine Adj=0x01 deg
reg 0x801A00CC set to VDL 0x054 with Fine Adj=0x01 deg
reg 0x801A00D0 set to VDL 0x054 with Fine Adj=0x01 deg
reg 0x801A00D4 set to VDL 0x054 with Fine Adj=0x01 deg
reg 0x801A00D8 set to VDL 0x054 with Fine Adj=0x01 deg
reg 0x801A00DC set to VDL 0x054 with Fine Adj=0x01 deg
reg 0x801A00E0 set to VDL 0x054 with Fine Adj=0x01 deg
reg 0x801A00E4 set to VDL 0x054 with Fine Adj=0x01 deg
reg 0x801A00E8 set to VDL 0x054 with Fine Adj=0x01 deg
reg 0x801A00EC set to VDL 0x054 with Fine Adj=0x01 deg
reg 0x801A00F0 set to VDL 0x054 with Fine Adj=0x01 deg
reg 0x801A00F4 set to VDL 0x054 with Fine Adj=0x01 deg
reg 0x801A00F8 set to VDL 0x054 with Fine Adj=0x01 deg
reg 0x801A00FC set to VDL 0x054 with Fine Adj=0x01 deg
reg 0x801A0100 set to VDL 0x054 with Fine Adj=0x01 deg
reg 0x801A0108 set to VDL 0x054 with Fine Adj=0x01 deg
reg 0x801A010C set to VDL 0x054 with Fine Adj=0x01 deg
HP RX TRIM
itrim = 0x0
lstrim = 0x9
ZQ Cal HP PHY
R in Ohm
P: Finger=0x318 Term=0x71 Drv=0x28
N: Finger=0x2A6 Term=0x71 Drv=0x28
PLL Ref(Hz)=0x02FAF080 UI STEPS=0x06E
DDR CLK(MHz)=0x31B WL CLK dly(ps)=0x0C8 bitT(ps)=0x274 VDLsize(fs)=0x164D CLK_VDL=0x023
start of memc_init
[0000000080180004] = 0x0110061f
[0000000080180234] = 0x00001101
Enable Auto-Refresh
[0000000080180110] = 0x11100f0e
[0000000080180114] = 0x15141312
[0000000080180118] = 0x19181716
[000000008018011c] = 0x001c1b1a
[0000000080180124] = 0x04000000
[0000000080180128] = 0x08070605
[000000008018012c] = 0x00000a09
[0000000080180134] = 0x000d0c0b
Writing to MC_CHN_CFG_CNFG reg; data=0x00000000
[0000000080180100] = 0x00000000
cfg_memc_timing_ctrl() Called
[0000000080180214] = 0x080b0b0b
[0000000080180218] = 0x04040606
[000000008018021c] = 0x20000627
[0000000080180220] = 0x06060c0c
[0000000080180224] = 0x120000d0
End of memc_init
start of pre_shmoo
[0000000080180004] = 0xc110071f
end of pre_shmoo
SHMOO 28nm
801A0000 80180800 00000000 00020000 00000000
Shmoo WL
One UI Steps : 0x7B
auto-clk result = 01B (filter=0C steps)
initial CLK shift = 023
final CLK shift = 01B
000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000011111111111111111111111
000000000011111111112222222222333333333344444444445555555555666666666677777777778888888888999999999900000000001111111111222
012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012
00 S-------------------X------------------------------------------------------------------------------------------------------
01 S-----------X--------------------------------------------------------------------------------------------------------------
Shmoo RD En
FORCED WR ODT = 0x00001800
DQSN DRIVE PAD CONTROL (from) (to)
B0 00039A91 00079A91
B1 00039A91 00079A91
B0 RISE UI=1 VDL=1B PICK UI=2 VDL=1B
B1 RISE UI=1 VDL=28 PICK UI=2 VDL=28
000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000011111111111111111111111
000000000011111111112222222222333333333344444444445555555555666666666677777777778888888888999999999900000000001111111111222
012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012
00 --S-----------------+---+++X+++++++++++++++--------------------------------------------------------------------------------
01 --S-----------------------------+----++-X+++++++++++++++-------------------------------------------------------------------
Shmoo RD DQ NP
DQS :
B0 VDL=6E ok
B1 VDL=6E ok
000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000011111111111111111111111
000000000011111111112222222222333333333344444444445555555555666666666677777777778888888888999999999900000000001111111111222
012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012
00 ---------------------+++++++++++++++++++++++++++++++++++++++++++++++X+++++++++++++++++++++++++++++++++++++++++++++++-------
01 ---------------+++++++++++++++++++++++++++++++++++++++++++++++++X+++++++++++++++++++++++++++++++++++++++++++++++++---------
02 ------------------+++++++++++++++++++++++++++++++++++++++++++++++X++++++++++++++++++++++++++++++++++++++++++++++++---------
03 ----------+++++++++++++++++++++++++++++++++++++++++++++++X++++++++++++++++++++++++++++++++++++++++++++++++-----------------
04 --------------+++++++++++++++++++++++++++++++++++++++++++++X++++++++++++++++++++++++++++++++++++++++++++++-----------------
05 ------------+++++++++++++++++++++++++++++++++++++++++++++++X++++++++++++++++++++++++++++++++++++++++++++++++---------------
06 ------------++++++++++++++++++++++++++++++++++++++++++++++++X+++++++++++++++++++++++++++++++++++++++++++++++++-------------
07 --------+++++++++++++++++++++++++++++++++++++++++++++++X+++++++++++++++++++++++++++++++++++++++++++++++--------------------
08 ------------------------+++++++++++++++++++++++++++++++++++++++++++++++X++++++++++++++++++++++++++++++++++++++++++++++++---
09 -----------------------++++++++++++++++++++++++++++++++++++++++++++++++X++++++++++++++++++++++++++++++++++++++++++++++++---
10 -------------------+++++++++++++++++++++++++++++++++++++++++++++++++X+++++++++++++++++++++++++++++++++++++++++++++++++-----
11 --------------------+++++++++++++++++++++++++++++++++++++++++++++++++X++++++++++++++++++++++++++++++++++++++++++++++++++---
12 -----------------+++++++++++++++++++++++++++++++++++++++++++++++++X++++++++++++++++++++++++++++++++++++++++++++++++++------
13 ----------------++++++++++++++++++++++++++++++++++++++++++++++++++X+++++++++++++++++++++++++++++++++++++++++++++++++++-----
14 --------------++++++++++++++++++++++++++++++++++++++++++++++++X+++++++++++++++++++++++++++++++++++++++++++++++++-----------
15 ------------------++++++++++++++++++++++++++++++++++++++++++++++++++X+++++++++++++++++++++++++++++++++++++++++++++++++++---
Shmoo RD DQ P
000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000011111111111111111111111
000000000011111111112222222222333333333344444444445555555555666666666677777777778888888888999999999900000000001111111111222
012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012
00 ---------------------+++++++++++++++++++++++++++++++++++++++++++++++X++++++++++++++++++++++++++++++++++++++++++++++++------
01 ---------------+++++++++++++++++++++++++++++++++++++++++++++++++++X+++++++++++++++++++++++++++++++++++++++++++++++++++-----
02 -------------------++++++++++++++++++++++++++++++++++++++++++++++++X+++++++++++++++++++++++++++++++++++++++++++++++++------
03 ---------++++++++++++++++++++++++++++++++++++++++++++++++++X++++++++++++++++++++++++++++++++++++++++++++++++++-------------
04 --------------+++++++++++++++++++++++++++++++++++++++++++++++X++++++++++++++++++++++++++++++++++++++++++++++++-------------
05 ------------+++++++++++++++++++++++++++++++++++++++++++++++++X++++++++++++++++++++++++++++++++++++++++++++++++++-----------
06 ------------++++++++++++++++++++++++++++++++++++++++++++++++X+++++++++++++++++++++++++++++++++++++++++++++++++-------------
07 --------++++++++++++++++++++++++++++++++++++++++++++++++X+++++++++++++++++++++++++++++++++++++++++++++++++-----------------
08 ------------------------++++++++++++++++++++++++++++++++++++++++++++++++X+++++++++++++++++++++++++++++++++++++++++++++++++-
09 -----------------------++++++++++++++++++++++++++++++++++++++++++++++++X++++++++++++++++++++++++++++++++++++++++++++++++---
10 -------------------+++++++++++++++++++++++++++++++++++++++++++++++++X+++++++++++++++++++++++++++++++++++++++++++++++++-----
11 --------------------+++++++++++++++++++++++++++++++++++++++++++++++++X++++++++++++++++++++++++++++++++++++++++++++++++++---
12 -----------------+++++++++++++++++++++++++++++++++++++++++++++++++X+++++++++++++++++++++++++++++++++++++++++++++++++-------
13 ---------------++++++++++++++++++++++++++++++++++++++++++++++++++++X++++++++++++++++++++++++++++++++++++++++++++++++++++---
14 --------------++++++++++++++++++++++++++++++++++++++++++++++++X+++++++++++++++++++++++++++++++++++++++++++++++++-----------
15 -----------------+++++++++++++++++++++++++++++++++++++++++++++++++++X+++++++++++++++++++++++++++++++++++++++++++++++++++---
Shmoo RD DQ N
000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000011111111111111111111111
000000000011111111112222222222333333333344444444445555555555666666666677777777778888888888999999999900000000001111111111222
012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012
00 ------------------+-+++++++++++++++++++++++++++++++++++++++++++++++X++++++++++++++++++++++++++++++++++++++++++++++++-------
01 ----------------++++++++++++++++++++++++++++++++++++++++++++++++X+++++++++++++++++++++++++++++++++++++++++++++++++---------
02 ------------------+++++++++++++++++++++++++++++++++++++++++++++++X++++++++++++++++++++++++++++++++++++++++++++++++---------
03 ---------+++++++++++++++++++++++++++++++++++++++++++++++X++++++++++++++++++++++++++++++++++++++++++++++++------------------
04 ------------++++++++++++++++++++++++++++++++++++++++++++++X+++++++++++++++++++++++++++++++++++++++++++++++-----------------
05 -----------++++++++++++++++++++++++++++++++++++++++++++++++X+++++++++++++++++++++++++++++++++++++++++++++++++--------------
06 -----------+++++++++++++++++++++++++++++++++++++++++++++++++X+++++++++++++++++++++++++++++++++++++++++++++++++-------------
07 -----++++++++++++++++++++++++++++++++++++++++++++++++X+++++++++++++++++++++++++++++++++++++++++++++++++--------------------
08 ------------------------++++++++++++++++++++++++++++++++++++++++++++++++X++++++++++++++++++++++++++++++++++++++++++++++++--
09 ---------------------++++++++++++++++++++++++++++++++++++++++++++++++++X++++++++++++++++++++++++++++++++++++++++++++++++++-
10 ------------------+++++++++++++++++++++++++++++++++++++++++++++++++X++++++++++++++++++++++++++++++++++++++++++++++++++-----
11 ------------------+++++++++++++++++++++++++++++++++++++++++++++++++++X+++++++++++++++++++++++++++++++++++++++++++++++++++--
12 ---------------++++++++++++++++++++++++++++++++++++++++++++++++++X+++++++++++++++++++++++++++++++++++++++++++++++++++------
13 ----------------++++++++++++++++++++++++++++++++++++++++++++++++++X+++++++++++++++++++++++++++++++++++++++++++++++++++-----
14 ------------++++++++++++++++++++++++++++++++++++++++++++++++++X++++++++++++++++++++++++++++++++++++++++++++++++++----------
15 ------------------++++++++++++++++++++++++++++++++++++++++++++++++++X+++++++++++++++++++++++++++++++++++++++++++++++++++---
RD DQS adjustments :
BL0: Start: 0x6E Final: 0x6E
BL1: Start: 0x6E Final: 0x6E
Shmoo WR DQ
000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000011111111111111111111111
000000000011111111112222222222333333333344444444445555555555666666666677777777778888888888999999999900000000001111111111222
012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012
00 ------------+++++++++++++++++++++++++++++++++++++++++++++++X++++++++++++++++++++++++++++++++++++++++++++++++---------------
01 ----------+++++++++++++++++++++++++++++++++++++++++++++X++++++++++++++++++++++++++++++++++++++++++++++---------------------
02 ------------+++++++++++++++++++++++++++++++++++++++++++++++X+++++++++++++++++++++++++++++++++++++++++++++++----------------
03 ---+++++++++++++++++++++++++++++++++++++++++++++++X++++++++++++++++++++++++++++++++++++++++++++++++------------------------
04 ---------+++++++++++++++++++++++++++++++++++++++++++++X+++++++++++++++++++++++++++++++++++++++++++++-----------------------
05 --------+++++++++++++++++++++++++++++++++++++++++++++++X+++++++++++++++++++++++++++++++++++++++++++++++--------------------
06 -----------++++++++++++++++++++++++++++++++++++++++++++++X+++++++++++++++++++++++++++++++++++++++++++++++------------------
07 ---+++++++++++++++++++++++++++++++++++++++++++++X+++++++++++++++++++++++++++++++++++++++++++++-----------------------------
08 ---------------+++++++++++++++++++++++++++++++++++++++++++++++X+++++++++++++++++++++++++++++++++++++++++++++++-------------
09 ---------------++++++++++++++++++++++++++++++++++++++++++++++X++++++++++++++++++++++++++++++++++++++++++++++---------------
10 -----------+++++++++++++++++++++++++++++++++++++++++++++++X++++++++++++++++++++++++++++++++++++++++++++++++----------------
11 -----------+++++++++++++++++++++++++++++++++++++++++++++++X+++++++++++++++++++++++++++++++++++++++++++++++-----------------
12 -----------+++++++++++++++++++++++++++++++++++++++++++++X++++++++++++++++++++++++++++++++++++++++++++++--------------------
13 -----------+++++++++++++++++++++++++++++++++++++++++++++++X+++++++++++++++++++++++++++++++++++++++++++++++-----------------
14 ----+++++++++++++++++++++++++++++++++++++++++++++++X+++++++++++++++++++++++++++++++++++++++++++++++------------------------
15 ------------+++++++++++++++++++++++++++++++++++++++++++++++X+++++++++++++++++++++++++++++++++++++++++++++++----------------
Shmoo WR DM
WR DM
000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000011111111111111111111111
000000000011111111112222222222333333333344444444445555555555666666666677777777778888888888999999999900000000001111111111222
012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012
00 -------++++++++++++++++++++++++++++++++++++++++++++++X++++++++++++++++++++++++++++++++++++++++++++++-----------------------
01 --------++++++++++++++++++++++++++++++++++++++++++++++++X++++++++++++++++++++++++++++++++++++++++++++++++------------------
start of memsys_end
[0000000080180004] = 0x8110071f
[0000000080180010] = 0x00000009
end of memsys_end
DDR test done successfully
FFinit find magic number 0x75456e76 at address 0x100000
FFinit find magic number 0x74506c21 at address 0x140000
reading blob from 0x140000 offset 0xc len 163741
digest sha256 OK
U-Boot TPL 2019.07 (Oct 31 2023 - 03:52:39 -0400)
Board is FLD secure
$TPL: 5.04L.02@419765 $
CPU Clock: 1500MHz
IMAGE is NAND
Trying to boot from NAND
nand flash device id 0x98d39126, total size 1024MB
block size 256KB, page size 4096 bytes, spare area 216 bytes
ECC BCH-8
image from 2097152 to 315621376
brcmnand_read_buf(): Attempt to read bad nand block 760
brcmnand_read_buf(): Attempt to read bad nand block 762
brcmnand_read_buf(): Attempt to read bad nand block 768
brcmnand_read_buf(): Attempt to read bad nand block 770
brcmnand_read_buf(): Attempt to read bad nand block 772
brcmnand_read_buf(): Attempt to read bad nand block 780
brcmnand_read_buf(): Attempt to read bad nand block 782
RESET STATUS is 0x80000000
SELECTED Image 1 FIT_VOL_ID is 3
brcmnand_read_buf(): Attempt to read bad nand block 760
brcmnand_read_buf(): Attempt to read bad nand block 762
brcmnand_read_buf(): Attempt to read bad nand block 768
brcmnand_read_buf(): Attempt to read bad nand block 770
brcmnand_read_buf(): Attempt to read bad nand block 772
brcmnand_read_buf(): Attempt to read bad nand block 780
brcmnand_read_buf(): Attempt to read bad nand block 782
Found FIT format U-Boot
tpl_load_read: sector 7000000, count 3194, buf 0000000007000000
tpl_load_read: sector 7000000, count 4192, buf 0000000007000000
fit read sector 7000000, sectors=16786, dst=0000000007000000, count=16786, size=0x4192
FIT Header Authentication Successfull!
INFO: Found disabled /trust/anti-rollback node!
INFO: Found /trust/hw_state node in fit
tpl_load_read: sector 7003680, count 8028, buf 0000000000004000
## Checking hash(es) for Image atf ... sha256+ OK
tpl_load_read: sector 700b680, count 27fc80, buf 0000000001000000
## Checking hash(es) for Image uboot ... sha256+ OK
tpl_load_read: sector 76ea1c0, count c5be, buf 000000000127fc80
## Checking hash(es) for Image fdt_VERIZON-G3100 ... sha256+ OK
INFO: Creating //trust
INFO: Creating /trust/antirollback_lvl
INFO: Adding exported item node antirollback_lvl to dtb, size:4
INFO: Creating /trust/brcm_pub_key
INFO: Adding exported item node brcm_pub_key to dtb, size:256
U-Boot 2019.07 (Oct 31 2023 - 03:52:45 -0400), Build: 5.04L.02@419765
Model: VERIZON-G3100
DRAM: 512 MiB
max supported leds 32[32]
Serial LED interface found num shifters 2 [2] serial data polarity low 0
BCA LED Controller initialized
HW led 3 registered
HW led 4 registered
HW led 5 registered
HW led 6 registered
HW led 7 registered
HW led 8 registered
HW led 9 registered
HW led 10 registered
SW led 0 registered
SW led 1 registered
SW led 2 registered
SW led 11 registered
SW led 12 registered
SW led 13 registered
SW led 14 registered
SW led 15 registered
Dump Current setting of SWREGs
1.0D, reg=0x00, val=0xc690
1.0D, reg=0x01, val=0x0d06
1.0D, reg=0x02, val=0xcb12
1.0D, reg=0x03, val=0x5372
1.0D, reg=0x04, val=0x0000
1.0D, reg=0x05, val=0x0702
1.0D, reg=0x06, val=0xb000
1.0D, reg=0x07, val=0x0029
1.0D, reg=0x08, val=0x0c02
1.0D, reg=0x09, val=0x0071
1.8 , reg=0x00, val=0xc690
1.8 , reg=0x01, val=0x0d06
1.8 , reg=0x02, val=0xcb12
1.8 , reg=0x03, val=0x5370
1.8 , reg=0x04, val=0x0000
1.8 , reg=0x05, val=0x0702
1.8 , reg=0x06, val=0xb000
1.8 , reg=0x07, val=0x0029
1.8 , reg=0x08, val=0x0c02
1.8 , reg=0x09, val=0x0071
1.5 , reg=0x00, val=0xc690
1.5 , reg=0x01, val=0x0d06
1.5 , reg=0x02, val=0xcb12
1.5 , reg=0x03, val=0x5370
1.5 , reg=0x04, val=0x0000
1.5 , reg=0x05, val=0x0702
1.5 , reg=0x06, val=0xb000
1.5 , reg=0x07, val=0x0029
1.5 , reg=0x08, val=0x0c02
1.5 , reg=0x09, val=0x0071
1.0A, reg=0x00, val=0xc690
1.0A, reg=0x01, val=0x0d06
1.0A, reg=0x02, val=0xcb12
1.0A, reg=0x03, val=0x5370
1.0A, reg=0x04, val=0x0000
1.0A, reg=0x05, val=0x0702
1.0A, reg=0x06, val=0xb000
1.0A, reg=0x07, val=0x0029
1.0A, reg=0x08, val=0x0c02
1.0A, reg=0x09, val=0x0071
Take PMC out of reset
waiting for PMC finish booting
PMC rev: 3.4.1.427360 running
pmc_init:PMC using DQM mode
Chip ID: BCM68369_B1
Broadcom B53 Dual Core: 1500MHz
RDP: 1400MHz
$Uboot: 5.04L.02@419765 $
WDT: Started with servicing (80s timeout)
NAND: 1024 MiB
MMC: sdhci: 0
Loading Environment from BOOT_MAGIC... ENV_BOOT_MAGIC_LOAD
found magic at 100000
good crc
resize from 16384 to 8192
OK
In: serial0
Out: serial0
Err: serial0
Board is FLD secure
INFO: Can't find /trust/fit-aes1 node in boot DTB!
Now we are in UBOOT proper
HTTPD: ready for starting
boot_device is NAND
Net: Using MAC Address b8:f8:53:0b:1d:01
eth0: switch0
No size specified -> Using max size (7300992)
Read 7300992 bytes from volume bootfs1 to 0000000002000000
FIT Header Authentication Successfull!
Read 4 bytes from volume rootfs1 to 000000001dd40664
## Loading kernel from FIT Image at 02000000 ...
Using 'conf_lx_VERIZON-G3100' configuration
Verifying Hash Integrity ... OK
Trying 'kernel' kernel subimage
Description: 4.19 kernel
Type: Kernel Image
Compression: lzma compressed
Data Start: 0x0228c800
Data Size: 3461392 Bytes = 3.3 MiB
Architecture: AArch64
OS: Linux
Load Address: 0x00100000
Entry Point: 0x00100000
Hash algo: sha256
Hash value: 77e40836ec218fa969f9d2bd572115ed9a7ef008cc75bfec4912354ce78a6349
Verifying Hash Integrity ... sha256+ OK
## Loading fdt from FIT Image at 02000000 ...
Using 'conf_lx_VERIZON-G3100' configuration
Verifying Hash Integrity ... OK
Trying 'fdt_VERIZON-G3100' fdt subimage
Description: dtb
Type: Flat Device Tree
Compression: uncompressed
Data Start: 0x026ea1c4
Data Size: 50618 Bytes = 49.4 KiB
Architecture: AArch64
Hash algo: sha256
Hash value: c50470d2e693ebcd7dd68e42cc1de0ace24ccc30766e9c36d08c6b4462fa2e53
Verifying Hash Integrity ... sha256+ OK
Booting using the fdt blob at 0x26ea1c4
ARCADYAN: Authenticating vmlinux ...
ARCADYAN: Authenticating vmlinux pass
ARCADYAN: Decrypting kernel image ...
ARCADYAN: Decrypting kernel image done
Uncompressing Kernel Image ... OK
ERROR: reserving fdt memory region failed (addr=1b400000 size=4c00000)
Loading Device Tree to 0000000007f73000, end 0000000007fff5b9 ... OK
RSVD: not found enrty for adsl
RSVD: not found enrty for bufmem
RSVD: not found enrty for rnrmem
RSVD: Allocated for rdp1 64MB
RSVD: Allocated for rdp2 8MB
RSVD: Allocated for dhd0 11MB
RSVD: Allocated for dhd1 11MB
RSVD: Allocated for dhd2 11MB
RSVD: Total 0x06c00000 bytes CMA reserved memory @ 0x19400000
appending extra boot args to linux boot command line:
mtdparts=brcmnand.0:2097152(loader),313524224@2097152(image),8388608@315621376(misc1),1048576@324009984(misc3),709885952@325058560(data),28311552@1034944512(owl),1048576@1063256064(mtdoops),2097152@1064304640(license),2097152@1066401792(certificate),1048576@1068498944(pri
Starting kernel ...
D%G
My device is currently running firmware 3.4.0.9, which I tried to revert to any previous version. I found a reference to a “hidden” admin page to update firmware at https://192.168.1.1/#/firmware_upgrade, but none of the firmware I downloaded would work (I think due to anti rollback).
So this is where I am currently stuck. I doubt that the key generation algorithm is on the device. However, if anyone is able to make sense of the serial output that might help unlock the firmware, I would love to just have a look around for curiosity sake. I will try to periodically scrape and update the password file, I originally thought it would have more entries by now.
Next Steps:- Analyze the data set to try to reduce key space (unused characters, common words, find the wordlist?)
- Collect more complete entries for the dataset
- Try to mount file system (ubi.img) in a proper Linux environment
- Try to find older firmware
RE: Verizon Fios G3100 and E3200 Research - FiosFiend - 04-03-2025
I forgot to post the E3200 Firmware links I discovered. The single mention I found previously was for the 3.2.0.11.trapeze.bin
https://cpe-ems34.verizon.com/firmware/e3200_fw_3.1.1.17.bin
https://cpe-ems34.verizon.com/firmware/e3200_fw_3.1.1.18.bin
https://cpe-ems34.verizon.com/firmware/e3200_fw_3.2.0.1.bin
https://cpe-ems34.verizon.com/firmware/BHRx_Ext/e3200_fw_3.2.0.11.trapeze.bin
https://cpe-ems34.verizon.com/firmware/BHRx_Ext/e3200_fw_3.2.0.12.trapeze.bin
https://cpe-ems34.verizon.com/firmware/BHRx_Ext/e3200_fw_3.4.0.8.trapeze.bin
https://cpe-ems34.verizon.com/firmware/BHRx_Ext/e3200_fw_3.2.0.11.bin
https://cpe-ems34.verizon.com/firmware/BHRx_Ext/e3200_fw_3.2.0.12.bin
https://cpe-ems34.verizon.com/firmware/BHRx_Ext/e3200_fw_3.4.0.7_loader.bin
https://cpe-ems34.verizon.com/firmware/BHRx_Ext/e3200_fw_3.4.0.8_loader.bin
Code: https://cpe-ems34.verizon.com/firmware/e3200_fw_3.1.1.17.bin
https://cpe-ems34.verizon.com/firmware/e3200_fw_3.1.1.18.bin
https://cpe-ems34.verizon.com/firmware/e3200_fw_3.2.0.1.bin
https://cpe-ems34.verizon.com/firmware/BHRx_Ext/e3200_fw_3.2.0.11.trapeze.bin
https://cpe-ems34.verizon.com/firmware/BHRx_Ext/e3200_fw_3.2.0.12.trapeze.bin
https://cpe-ems34.verizon.com/firmware/BHRx_Ext/e3200_fw_3.4.0.8.trapeze.bin
https://cpe-ems34.verizon.com/firmware/BHRx_Ext/e3200_fw_3.2.0.11.bin
https://cpe-ems34.verizon.com/firmware/BHRx_Ext/e3200_fw_3.2.0.12.bin
https://cpe-ems34.verizon.com/firmware/BHRx_Ext/e3200_fw_3.4.0.7_loader.bin
https://cpe-ems34.verizon.com/firmware/BHRx_Ext/e3200_fw_3.4.0.8_loader.bin
and the G3100 for readability.
Code: https://cpe-ems34.verizon.com/firmware/g3100_fw_2.0.0.6.bin
https://cpe-ems34.verizon.com/firmware/g3100_fw_3.1.1.17.bin
https://cpe-ems34.verizon.com/firmware/g3100_fw_3.1.1.18.bin
https://cpe-ems34.verizon.com/firmware/g3100_fw_3.2.0.11.bin
https://cpe-ems34.verizon.com/firmware/BHRx/g3100_fw_3.2.0.13.bin
https://cpe-ems34.verizon.com/firmware/BHRx/g3100_fw_3.2.0.14.bin
https://cpe-ems34.verizon.com/firmware/BHRx/g3100_fw_3.2.0.15.bin
https://cpe-ems34.verizon.com/firmware/BHRx/g3100_fw_3.4.0.4_loader.bin
https://cpe-ems34.verizon.com/firmware/BHRx/g3100_fw_3.4.0.6_loader.bin
https://cpe-ems34.verizon.com/firmware/BHRx/g3100_fw_3.4.0.8_loader.bin
https://cpe-ems34.verizon.com/firmware/BHRx/g3100_fw_3.4.0.9_loader.bin
<Mirrors>
https://cpe-ems33.verizon.com/firmware/g3100_fw_3.1.1.17.bin
https://cpe-ems33.verizon.com/firmware/g3100_fw_3.2.0.15.bin
RE: Verizon Fios G3100 and E3200 Research - drsnooker - 04-04-2025
Nicely done. Not sure if this will be helpful, but PSKracker has a couple of netgear wordlists that might come in handy
https://github.com/andrewjlamarche/PSKracker
RE: Verizon Fios G3100 and E3200 Research - RealEnder - 04-07-2025
Interesting research. We've looked at these and sadly couldn't find anything, which can limit the keyspace, which is really enormous. We have a lot of uncracked Fios networks in wpa-sec. We've got only these:
Code: b8f853eb8962 Fios-6MSdq arc53dock735wry
b8f85362dec2 Fios-DMG5b palmy82out76arc
04a222f1f9da Fios-9ZfGv tag828pun44snail
b8f85337fb06 Fios-fq8ZT zoo343owl289crow
As always, the BSSID may be fake.
RE: Verizon Fios G3100 and E3200 Research - FiosFiend - 04-08-2025
Yeah I have come across the wordlists for 3-7 letter words that could be combined to create a dictionary, however as others have discovered the possible keyspace is still huge. I had a bit of time over the weekend to play with the data, and I am happy to report that I made some progress! With a little more data collection/processing I should be able to generate all of the Serial numbers based on MAC address. Without an algorithm, it isn’t super exciting... but it does allow me to at least validate the MAC and serials I collect are accurate since the characters 0 8 B all look similar in blurry photos. If we ever do discover the algorithm, the serial number could likely be part of it.
Here’s my analysis...
I noticed that there seemed to be a pattern in the last digit of the MAC address, with many ending in 0/8, or 4/C especially when grouped together by serial number. So I separated the data by MAC address using the first 3 octets (ie B8.F8.53.XX.XX.XX), and then combined the last 3 octets (ie DD.4A.98) removed the decimals (DD4A98) and converted the hex to decimal value (14502552). This gave me a numerical value for the MAC that I could plot vs the serial number. We can see there is a very strong correlation, but we can’t accurately calculate the serial number.
![[Image: attachment.php?aid=1242]](https://hashcat.net/forum/attachment.php?aid=1242)
To try to determine the relationship, I kept the serial numbers sorted in order. Then I took the hex2dec and serial number of one entry, and subtracted it from the next. I then took the (Mac difference / Serial difference). Seeing the same whole digit pop up several times gives us a clue that we’re on to something!
![[Image: attachment.php?aid=1243]](https://hashcat.net/forum/attachment.php?aid=1243)
However, there are still several entries that don’t make any sense at all. I tried to look at the serial numbers individually, but there were huge jumps that didn’t seem explainable. I fed the data to our favorite AI, and it couldn’t make much sense of it either. However, it did suggest that perhaps the digits 21 in all of the serial numbers (E302120090812958) was a date code. I investigated this a little bit, but it didn’t seem to work out. Eventually I broke the digits into smaller numbers, which then allowed me to recognize there is a date code, just in a slightly different spot! The format is 2-digit year, 2 digit month, 2 digit day starting on the 6th character (E302120090812958 = 09/08/2020). I was able to verify this because the month spot is never greater than 12, the day spot is never greater than 31 and is only 31 on months that have that many days, and the years are between 19-23. The first 5 characters in the serial always stay the same, so that leaves us with the last 5 digits as the incremental serial (E302120090812958). With this information in hand, I sorted the list by date codes, and everything starts to line up more. The number 8 that shows up is how many steps there are between MAC addresses, so if the MAC is 3C.BD.C5.42.22.50, the next address in the sequence will be 3C.BD.C5.42.22.58. Using this information, I can actually back calculate the starting MAC address for each date code if we assume each block starts @ 00000 serial. Once all of the starting blocks are calculated, we can calculate the end of the previous block by subtracting 1 step. The E3200 MACS step by 6 digits instead of 8, some of the earlier g3100 jump by 11. Several of the ending blocks stop on seemingly non-random numbers, which is another clue that we're on the right track. I have gone though and done this for the 3C.BD.C5 MACs I have on hand, and ended up covering most of the address space. I was also able to identify and correct several places where the MAC or Serial was slightly off in my original data set (and validated using the saved photos)
![[Image: attachment.php?aid=1244]](https://hashcat.net/forum/attachment.php?aid=1244)
With this bit of success, I created a python script to calculate the serial based on a given MAC. There are still a few “UNKNOWN” blocks when there seems to be a large gap of MACs between blocks. I will work on adding the other MAC prefixes, so that we can enumerate all possible devices. I also stopped on serial 00001 earlier instead of 00000. I am still not sure which is correct honestly. Eventually I will correct them all to 00000 add code to detect these edges and give you both Serials. If you test the code, please report back. If you want to give me a MAC address and have me try to guess the serial I can. Otherwise, I have another batch of recently scraped images that I still need to validate and add to the database. I will be testing these on the script. My next post should have an updated data set!
Code: #!/usr/bin/env python3
# -*- coding: utf-8 -*-
import re
from datetime import datetime
# Your MAC ranges data
mac_data = """
3C.BD.C5.00.00.00:3C.BD.C5.01.F5.6A,G3100,8,Unknown
3C.BD.C5.01.F5.70:3C.BD.C5.09.3B.F8,G3100,8,121011516659
3C.BD.C5.09.3C.00:3C.BD.C5.0C.30.38,G3100,8,121030100001
3C.BD.C5.0C.30.40:3C.BD.C5.16.4A.C8,G3100,8,121021700001
3C.BD.C5.16.4A.D0:3C.BD.C5.1C.C1.58,G3100,8,121031200001
3C.BD.C5.1C.C1.5E:3C.BD.C5.22.C3.EA,G3100,8,Unknown
3C.BD.C5.22.C3.F0:3C.BD.C5.2B.5B.E8,G3100,8,121033100001
3C.BD.C5.2B.5B.F0:3C.BD.C5.31.1E.60,G3100,8,121041400001
3C.BD.C5.31.1E.66:3C.BD.C5.37.5C.92,G3100,8,Unknown
3C.BD.C5.37.5C.98:3C.BD.C5.3D.D3.40,G3100,8,121051800001
3C.BD.C5.3D.D3.48:3C.BD.C5.42.22.58,G3100,8,121060700001
3C.BD.C5.42.22.60:3C.BD.C5.46.3E.C4,G3100,8,121062200000
3C.BD.C5.46.3E.CC:3C.BD.C5.47.F6.C4,G3100,8,121071300000
3C.BD.C5.47.F6.CC:3C.BD.C5.49.AE.C4,G3100,8,121072100000
3C.BD.C5.49.AE.CC:3C.BD.C5.50.05.44,G3100,8,121070100000
3C.BD.C5.50.05.4C:3C.BD.C5.56.95.D4,G3100,8,121072000000
3C.BD.C5.56.95.DA:3C.BD.C5.60.3B.72,E3200,6,121072000000
3C.BD.C5.60.3B.74:3C.BD.C5.69.B8.CC,G3100,8,121081100000
3C.BD.C5.69.B8.D4:3C.BD.C5.71.07.FC,G3100,8,121082000000
3C.BD.C5.71.08.00:3C.BD.C5.76.8D.C8,G3100,8,121082600000
3C.BD.C5.76.8D.CC:3C.BD.C5.7D.27.9C,G3100,8,121090800000
3C.BD.C5.7D.27.A2:3C.BD.C5.85.4C.98,G3100,8,Unknown
3C.BD.C5.83.03.D4:3C.BD.C5.85.4C.9E,E3200,6,121091600001
3C.BD.C5.85.4C.A4:3C.BD.C5.8C.CB.C6,E3200,6,Unknown
3C.BD.C5.8C.CB.CC:3C.BD.C5.93.FF.8C,G3100,8,121101500000
3C.BD.C5.93.FF.92:BD.C5.93.9B.67.6C,G3100,8,Unknown
3C.BD.C5.9B.67.72:3C.BD.C5.A1.71.B2,G3100,8,121110500000
3C.BD.C5.A1.71.BA:3C.BD.C5.A3.FE.1C,E3200,6,121110500001
3C.BD.C5.A3.FE.22:3C.BD.C5.AD.16.64,E3200,6,Unknown
3C.BD.C5.AD.16.6A:3C.BD.C5.AE.AE.2E,E3200,6,122010100001
3C.BD.C5.AE.AE.34:3C.BD.C5.B4.2D.5E,E3200,6,121122100000
3C.BD.C5.B4.2D.62:3C.BD.C5.B5.09.9A,G3100,8,122021400000
3C.BD.C5.B5.09.A2:3C.BD.C5.B5.E5.9A,G3100,8,122031000000
3C.BD.C5.B5.E5.A2:3C.BD.C5.B8.0B.9A,G3100,8,122031100000
3C.BD.C5.B8.0B.A2:3C.BD.B8.C1.ED.A2,G3100,8,122031500000
3C.BD.C5.C1.ED.A4:3C.BD.C5.C2.40.1E,E3200,6,122031300000
3C.BD.C5.C2.40.24:3C.BD.C5.C2.89.E0,E3200,6,122031400000
3C.BD.C5.C2.89.E6:3C.BD.C5.CD.A1.1A,E3200,6,Unknown
3C.BD.C5.CD.A1.20:3C.BD.C5.CF.39.86,E3200,6,122052200000
3C.BD.C5.CF.39.8C:3C.BD.C5.D2.C8.06,E3200,6,122091400000
3C.BD.C5.D2.C8.0C:3C.BD.C5.D3.41.F2,E3200,6,122091500000
3C.BD.C5.D3.41.F8:3C.BD.C5.DA.E1.12,E3200,6,Unknown
3C.BD.C5.DA.E1.18:3C.BD.C5.DD.EE.80,E3200,6,122110900000
3C.BD.C5.DD.EE.86:3C.BD.C5.E5.83.8A,E3200,6,Unknown
3C.BD.C5.E5.83.90:3C.BD.C5.E8.44.B0,E3200,6,123011000000
3C.BD.C5.E8.34.96:3C.BD.C5.E8.44.B6,E3200,6,123030400000
3C.BD.C5.E8.44.BC:3C.BD.C5.F1.11.4A,E3200,6,Unknown
3C.BD.C5.F1.11.50:3C.BD.C5.F1.E1.E2,E3200,6,123042100000
3C.BD.C5.F1.E1.E8:3C.BD.C5.F4.B3.C2,E3200,6,123042600000
3C.BD.C5.F4.B3.C8:3C.BD.C5.F8.7A.CA,E3200,6,123052000000
3C.BD.C5.F8.7A.D0:3C.BD.C5.F9.F9.FE,E3200,6,123080600000
""".strip().splitlines()
# Helper to convert MAC string to integer
def mac_to_int(mac):
return int(mac.replace(".", ""), 16)
# Helper to extract the last 3 octets as integer
def last_3_octets_to_int(mac):
return int(mac.replace(".", "")[-6:], 16)
def format_date_from_serial(serial):
if serial.lower() == 'unknown' or not serial.isdigit():
return "Unknown"
try:
year = int(serial[1:3])
month = int(serial[3:5])
day = int(serial[5:7])
# Normalize year
year += 2000 if year < 100 else 0
date = datetime(year, month, day)
return date.strftime("%m-%d-%y")
except Exception:
return "Invalid"
def calculate_serial(mac_input):
mac_input_clean = mac_input.upper().replace(":", ".").replace("-", ".")
mac_value = mac_to_int(mac_input_clean)
mac_last = last_3_octets_to_int(mac_input_clean)
for line in mac_data:
mac_range, model, step_str, serial_start = line.split(",")
mac_start_str, mac_end_str = mac_range.split(":")
step = int(step_str)
mac_start_val = mac_to_int(mac_start_str)
mac_end_val = mac_to_int(mac_end_str)
if mac_start_val <= mac_value <= mac_end_val and serial_start != "Unknown":
mac_start_last = last_3_octets_to_int(mac_start_str)
delta = (mac_last - mac_start_last) // step
calculated_serial = str(int(serial_start) + delta).zfill(12)
date_str = format_date_from_serial(calculated_serial)
return {
"Given MAC": mac_input_clean,
"Start MAC": mac_start_str,
"Calculated Serial": calculated_serial,
"Model": model,
"Date": date_str
}
return {"error": "MAC not found in any known range or serial unknown."}
# Main loop
if __name__ == "__main__":
user_mac = input("Enter a MAC address (e.g., 3C:BD:C5:09:3C:12): ")
result = calculate_serial(user_mac)
if "error" in result:
print(result["error"])
else:
for k, v in result.items():
print(f"{k}: {v}")
RE: Verizon Fios G3100 and E3200 Research - FiosFiend - 04-08-2025
I wanted to mention that I know the posted data set and python code both contain minor errors.
For the data set: I will be posting a new data set with revalidated data, additional columns, and new entries.
For the python code: I realized since the info in the date blocks is the same, we can output a lot of details about a specific device, including the correct keyspace for a dictionary attack based on MAC. I will also be sharing the various scripts that I’ve discussed once I clean them up a little bit.
For now if anyone can help with the firmware it would be greatly appreciated. Here is a bit more info in that regard.
I found a nice teardown of the device here: https://fccid.io/RAXG3100/Internal-Photos/Internal-Photos-4330446.pdf
Here we see the CPU chip is a BROADCOM BCM43684KRFBG. (product page)
![[Image: attachment.php?aid=1245]](https://hashcat.net/forum/attachment.php?aid=1245)
From the UART output posted previously we know that it is running AArch64 Linux. Is the sha256 hash value just a check, or something that can be cracked?
Code: ## Loading kernel from FIT Image at 02000000 ...
Using 'conf_lx_VERIZON-G3100' configuration
Verifying Hash Integrity ... OK
Trying 'kernel' kernel subimage
Description: 4.19 kernel
Type: Kernel Image
Compression: lzma compressed
Data Start: 0x0228c800
Data Size: 3461392 Bytes = 3.3 MiB
Architecture: AArch64
OS: Linux
Load Address: 0x00100000
Entry Point: 0x00100000
Hash algo: sha256
Hash value: 77e40836ec218fa969f9d2bd572115ed9a7ef008cc75bfec4912354ce78a6349
Verifying Hash Integrity ... sha256+ OK
The memory is TOSHIBA TH58NVG3S0HTA10 (data sheet). It looks like there test are pads to access the memory. Figuring out the layout, and dump directly from the chip is probably a bit above my skillset currently.
![[Image: attachment.php?aid=1246]](https://hashcat.net/forum/attachment.php?aid=1246)
Part of the UART output posted earlier:
Code: MEMC DRAM profile (memc_dram_profile_struct) values:
dram_type = DDR3
====================================================
PART values:
part_speed_grade = 1600 CL11
part_size_Mbits = 4096 (DRAM size in MegaBits)
part_row_bits = 15 (number of row bits)
part_col_bits = 10 (number of column bits)
part_ba_bits = 3 (number of bank bits)
part_width_bits = 16 (DRAM width in bits)
NUMER OF PARTS:
part_num = 1 (Number of parts)
TOTAL values:
total_size_Mbits = 4096 (DRAM size in MegaBits)
total_cs_bits = 0 (number of cs bits, for dual_rank mode)
total_width_bits = 16 (DRAM width in bits)
total_burst_bytes = 16 (Number of bytes per DRAM access)
total_max_byte_addr = 0x1fffffff (Maximum/last DRAM byte address)
(Number of bits in total_max_byte_addr is 29)
(i.e. total_max_byte_addr goes from bit 0 to bit 28)
There are 2 boards inside the device. Each has an obvious UART, however I was only able to get output from 1. Unfortunately I don’t remember the pin layout, but I used a multimeter to find (+) and (-). I think RX/TX were right my first try, otherwise swap them. There is also possibly a JTAG connector, but I don’t have much experience with that.
Bad UART: Board without COAX connector.
![[Image: attachment.php?aid=1248]](https://hashcat.net/forum/attachment.php?aid=1248)
Good UART: Board with the COAX connector
![[Image: attachment.php?aid=1247]](https://hashcat.net/forum/attachment.php?aid=1247)
There are several other chips on the boards such as, ZM5101A-CME3, Broadcom B50212E, ERF32, SEC 907(?), MXL3711 which I know very little about.
RE: Verizon Fios G3100 and E3200 Research - textile302 - 04-10-2025
Awesome work but it seems the firmware links are now not respond. You don't by chance have a different source for them do you?
RE: Verizon Fios G3100 and E3200 Research - FiosFiend - 04-11-2025
(04-10-2025, 08:44 PM)textile302 Wrote: Awesome work but it seems the firmware links are now not respond. You don't by chance have a different source for them do you?
Thanks for your interest in this! Unfortunately I think you need to be on Fios network for the download links to work. However I have already downloaded all of the linked firmware. I just sent you a DM with the link.
Stay tuned... I will post an updated data set and python code sometime this weekend.
RE: Verizon Fios G3100 and E3200 Research - FiosFiend - 04-13-2025
Hey all, it’s the weekend and here is that Python script that I promised! I worked on calculating the Start/End of the known Date Code blocks in the data set. I had a script to help with the actual calculations, but I did each one individually to oversee how everything was lining up.
Here’s the code I ended up with, I have named it Fios-F1nDr as a play on their SSID 😀
Code: import pandas as pd
import os
from tabulate import tabulate
def parse_ref_data(ref_data_lines):
ref_data = []
for line in ref_data_lines:
parts = line.split(',')
# Ensure parts has enough elements
if len(parts) < 11:
print(f"Skipping line due to insufficient data: {line}")
continue
ref_data.append({
'MAC_start': parts[0],
'MAC_end': parts[1],
'Serial_start': parts[2],
'Serial_end': parts[3],
'M2HR': parts[4] if parts[4] else "Unknown",
'W_format': int(parts[5]) if parts[5].isdigit() else None,
'W_len': int(parts[6]) if parts[6].isdigit() else None,
'A_format': int(parts[7]) if parts[7].isdigit() else None,
'A_len': int(parts[8]) if parts[8].isdigit() else None,
'Date': parts[9] if len(parts) > 9 else '',
'HW': parts[10] if len(parts) > 10 else '',
'Model': parts[11] if len(parts) > 11 else ''
})
return ref_data
def mac_to_hex(mac):
# Strip separators and convert to lowercase
mac = mac.replace(':', '').replace('.', '').lower()
return int(mac[-6:], 16)
def process_single_mac(mac, ref_data):
# Strip separators and convert to lowercase
mac_cleaned = mac.replace(':', '').replace('.', '').replace('-', '').lower()
# Check for valid prefix
valid_prefixes = ["04a222", "b8f853", "3cbdc5", "dcf51b"]
if mac_cleaned[:6] not in valid_prefixes:
return {"Model": "Unknown Device", "Calculated Serial": "Unknown Device"}
# Skip calculation for DCF51B prefix
if mac_cleaned[:6] == "dcf51b":
return {"Calculated Serial": "Not enough data", "Model": "E3200", "HW": 1104,
"W_format": 2, "W_len": "15", "A_format": 2, "A_len": 9}
# Find the relevant block
for block in ref_data:
mac_start_cleaned = block['MAC_start'].replace(':', '').replace('.', '').replace('-', '').lower()
mac_end_cleaned = block['MAC_end'].replace(':', '').replace('.', '').replace('-', '').lower()
# Compare cleaned MAC addresses
if mac_start_cleaned <= mac_cleaned <= mac_end_cleaned:
if block['Serial_start'] == "Unknown Block":
return {"Calculated Serial": "Unknown Block", "Model": block['Model'], "Hardware": block['HW'],
"W_format": block['W_format'], "W_len": block['W_len'], "A_format": block['A_format'], "A_len": block['A_len']}
# Skip calculation if M2HR is unknown
if block['M2HR'] == "Unknown":
return {"Calculated Serial": "Unknown", "M2HR": "Unknown", "Model": block['Model'], "HW": block['HW'],
"W_format": block['W_format'], "W_len": block['W_len'], "A_format": block['A_format'], "A_len": block['A_len']}
# Calculate Serial
serial_prefix = block['Serial_start'][0]
serial_start_cleaned = block['Serial_start'][1:]
mac_dec = mac_to_hex(mac)
mac_start_dec = mac_to_hex(block['MAC_start'])
serial_difference = (mac_dec - mac_start_dec) / int(block['M2HR'])
calculated_serial = serial_prefix + str(int(serial_start_cleaned) + serial_difference)
calculated_serial = calculated_serial[:16]
return {"MAC_start": block['MAC_start'], "MAC_end": block['MAC_end'], "M2HR": block['M2HR'], "Calculated Serial": calculated_serial,
"W_format": block['W_format'], "W_len": block['W_len'], "A_format": block['A_format'], "A_len": block['A_len'],
"Model": block['Model'], "Date": block['Date'], "HW": block['HW']}
return {"Model": "Unknown Device", "Calculated Serial": "Unknown Device"}
def process_csv_file(file_path, ref_data, save_location):
# Read the CSV file containing MAC addresses
df = pd.read_csv(file_path)
# Define the column titles for the output CSV
columns = ["MAC_input", "MAC_start", "MAC_end", "M2HR", "Calculated Serial", "W_format", "W_len", "A_format", "A_len", "Model", "Date Code (YYMMDD)", "HW"]
# Prepare a list to hold results
results = []
# Process each MAC address
for mac in df:
result = process_single_mac(mac.strip(), ref_data) # Ensure whitespace is stripped
result['MAC'] = mac # Include the original MAC address
# Format W_len and A_len using format_description
W_format = format_description(result.get("W_format", ""), is_wifi=True)
A_format = format_description(result.get("A_format", ""), is_wifi=False)
# Append the values in the order of the defined columns
results.append([
result.get("MAC", ""),
result.get("MAC_start", ""),
result.get("MAC_end", ""),
result.get("M2HR", ""),
result.get("Calculated Serial", ""),
W_format,
result.get("W_len", ""),
A_format,
result.get("A_len", ""),
result.get("Model", ""),
result.get("Date", ""),
result.get("HW", "")
])
# Convert results to DataFrame
results_df = pd.DataFrame(results, columns=columns)
# Save the DataFrame to a CSV file
results_df.to_csv(save_location, index=False)
print(str(len(results_df)) + " MACs proccessed, saved to " + save_location)
def format_description(format_type, is_wifi=True):
if is_wifi:
return "wnwnw" if format_type == 1 else "w?-w?-w? " if format_type == 2 else ""
else:
return "wnw" if format_type == 1 else "<A-Z><0-9>" if format_type == 2 else ""
def print_formatted_table(result):
print(" Fios-F1NdR")
# Organize the data into a table
table_data = [
["MAC Input", result.get("MAC", "")],
["MAC Block Start", result.get("MAC_start", "")],
["MAC Block End", result.get("MAC_end", "")],
["MAC 2 Hex Ratio", result.get("M2HR", "")],
["Calculated Serial", result.get("Calculated Serial", "")],
["Keyspace", "w = <word> n = <number>\n? = single digit at end of random word"],
["WiFi Pass Format", format_description(result.get("W_format", ""), is_wifi=True)],
["WiFi Pass Length", result.get("W_len", "")],
["Admin Pass Format", format_description(result.get("A_format", ""), is_wifi=False)],
["Admin Pass Length", result.get("A_len", "")],
["Model Type", result.get("Model", "")],
["Date Code (YYMMDD)", result.get("Date", "")],
["Hardware", result.get("HW", "")]
]
formatted_table = tabulate(table_data, tablefmt="grid")
print(formatted_table)
def main():
ref_data_lines = [
"04.A2.22.00.00.00,04.A2.22.AE.B8.7E,0,0,Unknown,1,0,1,0,0,0,Unknown",
"04.A2.22.AE.B8.89,04.A2.22.BA.30.A2,G401119042900000,G401119042968331,11,1,16,1,16,190429,1102,G3100",
"04.A2.22.BA.30.A6,04.A2.22.C3.3A.BB,G401119061100000,G401119061153855,11,1,16,1,16,190611,1103,G3100",
"04.A2.22.C3.3A.C6,04.A2.22.CB.A8.3C,G401119061800000,G401119061850210,11,1,16,1,16,190618,1103,G3100",
"04.A2.22.CB.5B.F0,04.A2.22.CB.5B.F2,E301119062000000,0,Unknown,1,16,1,16,190620,1102,E3200",
"04.A2.22.CB.E9.6C,04.A2.22.DB.74.3E,G401119062600000,G40111906292598,11,1,16,1,16,190626,1103,G3100",
"04.A2.22.D3.FF.3A,04.A2.22.DC.D2.DE,G401119071600000,G401119071652588,11,1,16,1,16,190716,1103,G3100",
"04.A2.22.DC.D2.E0,04.A2.22.DC.D2.E2,E301119072900000,0,Unknown,1,16,1,16,190729,1102,E3200",
"04.A2.22.DF.45.32,04.A2.22.DF.45.34,E301119073010000,0,Unknown,1,16,1,16,190730,1102,E3200",
"04.A2.22.DF.DB.E0,04.A2.22.DF.DB.E2,E301119073000000,0,Unknown,1,16,1,16,190730,1102,E3200",
"04.A2.22.E1.1D.12,04.A2.22.EA.27.27,G401119081000000,G401119081053855,11,1,16,1,16,190810,1103,G3100",
"04.A2.22.E2.B5.72,04.A2.22.E5.5E.A1,G401119073100000,G401119073115853,11,1,16,1,16,190731,1103,G3100",
"04.A2.22.E5.5E.A2,04.A2.22.F3.31.E2,G401119081300000,G401119081382368,11,1,16,1,16,190813,1103,G3100",
"04.A2.22.F3.31.E2,04.A2.22.F8.0B.14,G401119082300000,G401119082328886,11,1,16,1,16,190823,1103,G3100",
"04.A2.22.F8.0B.1F,04.A2.22.F8.3E.DB,G401119081300000,G401119081396619,0.000115284648277019,1,16,1,16,190813,1103,G3100",
"04.A2.22.F8.3E.DC,04.A2.22.FA.2B.90,0,0,Unknown,1,0,1,0,0,0,Unknown",
"04.A2.22.FA.2B.9A,04.A2.22.FB.F4.BF,G401119092000000,G401119092010639,11,1,16,1,16,190920,1103,G3100",
"04.A2.22.FB.F4.CA,04.A2.22.FF.FF.FF,0,0,Unknown,1,0,1,0,0,0,Unknown",
"B8.F8.53.00.00.00,B8.F8.53.02.AD.9B,0,0,Unknown,1,0,,0,0,0,Unknown",
"B8.F8.53.02.8D.41,B8.F8.53.05.93.61,G401119092620000,G401119092638016,11,1,16,1,16,190926,1103,G3100",
"B8.F8.53.05.93.61,B8.F8.53.07.27.6A,G401119101100000,G401119101109403,11,1,16,1,16,191011,1103,G3100",
"B8.F8.53.07.27.75,B8.F8.53.08.BF.CA,G401119101400000,G401119101409503,11,1,16,1,16,191014,1103,G3100",
"B8.F8.53.08.BF.D5,B8.F8.53.09.CF.B2,G401119101600000,G401119101606327,11,1,16,1,16,191016,1103,G3100",
"B8.F8.53.09.D0.15,B8.F8.53.0A.B2.DF,G401119101700000,G401119101705278,11,1,16,1,16,191017,1103,G3100",
"B8.F8.53.0A.B2.D6,B8.F8.53.0A.E0.54,0,0,Unknown,1,0,1,0,0,0,Unknown",
"B8.F8.53.0A.E0.55,B8.F8.53.0B.49.17,G401119101800000,G401119101802438,11,1,16,1,16,191018,1103,G3100",
"B8.F8.53.0B.49.0E,B8.F8.53.1C.67.5C,0,0,Unknown,1,0,1,0,0,0,Unknown",
"B8.F8.53.1C.67.5D,B8.F8.53.20.20.3D,G401119111200000,G401119111222176,11,1,16,1,16,191112,1103,G3100",
"B8.F8.53.20.20.3D,B8.F8.53.24.7C.D3,G401119110800000,G401119110825986,11,1,16,1,16,191108,1104,G3100",
"B8.F8.53.25.5A.AF,B8.F8.53.25.5A.BB,E301119111100000,0,Unknown,1,16,1,16,191111,1102,E3200",
"B8.F8.53.25.C1.09,B8.F8.53.28.DC.42,G401119111500000,G401119111518507,11,1,16,1,16,191115,1103,G3100",
"B8.F8.53.28.DC.49,B8.F8.53.2C.FC.75,G401119120200000,G401119120224580,11,1,16,1,16,191202,1103,G3100",
"B8.F8.53.2C.FC.75,B8.F8.53.2F.1D.C6,G401119120500000,G401119120512691,11,1,16,1,16,191205,1103,G3100",
"B8.F8.53.2F.1D.CD,B8.F8.53.34.F7.22,G401119120700000,G401119120734848,11,1,16,1,16,191207,1103,G3100",
"B8.F8.53.34.F7.2D,B8.F8.53.35.B1.B4,G401119121700000,G401119121704341,11,1,16,1,16,191217,1103,G3100",
"B8.F8.53.35.B1.BD,B8.F8.53.3B.0B.27,G401119120900000,G401119120931870,11,1,16,1,16,191209,1103,G3100",
"B8.F8.53.3B.0B.31,B8.F8.53.3C.A3.86,G401120010700000,G401120010709503,11,1,16,1,16,200107,1103,G3100",
"B8.F8.53.3C.A3.8B,B8.F8.53.3E.3B.EB,G401120010900000,G401120010909504,11,1,16,1,16,200109,1103,G3100",
"B8.F8.53.3E.3B.F1,B8.F8.53.40.1F.62,G401120011000000,G401120011011251,11,1,16,1,16,200110,1103,G3100",
"B8.F8.53.40.1F.65,B8.F8.53.43.05.09,G401120011300000,G401120011317260,11,1,16,1,16,200113,1103,G3100",
"B8.F8.53.43.05.11,B8.F8.53.44.90.98,G401120011600000,G401120011609205,11,1,16,1,16,200116,1103,G3100",
"B8.F8.53.44.90.9F,B8.F8.53.4C.AE.CE,G401120010200000,G401120010248365,11,1,16,1,16,200102,1103,G3100",
"B8.F8.53.4C.AE.D6,B8.F8.53.51.F0.93,G402120021000000,0,Unknown,1,16,1,16,200210,1104,G3100",
"B8.F8.53.51.B9.01,B8.F8.53.51.F7.F2,G402120022400000,0,Unknown,1,16,1,16,200224,1104,G3100",
"B8.F8.53.52.19.01,B8.F8.53.52.9E.82,G402120022500000,0,Unknown,1,16,1,16,200225,1104,G3100",
"B8.F8.53.52.E2.01,B8.F8.53.52.F7.12,G402120022600000,0,Unknown,1,16,1,16,200226,1104,G3100",
"B8.F8.53.54.6E.01,B8.F8.53.54.B6.FA,G402120022900000,0,Unknown,1,16,1,16,200229,1104,G3100",
"B8.F8.53.55.34.01,B8.F8.53.55.58.52,G402120030300000,0,Unknown,1,16,1,16,200303,1104,G3100",
"B8.F8.53.57.8C.41,B8.F8.53.57.D8.C2,G402120031000000,0,Unknown,1,15,1,16,200310,1104,G3100",
"B8.F8.53.59.7B.41,B8.F8.53.59.87.62,G402120031300000,0,Unknown,1,16,1,16,200313,1104,G3100",
"B8.F8.53.5A.41.41,B8.F8.53.5A.8A.C0,G402120031400000,0,Unknown,1,16,1,16,200314,1004,G3100",
"B8.F8.53.5B.CD.41,B8.F8.53.5F.4B.89,G402120031800000,G402120031828617,8,1,15,1,16,200318,1104,G3100",
"B8.F8.53.5F.4B.90,B8.F8.53.60.11.88,G402120040800000,G402120040806335,8,1,15,1,16,200408,1104,G3100",
"B8.F8.53.60.11.90,B8.F8.53.62.00.88,G402120040900000,G402120040915839,8,1,15,1,16,200409,1104,G3100",
"B8.F8.53.62.00.90,B8.F8.53.62.C6.88,G402120041200000,G402120041206335,8,1,15,1,16,200412,1104,G3100",
"B8.F8.53.62.C6.90,B8.F8.53.67.0D.C8,G402120032500000,G402120032535047,8,1,15,1,16,200325,1104,G3100",
"B8.F8.53.67.0D.D0,B8.F8.53.67.D3.C8,G402120050600000,G402120050606336,8,1,15,1,16,200506,1104,G3100",
"B8.F8.53.67.D3.D0,B8.F8.53.69.5F.C8,G402120050800000,G402120050812671,8,1,15,1,16,200508,1104,G3100",
"B8.F8.53.68.99.D0,B8.F8.53.68.B8.B1,G402120050900000,G402120050900989,8,1,15,1,16,200509,1104,G3100",
"B8.F8.53.69.5F.D0,B8.F8.53.6D.80.88,G402120051100000,G402120051133816,8,1,15,1,16,200511,1104,G3100",
"B8.F8.53.6D.80.90,B8.F8.53.70.35.88,G402120060600000,G402120060622176,8,1,15,1,16,200606,1104,G3100",
"B8.F8.53.70.35.90,B8.F8.53.72.0F.59,G402120052600000,G402120052634649,8,1,15,1,16,200526,1104,G3100",
"B8.F8.53.73.AA.58,B8.F8.53.73.B9.F9,G402120070200000,G402120070200501,8,1,15,1,16,200702,1104,G3100",
"B8.F8.53.74.70.58,B8.F8.53.75.36.50,G402120070300000,G402120070306335,8,1,15,1,16,200703,1104,G3100",
"B8.F8.53.75.36.58,B8.F8.53.77.52.70,G402120070500000,G402120070517284,8,1,15,1,16,200705,1104,G3100",
"B8.F8.53.77.52.78,B8.F8.53.7D.EB.B0,G402120062600000,G402120062654056,8,1,15,1,16,200626,1104,G3100",
"B8.F8.53.7D.EB.B8,B8.F8.53.7F.14.B0,G402120072300000,G402120072309503,8,1,15,1,16,200723,1104,G3100",
"B8.F8.53.7F.14.B8,B8.F8.53.85.C5.38,G402120071800000,G402120071854800,8,1,15,1,16,200718,1104,G3100",
"B8.F8.53.85.C5.40,B8.F8.53.8B.AB.A8,G402120081100000,G402120081148333,8,1,15,1,16,200811,1104,G3100",
"B8.F8.53.8B.AB.B0,B8.F8.53.95.FB.A8,G402120081200000,G402120081284479,8,1,15,1,16,200812,1104,G3100",
"B8.F8.53.95.FB.B0,B8.F8.53.9E.AF.28,G402120082000000,G402120082071279,8,1,15,1,16,200820,1104,G3100",
"B8.F8.53.9E.AF.32,B8.F8.53.A0.F4.30,E302120082400000,E302120082424789,6,1,15,1,16,200824,1103,E3200",
"B8.F8.53.A0.F4.34,B8.F8.53.A1.62.2C,G402120082800000,G402120082803519,8,1,15,1,16,200828,1104,G3100",
"B8.F8.53.A1.62.34,B8.F8.53.AA.85.1C,G402120083000000,G402120083074845,8,1,15,1,16,200830,1104,G3100",
"B8.F8.53.AA.85.1E,B8.F8.53.AD.F8.DA,E302120090800000,E302120090837706,6,1,15,1,16,200908,1103,E3200",
"B8.F8.53.AD.F8.DC,B8.F8.53.B6.85.24,G402120091500000,G402120091570025,8,1,15,1,16,200915,1104,G3100",
"B8.F8.53.B6.85.26,B8.F8.53.B7.01.8E,E302120091500000,E302120091505308,6,1,15,1,16,200915,1103,E3200",
"B8.F8.53.B7.01.8F,B8.F8.53.B7.98.C3,0,0,Unknown,1,0,1,0,0,0,Unknown",
"B8.F8.53.B7.98.C4,B8.F8.53.B8.06.BC,G402120101500000,G402120101503519,8,1,15,1,16,201015,1104,G3100",
"B8.F8.53.B8.06.C4,B8.F8.53.BB.08.BC,G402120101600000,G402120101624639,8,1,15,1,16,201016,1104,G3100",
"B8.F8.53.BB.08.C4,B8.F8.53.BB.76.BC,G402120101800000,G402120101803519,8,1,15,1,16,201018,1104,G3100",
"B8.F8.53.BB.76.C4,B8.F8.53.C0.9E.BC,G402120101900000,G402120101942240,8,1,15,1,16,201019,1104,G3100",
"B8.F8.53.C0.9E.C4,B8.F8.53.C2.56.C4,G402120102400000,G402120102414080,8,1,15,1,16,201024,1104,G3100",
"B8.F8.53.C2.56.C4,B8.F8.53.C5.D1.1C,G402120102500000,G402120102528491,8,1,15,1,16,201025,1104,G3100",
"B8.F8.53.C5.D1.20,B8.F8.53.CD.91.D0,G402120100700000,G402120100763510,8,1,15,1,16,201007,1104,G3100",
"B8.F8.53.CD.91.D2,B8.F8.53.CE.C3.5A,E302120100700000,0,6,1,15,1,16,201007,1103,E3200",
"B8.F8.53.CE.C3.60,B8.F8.53.B7.98.BE,0,0,Unknown,1,0,1,0,0,0,Unknown",
"B8.F8.53.CE.D4.C8,B8.F8.53.D3.58.68,G402120101300000,G402120101336980,8,1,15,1,16,201013,1104,G3100",
"B8.F8.53.D3.58.6A,B8.F8.53.D5.EC.64,E302120101500000,E302120101528159,6,1,15,1,16,201015,1103,E3200",
"B8.F8.53.D5.EC.68,B8.F8.53.D7.36.60,G402120111200000,G402120111210559,8,1,15,1,16,201112,1104,G3100",
"B8.F8.53.D7.36.68,B8.F8.53.DA.38.60,G402120111300000,G402120111324640,8,1,15,1,16,201113,1104,G3100",
"B8.F8.53.DA.38.68,B8.F8.53.DC.01.D0,G402120111700000,G402120111714637,8,1,15,1,16,201117,1104,G3100",
"B8.F8.53.DC.01.D2,B8.F8.53.DC.6F.CA,E302120111300000,E302120111304693,6,1,15,1,16,201113,1103,E3200",
"B8.F8.53.DC.6F.D0,B8.F8.53.E3.C6.D8,G402120111300000,G402120111360129,8,1,15,1,16,201113,1104,G3100",
"B8.F8.53.E3.C6.E0,B8.F8.53.EB.14.D8,G402120120200000,G402120120259839,8,1,15,1,16,201202,1104,G3100",
"B8.F8.53.EB.14.E0,B8.F8.53.F3.08.C8,G402120121000000,G402120121065150,8,1,15,1,16,201210,1104,G3100",
"B8.F8.53.F3.08.D0,B8.F8.53.F8.30.C8,G402120122300000,G402120122342240,8,1,15,1,16,201223,1104,G3100",
"B8.F8.53.F8.30.D0,B8.F8.53.FA.C4.C8,G402121011800000,G402121011821120,8,1,15,1,16,210118,1104,G3100",
"B8.F8.53.FA.C4.D0,B8.F8.53.FF.BF.F8,G402121010600000,G402121010640805,8,1,15,1,16,210106,1104,G3100",
"B8.F8.53.FF.BF.F9,B8.F8.53.FF.FF.FF,0,0,Unknown,1,0,1,0,0,0,Unknown",
"3C.BD.C5.00.00.00,3C.BD.C5.01.25.57,0,0,Unknown,1,0,1,0,0,0,Unknown",
"3C.BD.C5.01.25.58,3C.BD.C5.01.F5.78,G402121011510000,G402121011516660,8,1,15,1,16,210115,1104,G3100",
"3C.BD.C5.09.3B.F8,3C.BD.C5.0B.B4.78,G402121030100000,G402121030120240,8,1,15,1,16,210301,1104,G3100",
"3C.BD.C5.0B.B4.7A,3C.BD.C5.0B.BC.FD,E302121030300000,E302121030300364,6,1,15,1,16,210303,1103,E3200",
"3C.BD.C5.0C.30.38,3C.BD.C5.16.4A.C0,G402121021700000,G402121021782769,8,1,15,1,16,210217,1104,G3100",
"3C.BD.C5.16.4A.C8,3C.BD.C5.22.55.E0,G402121031200000,G402121031298659,8,1,15,1,16,210312,1104,G3100",
"3C.BD.C5.1E.E5.EA,3C.BD.C5.22.55.E6,E302121031200000,E302121031237546,6,1,15,1,16,210312,1103,E3200",
"3C.BD.C5.22.55.E8,3C.Bd.C5.2B.5B.E0,G402121033100000,G402121033173919,8,1,15,1,16,210331,1104,G3100",
"3C.BD.C5.2B.5B.E8,3C.BD.C5.31.1E.68,G402121041400000,G402121041447184,8,1,15,1,16,210414,1104,G3100",
"3C.BD.C5.31.1E.69,3C.BD.C5.35.36.88,0,0,Unknown,1,0,1,0,0,0,Unknown",
"3C.BD.C5.35.36.90,3C.BD.C5.3C.6B.58,G402121051500000,G402121051559033,8,1,15,1,16,210515,1104,G3100",
"3C.BD.C5.3C.6B.59,3C.BD.C5.37.5C.88,0,0,Unknown,1,0,1,0,0,0,Unknown",
"3C.BD.C5.37.5C.90,3C.BD.C5.3D.D3.38,G402121051800000,G402121051852950,8,1,15,1,16,210518,1104,G3100",
"3C.BD.C5.3D.D3.40,3C.BD.C5.42.27.40,G402121060700000,G402121060735456,8,1,15,1,16,210607,1104,G3100",
"3C.BD.C5.42.27.4C,3C.BD.C5.46.3E.C4,G402121062200000,G402121062233519,8,1,15,1,16,210622,1104,G3100",
"3C.BD.C5.46.3E.CC,3C.BD.C5.47.F6.C4,G402121071300000,G402121071314079,8,1,15,1,16,210713,1104,G3100",
"3C.BD.C5.47.F6.CC,3C.BD.C5.49.AE.C4,G402121072100000,G402121072114079,8,1,15,1,16,210721,1104,G3100",
"3C.BD.C5.49.AE.CC,3C.BD.C5.50.05.4C,G402121070100000,G402121070151920,8,1,15,1,16,210701,1104,G3100",
"3C.BD.C5.50.05.4C,3C.BD.C5.57.37.CC,G402121072000000,G402121072058960,8,2,15,2,9,210720,1104,G3100",
"3C.BD.C5.57.37.CE,3C.BD.C5.59.22.C0,E302121072000000,E302121072020947,6,2,15,2,9,210720,1103,E3200",
"3C.BD.C5.59.24.74,3C.BD.C5.60.3B.6C,G402121080200000,G402121080258079,8,2,15,2,9,210802,1104,G3100",
"3C.BD.C5.60.3B.74,3C.BD.C5.67.20.6C,G402121081100000,G402121081156479,8,2,15,2,9,210811,1104,G3100",
"3C.BD.C5.67.20.74,3C.BD.C5.69.B8.CC,G402121081160000,G402121081181259,8,2,15,2,9,210811,1104,G3100",
"3C.BD.C5.69.B8.D4,3C.BD.C5.71.07.FC,G402121082000000,G402121082059877,8,2,15,2,9,210820,1104,G3100",
"3C.BD.C5.71.08.00,3C.BD.C5.76.8D.C8,G402121082600000,G402121082645241,8,2,15,2,9,210826,1104,G3100",
"3C.BD.C5.76.8D.CD,3C.BD.C5.7D.27.A5,G402121090800000,G402121090854075,8,2,15,2,9,210908,1104,G3100",
"3C.BD.C5.7D.27.A6,3C.BD.C5.83.03.C6,0,0,Unknown,2,0,2,0,0,0,Unknown",
"3C.BD.C5.7E.9C.4C,3C.BD.C5.83.03.CC,G402121091600000,G402121091636080,8,2,15,2,9,210916,1104,G3100",
"3C.BD.C5.83.03.CE,3C.BD.C5.85.4C.A4,E302121091600000,E302121091624953,6,2,15,2,9,210916,1103,E3200",
"3C.BD.C5.85.4C.AA,3C.BD.C5.8C.CB.CB,0,0,Unknown,2,0,2,0,0,0,Unknown",
"3C.BD.C5.8C.CB.CC,3C.BD.C5.93.FF.94,G402121101500000,G402121101559001,8,2,15,2,9,211015,1104,G3100",
"3C.BD.C5.93.FF.9C,3C.BD.C5.9B.67.71,0,0,Unknown,2,0,2,0,0,0,Unknown",
"3C.BD.C5.9B.67.72,3C.BD.C5.A1.71.B2,G402121110500000,G402121110549480,8,2,15,2,9,211105,1104,G3100",
"3C.BD.C5.A1.71.B4,3C.BD.C5.A3.FE.22,E302121110500000,E302121110527837,6,2,15,2,9,211105,1103,E3200",
"3C.BD.C5.A3.FE.28,3C.BD.C5.AD.16.63,0,0,Unknown,2,0,2,0,0,0,Unknown",
"3C.BD.C5.AD.16.64,3C.BD.C5.AE.AE.34,E302122010100000,E30212201017400,6,2,15,2,9,220101,1103,E3200",
"3C.BD.C5.AE.AE.34,3C.BD.C5.B4.2D.5E,E302121122100000,E302121122160039,6,2,15,2,9,211221,1103,E3200",
"3C.BD.C5.B4.2D.62,3C.BD.C5.B5.09.9A,G402122021400000,G402122021407047,8,2,15,2,9,220214,1104,G3100",
"3C.BD.C5.B5.09.A2,3C.BD.C5.B5.E5.9A,G402122031000000,G402122031007039,8,2,15,2,9,220310,1104,G3100",
"3C.BD.C5.B5.E5.A2,3C.BD.C5.B8.0B.9A,G402122031100000,G402122031117599,8,2,15,2,9,220311,1104,G3100",
"3C.BD.C5.B8.0B.A2,3C.BD.C5.C1.ED.A2,G402122031500000,G402122031580960,8,2,15,2,9,220315,1104,G3100",
"3C.BD.C5.C1.ED.A4,3C.BD.C5.C2.40.1E,E302122031300000,E302122031303519,6,2,15,2,9,220313,1103,E3200",
"3C.BD.C5.C2.40.24,3C.BD.C5.C2.89.E6,E302122031400000,E302122031403147,6,2,15,2,9,220314,1103,E3200",
"3C.BD.C5.C2.89.EC,3C.BD.C5.CD.A1.19,0,0,Unknown,2,0,2,0,0,0,Unknown",
"3C.BD.C5.CD.A1.20,3C.BD.C5.CF.39.86,E302122052200000,E302122052217426,6,2,15,2,9,220522,1103,E3200",
"3C.BD.C5.CF.39.8C,3C.BD.C5.D2.C8.06,E302122091400000,E302122091438847,6,2,15,2,9,220914,1103,E3200",
"3C.BD.C5.D2.C8.0C,3C.BD.C5.DA.E1.12,E302122091500000,E302122091588450,6,2,15,2,9,220915,1103,E3200",
"3C.BD.C5.DA.E1.18,3C.BD.C5.DD.EE.86,E302122110900000,E302122110933341,6,2,15,2,9,221109,1103,E3200",
"3C.BD.C5.DD.EE.8C,3C.BD.C5.E5.83.97,0,0,Unknown,2,0,2,0,0,0,Unknown",
"3C.BD.C5.E5.83.98,3C.BD.C5.E8.34.8A,E302123011000000,E302123011029396,6,2,15,2,9,230110,1103,E3200",
"3C.BD.C5.E8.34.90,3C.BD.C5.F1.11.4A,E302123030400000,E302123030496800,6,2,15,2,9,230304,1103,E3200",
"3C.BD.C5.F1.11.50,3C.BD.C5.F1.E1.E2,E302123042100000,E302123042108899,6,2,15,2,9,230421,1103,E3200",
"3C.BD.C5.F1.E1.E8,3C.BD.C5.F4.B3.C2,E302123042600000,E302123042630800,6,2,15,2,9,230426,1103,E3200",
"3C.BD.C5.F4.B3.C8,3C.BD.C5.F8.7A.CA,E302123052000000,E302123052041260,6,2,15,2,9,230520,1103,E3200",
"3C.BD.C5.F8.7A.D0,3C.BD.C5.F8.A3.63,E302123080600000,E302123080601732,6,2,15,2,9,230806,1103,E3200",
"3C.BD.C5.F8.A3.64,3C.BD.C5.FF.FF.FF,0,0,Unknown,2,0,2,0,0,0,Unknown",
"DC.F5.1B.5F.EA.4F,DC.F5.1B.64.2B.10,Unknown,Unknown,0,2,16,2,9,223550,1103,Unknown",
"DC.F5.1B.64.2B.1A,DC.F5.1B.64.34.D5,E302123103100000,0,6,2,15,2,9,231031,1103,E3200",
"DC.F5.1B.64.54.5A,DC.F5.1B.64.57.B5,E302123110200000,0,6,2,15,2,9,231102,1103,E3200",
"DC.F5.1B.67.F4.7A,DC.F5.1B.68.6F.Ff,E302123113000000,0,6,2,15,2,9,231130,1103,E3200",
"DC.F5.1B.5D.64.60,DC.F5.1B.60.14.57,AA63332935300000,0,6,2,15,2,9,329353,1103,Unknown",
]
ref_data = parse_ref_data(ref_data_lines)
user_input = input("Enter one or more MAC addresses (comma-separated) or the path to a.csv file: ")
if user_input.lower().endswith('.csv'):
while not os.path.isfile(user_input) or not user_input.lower().endswith('.csv'):
user_input = input("Please enter a valid.csv file path: ")
save_location = input("Enter the save location for the output.csv file: ")
process_csv_file(user_input, ref_data, save_location)
else:
mac_addresses = user_input.split(',')
for mac in mac_addresses:
mac = mac.strip() # Remove any leading/trailing whitespace
result = process_single_mac(mac, ref_data)
result['MAC'] = mac # Include the original MAC address
# Print the result in a formatted table
print_formatted_table(result)
if __name__ == "__main__":
main()
Output:
Code: Fios-F1NdR
+--------------------+----------------------------------------+
| MAC Input | B8.F8.53.E2.EC.60 |
+--------------------+----------------------------------------+
| MAC Block Start | B8.F8.53.DC.6F.D0 |
+--------------------+----------------------------------------+
| MAC Block End | B8.F8.53.E3.C6.D8 |
+--------------------+----------------------------------------+
| MAC 2 Hex Ratio | 8 |
+--------------------+----------------------------------------+
| Calculated Serial | G402120111353138 |
+--------------------+----------------------------------------+
| Keyspace | w = <word> n = <number> |
| | ? = single digit at end of random word |
+--------------------+----------------------------------------+
| WiFi Pass Format | wnwnw |
+--------------------+----------------------------------------+
| WiFi Pass Length | 15 |
+--------------------+----------------------------------------+
| Admin Pass Format | wnw |
+--------------------+----------------------------------------+
| Admin Pass Length | 16 |
+--------------------+----------------------------------------+
| Model Type | G3100 |
+--------------------+----------------------------------------+
| Date Code (YYMMDD) | 201113 |
+--------------------+----------------------------------------+
| Hardware | 1104 |
+--------------------+----------------------------------------+
Using the script is pretty simple, just run it! The script will prompt you to "Enter one or more MAC addresses (comma-separated) or the path to a.csv file:”. As it says, it will accept a variety of inputs. You can type a single MAC address, a few MACs separated by a comma, or feed it a list of MACs from a comma separated .csv file. The script strips out the characters . - : so it will accept a variety of formats. If you give it a .csv file, it will prompt you for a save path, which will be something like "/path/fiender.csv”. The script will then use “ref_data_lines” as the data to calculate the information. Everything should be human readable and commented, but let me know if you have any questions. For future updates I will only post the new ref_data_lines because that should be all that needs changed.
Once I had the data and the script, I collected 25 new entries for the data base and checked them against the script. How did we do? OOF, only 36% of the new entries were calculated correctly. At least the correct hits show that we’re on the right path...
Correct = 9 (36%)
Incorrect = 10 (40%)
Unknown Block = 4 (16%)
Unknown Device = 1 (4%)
Not Enough data = 1 (4%)
This actually isn’t a bad thing though, the script is making some assumptions about each MAC block, and these entries provide us with new date codes. After working the new entries into the data, we test the script again. Much better, with 80% of the hits correct. The ones we’re missing are because we don’t have enough information to calculate the block space just yet. Sometimes just a single entry can remove a bunch of the unknown, which means that continuing to collect data will continue to improve the script. The good news is that this only really pertains to calculating the correct Serial Number, which doesn’t matter much at this point without a keygen algorithm. The script will still output everything we know, including the Password Keyspace as this info doesn’t actually change too much across devices. I will keep track of these stats as I continue to update the data base to see how close we’re getting to finding all of the blocks. Although we don’t have the algorithm, all we need to do is drop it into the script and we have a complete recovery tool!
Correct = 20 (80%)
Incorrect = 0 (0%)
Unknown Block = 4 (16%)
Unknown Device = 0 (0%)
Not Enough data = 1 (4%)
Some other fun stats:
We have discovered 145 unique date codes. Here the date codes and the # of devices currently believed to be in each block. On average, a block contains 29336 devices, so a usually high number of devices could indicate that there is at least 1 missing date code. 0 devices means that we don’t know enough about that block yet. Current calculations predict ~4165721 devices total.
Code: 190429 68331
190611 53855
190618 50210
190620 0
190626 92598
190716 52588
190729 0
190730 0
190730 0
190810 53855
190731 15853
190813 82368
190823 28886
190813 96619
190920 10639
190926 38016
191011 09403
191014 09503
191016 06327
191017 05278
191018 02438
191112 22176
191108 25986
191111 0
191115 18507
191202 24580
191205 12691
191207 34848
191217 04341
191209 31870
200107 09503
200109 09504
200110 11251
200113 17260
200116 09205
200102 48365
200210 0
200224 0
200225 0
200226 0
200229 0
200303 0
200310 0
200313 0
200314 0
200318 28617
200408 06335
200409 15839
200412 06335
200325 35047
200506 06336
200508 12671
200509 00989
200511 33816
200606 22176
200526 34649
200702 00501
200703 06335
200705 17284
200626 54056
200723 09503
200718 54800
200811 48333
200812 84479
200820 71279
200824 24789
200828 03519
200830 74845
200908 37706
200915 70025
200915 05308
201015 03519
201016 24639
201018 03519
201019 42240
201024 14080
201025 28491
201007 63510
201007 0
201013 36980
201015 28159
201112 10559
201113 24640
201117 14637
201113 04693
201113 60129
201202 59839
201210 65150
201223 42240
210118 21120
210106 40805
210115 16660
210301 20240
210303 00364
210217 82769
210312 98659
210312 37546
210331 73919
210414 47184
210515 59033
210518 52950
210607 35456
210622 33519
210713 14079
210721 14079
210701 51920
210720 58960
210720 20947
210802 58079
210811 56479
210811 81259
210820 59877
210826 45241
210908 54075
210916 36080
210916 24953
211015 59001
211105 49480
211105 27837
220101 17400
211221 60039
220214 07047
220310 07039
220311 17599
220315 80960
220313 03519
220314 03147
220522 17426
220914 38847
220915 88450
221109 33341
230110 29396
230304 96800
230421 08899
230426 30800
230520 41260
230806 01732
223550 0
231031 0
231102 0
231130 0
329353 0
RE: Verizon Fios G3100 and E3200 Research - FiosFiend - 04-17-2025
I am happy to say I have added another 59 entries to the dataset, which added to the 25 that I collected in the previous post brings us to 84 new entries! I was hoping for 100, but that is close enough for me. There are now 313 complete entries.
Dataset:
g3100_E3200_04_16_24.xlsx (Size: 331.59 KB / Downloads: 0)
Reference Images: Ref_images.zip
Let’s see what we’ve learned...
First, we test the new entries against the Fios-F1nDr database. We test 58 entries, since 1 was actually missing the serial. Again it doesn’t look good at first, but all it really means is that we’ve collected a bunch of new Date Codes! After working all of the new entries into the proper place and recalculating everything, we retest against the updated database.
Before:
Correct - 12 (~20.5%)
Incorrect - 23 (~40.5%)
unknown block - 12 (~20.5%)
Unknown device - 9 (~15.5%)
Not Enough Data - 2 (~3%)
After:
Correct - 44 (~75.9%)
Incorrect - 3 (~5%)
unknown block - 0 (0%)
Unknown Device 9 (~15.5%)
Not enough data 2 (~3%)
Much Better! The 3 incorrect are outliers in the dataset, that don’t calculate correctly at the moment. The Unknown devices are showing up because they are either in the DC.F5.1B block or new block 74.90.BC. We are starting to gather a bit more info about both of these, but we need more entries to better understand what’s going on there.
We now have 166 Unique Date codes. There is now a second sheet named “Date Codes” in the dataset that has each of the blocks separated. This eventually gets collapsed into that data_ref_lines that the Fios-F1nDr code uses, which is also included with the dataset. Sorting the entries by the date codes allows us to see devices that are in the same block possibly removing some of the overall randomness. There are quite a few blocks that we have 4-7 entries for.
Also added to the dataset is a new column named “QR”, which indicates if the QR data was read from the reference image. The QR data either reads or it doesn’t, so it is the most accurate and therefore preferred source of the data. This is the script that I am using to sort the scraped images into “found” and “not found”. Found images contain either a QR code, or some part of the back label we are looking for (WIFI, Serial, Password, etc). The script is adapted from code found here, and uses apple vision for the text and zbarimg for the QR code. The script might only work on an Apple devices, but I am not sure. The script will output “imagedata.csv” at the end, that contains all of the info that it finds. The script works great to sort the images, but unfortunately the extracted text is rarely complete or correct, but it’s fun to see what the computer picks up.
Code: """
Use Apple's Vision Framework via PyObjC to detect text in images
modified code from: https://gist.github.com/RhetTbull/1c34fc07c95733642cffcd1ac587fc4c
Necessary Dependencies:
python3 -m pip install pyobjc-core pyobjc-framework-Quartz pyobjc-framework-Vision wurlitzer
brew install zbar
This script process all of the images in folder_path using apple vision to extract text.
It checks to see if any of the keywords are found in the image, and extracts the relevent info
All of the info is saved to <file name> and relevent photos are moved to the "found" folder
in case they need to be referenced later. Any photos without keywords are deleted.
"""
import pathlib
import sys
import Quartz
import Vision
import os
import shutil
import pandas as pd
from Cocoa import NSURL
from Foundation import NSDictionary
# needed to capture system-level stderr
from wurlitzer import pipes
import subprocess
import re
from pyzbar.pyzbar import decode, ZBarSymbol
from PIL import Image
sys.path.append(r'/opt/homebrew/Cellar/zbar') #tell the script where to find zbarimg
KEYWORDS = ["Wi-Fi Name:", "Wi-Fi Password:", "Admin URL:", "Admin Password:",
"Model Number:", "Serial #.", "WAN MAC:", "HW ver.:", "Shipped FW ver.:"]
# Define the keyword mappings
qr_to_keyword_map = {
"WIFI:S:": "Wi-Fi Name:",
"T:WPA;P:": "Wi-Fi Password:",
"ROUTER:M:": "Model Number:",
"S:": "Serial #.",
"W:": "WAN MAC:",
"I:admin;P:": "Admin Password:",
}
QRKEYWORDS = ["WIFI:S:", "T:WPA;P:", "I:admin;P:", "ROUTER:M:", "S:"]
KEYWORDS = ["Wi-Fi Name:", "Wi-Fi Password:", "Admin URL:", "Admin Password:",
"Model Number:", "Serial #.", "WAN MAC:", "HW ver.:", "Shipped FW ver.:"]
keywords_lower = [keyword.lower() for keyword in KEYWORDS] #makes keywords lowercase(case insensitive) for better matching
global qr_found
def image_to_text(img_path, lang="eng"):
input_url = NSURL.fileURLWithPath_(img_path)
with pipes() as (out, err):
# capture stdout and stderr from system calls
# otherwise, Quartz.CIImage.imageWithContentsOfURL_
# prints to stderr something like:
# 2020-09-20 20:55:25.538 python[73042:5650492] Creating client/daemon connection: B8FE995E-3F27-47F4-9FA8-559C615FD774
# 2020-09-20 20:55:25.652 python[73042:5650492] Got the query meta data reply for: com.apple.MobileAsset.RawCamera.Camera, response: 0
input_image = Quartz.CIImage.imageWithContentsOfURL_(input_url)
vision_options = NSDictionary.dictionaryWithDictionary_({})
vision_handler = Vision.VNImageRequestHandler.alloc().initWithCIImage_options_(
input_image, vision_options
)
results = []
handler = make_request_handler(results)
vision_request = Vision.VNRecognizeTextRequest.alloc().initWithCompletionHandler_(handler)
error = vision_handler.performRequests_error_([vision_request], None)
return results
def scan_qr(image_path, img_name):
qr_read = pd.DataFrame()
global qr_found
qr_found = False
try:
# Run zbarimg command on the image
#qimage_path = '/Users/Brian/Downloads/Routers/Fios-3100/ebay_images/found/image_702.webp'
img = Image.open(image_path) # Replace with your file
decoded_objects = decode(img)
if decoded_objects:
qr_read = pd.DataFrame(decoded_objects)
#print(decoded_objects)
#print(f"✅ QR Code Found:" + str(decoded_objects))
#qr_codes = [line.split(": ", 1)[1] for line in result.stdout.strip().split("\n") if ": " in line]
#qr_read = pd.DataFrame(qr_codes) # Create a DataFrame
qr_read["QR_read"] = "Yes"
#df = pd.DataFrame(qr_codes, columns=["QR Code Data"])
qr_found = True
#else:
#print(f"❌ No QR code detected in", img_name)
except FileNotFoundError:
print("Error: zbarimg is not installed or not found in PATH.")
#return qr_read
return decoded_objects
def make_request_handler(results):
""" results: list to store results """
if not isinstance(results, list):
raise ValueError("results must be a list")
def handler(request, error):
if error:
print(f"Error! {error}")
else:
observations = request.results()
for text_observation in observations:
recognized_text = text_observation.topCandidates_(1)[0]
results.append([recognized_text.string(), recognized_text.confidence()])
return handler
def extract_values(qrcodes, results, QRKEYWORDS, KEYWORDS):
global match_found
match_found = False
extracted_data = {key: "" for key in KEYWORDS} # Initialize a dictionary with empty values
# Convert QRKEYWORDS to KEYWORDS mapping
qr_to_keyword_map = {
"WIFI:S:": "Wi-Fi Name:",
"T:WPA;P:": "Wi-Fi Password:",
"I:admin;P:": "Admin Password:",
"ROUTER:M:": "Model Number:",
";S:": "Serial #."
}
# **Step 1: Search QR Code Data**
for qr_entry in qrcodes:
data_str = str(qr_entry) # Decode bytes to string
for qr_key, keyword in qr_to_keyword_map.items():
match = re.search(fr'{qr_key}([^;]+)', data_str)
if match:
extracted_data[keyword] = match.group(1).split("'")[0] # Remove trailing artifacts
match_found = True
extracted_data["QR_found"] = "Yes"
# **Step 2: Search OCR Text (Only if not found in QR)**
for text_entry in results:
text = str(text_entry)
for keyword in KEYWORDS:
if extracted_data[keyword]: # Skip if already filled by QR
continue
match = re.search(fr'{keyword}([^;]+)', text, re.IGNORECASE)
if match:
extracted_data[keyword] = match.group(1).split("'")[0] # Extract OCR value
match_found = True
# Convert to DataFrame
extract_df = pd.DataFrame([extracted_data])
return extract_df
folder_path = input("Please enter the file path to folder with the images: ")
folder_path = (folder_path + "/")
folder_contents = os.listdir(folder_path)
os.makedirs(folder_path +"found/", exist_ok=True)
os.makedirs(folder_path +"not_found/", exist_ok=True)
global match_found
match_found = False
matched_text = pd.DataFrame() #the dataframe where well store all of oure matched text
clean_list = pd.DataFrame()
for imgs in folder_contents:
if not imgs.lower().endswith((".png", ".jpg", ".jpeg", ".webp", ".tiff")): #.lower makes the comparison case-insensitive
continue
match_found = False
print ("Processing: " + imgs)
img_path = (folder_path + imgs)
qrcodes = scan_qr(img_path, imgs)
results = image_to_text(img_path)
# Extract values from QR and OCR results
if qrcodes:
#qr_data = extract_values(qrcodes)
print("QR Code Found: " + str(qrcodes))
if results:
#ocr_data = extract_values(results)
print ("OCR Text Found: " + str(results))
if qrcodes or results:
img_data = extract_values(qrcodes, results, QRKEYWORDS, KEYWORDS)
img_data['IMG'] = imgs #add the image name to the info
if match_found == True:
print(f"✅ Match found! Moving: {imgs}")
matched_text = pd.concat([matched_text, img_data], ignore_index=True) #add the extracted info to our dataframe
shutil.move(folder_path + imgs, folder_path + "found/" + imgs) #moves the images to a folder named "found"
else:
print(f"❌ No match. Moving: {imgs}")
shutil.move(folder_path + imgs, folder_path + "not_found/" + imgs) #moves the images to a folder named "found"
#os.remove(img_path) #delete files where no info is found
#Now to do some cleaning to our matched_text
#clean_list['Duplicates'] = 0
if not matched_text.empty:
clean_list = matched_text #copy the matched text into a new dataframe
clean_list = clean_list.fillna("") #remove any nan
clean_list = clean_list.map(lambda x: x.replace(" ", "") if isinstance(x, str) else x)
#clean_list = clean_list.map(lambda x: x.replace("', 0.5]", "") if isinstance(x, str) else x)
img_column = clean_list.pop('IMG') # Removes "IMG" column but keeps it in memory
clean_list["duplicates"] = clean_list.duplicated(keep="first").astype(int) #adds a column "duplicates" and denotes duplicate with 0 or 1
clean_list["duplicates"] = clean_list.groupby(clean_list.columns.drop(["duplicates"]).tolist())["duplicates"].transform("sum") #count the number of duplicates
clean_list = clean_list.drop_duplicates() #.reset_index(drop=True) # Drop duplicate rows and keep the first occurrence
clean_list.insert(0, "IMG", img_column)
clean_list = clean_list[["IMG"] + [col for col in clean_list.columns if col != "IMG"]] # ensures "IMG" is first column, while preserving the rest of the order
clean_list = clean_list.sort_values(by="IMG").reset_index(drop=True) #Arranges list in alphabetical order based on image name
clean_list = clean_list.reset_index(drop=True)
clean_list.to_csv(folder_path + "/imagedata.csv")
else:
print("No matched images found!")
# the number in the results is the confidence score, It's important to note that a lower confidence score doesn't
#necessarily mean the recognized text is incorrect, but it does suggest that the system is less certain about
#its accuracy. In such cases, manual verification or additional processing might be warranted to ensure the information's correctness.
Unfortunately, the script is not very good at reading the QR code. Running the script against all of the reference images only yields 38/313 QR codes. Using my phone, with a QR reader app is how I actually collect the QR codes. Using this method I’ve read 133/313 codes, but it takes much longer. If I could somehow get the script to read the QR with the same effectiveness as my phone it would make the scraping process so much faster and simpler! The good news is now that we have the QR column, we actually can separate the reference images into a “Read” and “Unread”, and perhaps use this to train the image processing to better recognize our QR codes. Furthermore, we are looking for a specific format to the QR code, so hopefully this can better inform the script too? Here is what an example read looks like.
Code: WIFI:S:Verizon_ZFBX9P;T:WPA;P:bread-veto6-ode;;ROUTER:M:G3100;S:G402121090810583;W:3CBDC577D884;I:admin;P:KT7XFBH3D;;4
If you want to see if your phone is any better at reading images, I can read the first image but not the second.
![[Image: attachment.php?aid=1254]](https://hashcat.net/forum/attachment.php?aid=1254) ![[Image: attachment.php?aid=1256]](https://hashcat.net/forum/attachment.php?aid=1256)
Despite everything that I’ve been able to accomplish, I am very much new to all this. This is my first foray into hardware hacking, and I am working mostly off of tutorials found online. I was able to get binwalk to run, and I can get it loaded into Ghidra, but I honestly have no clue what the next steps should be. I believe it is encrypted, possibly with LUKS. I found an awesome post on the openwrt forums discussing the CR1000A which is a similar device. The post is an exciting read, but quickly got over my head. I also found a nice teardown of the E3200, which seems to be very similar to the G3100 internally. Looks like the embedded processor of choice is a Broadcom BCM68369KFEBG, which is a Dual Core 1.5 GHz ARM v8 processor featuring 4x GbE PHYs, 1x USB 3.0, DDR 800MHz support, 4ch VoIP.
"Looks like the embedded processor of choice is a Broadcom BCM68369KFEBG, which is a Dual Core 1.5 GHz ARM v8 processor featuring 4x GbE PHYs, 1x USB 3.0, DDR 800MHz support, 4ch VoIP."
I hope that my posts show that I am putting a lot of effort into this, and willing to share my ideas openly. I don’t really expect to find the keygen algorithm, but it’s enough of a carrot to keep me going. I will continue to drudge along by myself, but if you, or anyone you know may be interested in furthering this research please let me know. I have all of the listed firmware downloaded and I’m happy to pass it along.
|