Merge pull request #2593 from Akury83/master
[RRG-proxmark3.git] / client / luascripts / mem_readpwd.lua
blob82343b94345eee7ef4931ac6752b16cde9fc6d48
1 local getopt = require('getopt')
2 local bin = require('bin')
3 local ansicolors = require('ansicolors')
5 copyright = 'Copyright (c) 2018 Bogito. All rights reserved.'
6 author = 'Bogito'
7 version = 'v1.0.4'
8 desc = [[
9 This script will read the flash memory of RDV4 and print the stored passwords/keys.
11 It was meant to be used as a help tool after using the BogRun standalone mode before SPIFFS.
12 You should now use data_read_pwd_mem_spiffs instead after the updated BogRun standalone mode.
14 (Iceman) script adapted to read and print keys in the default dictionary flashmemory sections.
16 example = [[
17 -- This will scan the first 256 bytes of flash memory for stored passwords
18 script run mem_readpwd
20 -- This will scan 256 bytes of flash memory at offset 64 for stored passwords
21 script run mem_readpwd -o 64
23 -- This will scan 32 bytes of flash memory at offset 64 for stored passwords
24 script run mem_readpwd -o 64 -l 32
26 -- This will print the stored Mifare dictionary keys
27 script run mem_readpwd -m
29 -- This will print the stored t55xx dictionary passwords
30 script run mem_readpwd -t
32 -- This will print the stored iClass dictionary keys
33 script run mem_readpwd -i
35 usage = [[
36 script run mem_readpwd [-h] [-o <offset>] [-l <length>] [-k <keylength>] [-m] [-t] [-i]
38 arguments = [[
39 -h : this help
40 -o <offset> : memory offset, default is 0
41 -l <length> : length in bytes, default is 256
42 -k <keylen> : key length in bytes <4|6|8> , default is 4
43 -m : print Mifare dictionary keys
44 -t : print t55xx dictionary passwords
45 -i : print iClass dictionary keys
47 ---
48 -- This is only meant to be used when errors occur
49 local function oops(err)
50 print('ERROR:', err)
51 core.clearCommandBuffer()
52 return nil, err
53 end
54 ---
55 -- Usage help
56 local function help()
57 print(copyright)
58 print(author)
59 print(version)
60 print(desc)
61 print(ansicolors.cyan..'Usage'..ansicolors.reset)
62 print(usage)
63 print(ansicolors.cyan..'Arguments'..ansicolors.reset)
64 print(arguments)
65 print(ansicolors.cyan..'Example usage'..ansicolors.reset)
66 print(example)
67 end
68 ---
69 -- The main entry point
70 local function main(args)
72 print( string.rep('--',20) )
73 print( string.rep('--',20) )
74 print()
76 local data, err, quadlet
77 local offset = 0
78 local length = 256
79 local keylength = 4
80 local usedkey = false
82 for o, a in getopt.getopt(args, 'ho:l:k:mti') do
84 -- help
85 if o == 'h' then return help() end
87 -- offset
88 if o == 'o' then offset = tonumber(a) end
90 -- num of bytes to read
91 if o == 'l' then
92 length = tonumber(a)
93 if length < 0 or length > 256 then
94 return oops('Error: Length is not valid. Must be less than 256')
95 end
96 end
98 -- keylength
99 if o == 'k' then keylength = tonumber(a); usedkey = true end
101 if o == 'm' then keylength = 6; usedkey = true; length = 8192; offset = 0x3F000-0x6000; end
102 if o == 't' then keylength = 4; usedkey = true; length = 4096; offset = 0x3F000-0x3000; end
103 if o == 'i' then keylength = 8; usedkey = true; length = 4096; offset = 0x3F000-0x4000; end
106 if (offset < 0) or (offset % 4 ~= 0) then
107 return oops('Error: Offset is not valid. Mod-4 values are only allowed.')
110 print('Memory offset', offset)
111 print('Length ', length)
112 print('Key length ', keylength)
113 print( string.rep('--', 20) )
115 data, err = core.GetFromFlashMem(offset, length)
116 if err then return oops(err) end
118 if usedkey then
120 _, keys, s = bin.unpack('SH'..length-2, data)
121 if keys == 0xFFFF then return "No keys found in section" end
123 local kl = keylength * 2
124 for i = 1, keys do
125 key = string.sub(s, (i - 1) * kl + 1, i * kl )
126 print(string.format('[%02d] %s',i, key))
128 print( string.rep('--',20) )
129 print( ('[+] found %d passwords'):format(keys))
130 else
132 _, s = bin.unpack('H'..length, data)
134 local cnt = 0, i
135 for i = 1, (length/keylength) do
137 key = string.sub(s, (i-1)*8+1, i*8)
138 if key == 'FFFFFFFF' then break end
139 print(string.format('[%02d] %s',i, key))
140 cnt = cnt + 1
142 print( string.rep('--',20) )
143 print( ('[+] found %d passwords'):format(cnt))
145 print( string.rep('--',20) )
148 main(args)