20,225 bytes added
, Yesterday at 19:24
[[File:Lantronix MSS100 external.jpg|thumb|Lantronix MSS100 case front with "Retro Teal" branding]]
<span id="contents"></span>
<span id="mss100"></span>
= MSS100 =
Serial to Ethernet device produced by Lantronix
There are a bunch of these on the public Internet, or a bunch of honeypots :) - 6 real ones on the internet, over 300 honeypots.
I purchased a used one for $19 on eBay including shipping in April 2024
[https://www.lantronix.com/wp-content/uploads/pdf/MSS_QSG.pdf Quick Start Guide] [https://www.lantronix.com/wp-content/uploads/pdf/mss1-x.pdf Installation Guide] [https://www.lantronix.com/wp-content/uploads/pdf/mss_ref.pdf Reference Manual]
<span id="external-photos"></span>
= External Photos =
<gallery mode="packed" heights="200">
File:Lantronix MSS100 external.jpg|thumb|Lantronix MSS100 case front with "Retro Teal" branding
File:Mss100-external-ethernet-power.jpg|thumb|MSS100 Ethernet and DC input ports
File:Mss100-external-serial.jpg|thumb|MSS100 serial port
</gallery>
<span id="disassembly"></span>
= Disassembly =
Two PH0 screws on either side. Remove the serial port pegs. Then press on the serial port to shift the two metal halves apart
Internal lot date: 06/99
Three additional internal PH0 screws holding the PCB to the metal housing. Slide PCB slightly toward the serial side, then lift at an angle parallel to the length
<span id="internal-photos"></span>
= Internal Photos =
<gallery mode="packed" heights="200">
File:Internal-casefront.jpg|thumb|Inside of the front of the MSS100 case
File:External-screws.jpg|thumb|MSS100 external screws
File:Internal-casewide.jpg|thumb|Wide angle photo of the front of the MSS100 circuit board
File:Internal-caseclose1.jpg|thumb|Close up shot of the MSS100 circuit board
File:Internal-caseclose2.jpg|thumb|Close up shot of the MSS100 circuit board
File:Internal-caseclose3.jpg|thumb|Close up shot of the MSS100 circuit board
File:Internal-caseclose4.jpg|thumb|Close up shot of the MSS100 circuit board
File:Internal-caseclose5.jpg|thumb|Close up shot of the MSS100 circuit board
File:Internal-headers1.jpg|thumb|Close up shot of the MSS100 circuit board showing internal headers
File:Internal-caseclose6.jpg|thumb|Close up shot of the MSS100 circuit board
File:Internal-headers2.jpg|thumb|Close up shot of the MSS100 circuit board showing an unpopulated header connection
File:Internal-bottomwide.jpg|thumb|Wide angle photo of the bottom of the MSS100 circuit board
File:Internal-bottomclose1.jpg|thumb|Close up shot of the bottom of the MSS100 circuit board
</gallery>
<span id="components"></span>
= Components =
Shares components with [[MSSVIA#Components]]
{| class="wikitable"
|-
! Component
! Part No.
! Manufacturer
|-
| Dual Speed Ethernet Transceiver
| Level One 9929 DF58 [https://www.alldatasheet.com/datasheet-pdf/pdf/66167/INTEL/LXT970AQC.html LXT970AQC] 2LVU20236.1
| Intel Corporation
|-
| CMOS Boot Flash
| AM29LV800BT-120EC 9928GBB HH
| Advanced Micro Devices
|-
| 16 Meg FPM DRAM (x2)
| 9928 MT 4LC1M16C3 TG -6 V
| Micron
|-
| Voltage Regulator
| [https://www.onsemi.com/pdf/datasheet/mc33269-d.pdf 269-3] XAUY
| Onsemi
|-
| Supply Voltage Supervisor
| [https://pdf1.alldatasheet.com/datasheet-pdf/download/177157/TI/7705AC.html 7705AC] 96M AEOF
| Texas Instruments
|-
| RS-232 Transmitter/Receiver
| HIN 208ECA L9909GFFT
| Renesas
|-
| CPU
| Net+ARM 55595B/0136951 234 9926
| NETSILICON
|}
CPU and another DRAM chip on the bottom side of the board
https://ftp1.digi.com/support/documentation/userguide_hwreferenceguide.pdf 1.2 NET+ARM Chip Key Features 32-bit ARM7TDMI RISC Processor
https://en.wikipedia.org/wiki/ARM7#ARM7TDMI The ARM7TDMI (ARM7 + 16 bit Thumb + JTAG Debug + fast Multiplier + enhanced ICE) processor implements the ARMv4 instruction set.
I already tried loading our COFF into Ghidra as ARMv4, but it didn’t like it.
<span id="revisions"></span>
= Revisions =
{| class="wikitable"
|-
! Retro Teal
! Blue Splotch
! Orange Swab
|-
| [[File:Lantronix MSS100 external.jpg|thumb|Lantronix MSS100 case front with "Retro Teal" branding]]
| [https://ecx.images-amazon.com/images/I/31DK6Y3T24L._SX300_.jpg Link to "Blue Splotch" branding example image]
| [https://automatyka.istore.pl/userdata/public/gfx/40872/DSC_0489.jpg Link to "Orange Swab" branding example image]
|}
{| class="wikitable"
|-
! Revision 1
! Revision 2
! Model
! Country
! Weekstamp
! Branding
|-
| B0 *
| Unknown
| MSS100
| USA
| 06/99 *
| Retro Teal
|-
| B12
| Unknown
| MSS100
| USA
| Unknown
| Retro Teal
|-
| A15
| Unknown
| MSS100-357
| USA
| Unknown
| Blue Splotch
|-
| D13
| Unknown
| MSS100
| USA
| Unknown
| Blue Splotch
|-
| E14
| Unknown
| MSS100
| USA
| Unknown
|
|-
| E16
| Unknown
| MSS100
| Unknown
| Unknown
| Blue Splotch
|-
| F14
| Unknown
| MSS100
| China
| 1702
| Blue Splotch
|-
| F15
| Unknown
| MSS100
| China
| 2902
|
|-
| F15
| Unknown
| MSS100
| China
| 3002
|
|-
| F15
| Unknown
| MSS100
| China
| 0303
| Blue Splotch
|-
| B11
| Unknown
| MSS100-11
| China
| 04W09
| Blue Splotch
|-
| E19
| Rev. D
| MSS100
| China
| 05W04
| Orange Swab
|-
| B13
| Rev. D
| MSS100
| China
| 05W14
|
|-
| E19
| Rev. D
| MSS100
| China
| 05W17
| Orange Swab
|-
| B14
| Rev. D
| MSS100
| China
| 05W44
| Orange Swab
|-
| E20
| Rev. D
| MSS100
| China
| 06W24
|
|-
| A11
| Rev. C
| MSS100
| China
| 07W06
|
|-
| A13
| Rev. C
| MSS100
| China
| 08W51
| Orange Swab
|-
| A13
| Unknown
| MSS100-21
| Unknown
| Unknown
|
|-
| A14
| Rev. C
| MSS100
| China
| 09W52
| Orange Swab
|-
| A14
| Rev. C
| MSS100
| China
| 10W08
| Orange Swab
|-
| A14
| Rev. D
| MSS100-21
| China
| 10W42
|
|-
| A14
| Rev. D
| MSS100-22
| China
| 11W02
|
|-
| A14
| Rev. D
| MSS100-21
| China
| 11W30
|
|}
<code>*</code>: based on internal markings
<span id="firmware"></span>
= Firmware =
[https://ts.lantronix.com/ftp/mss100/ Download Link] Only 3.8.1 is available, Archive.org goes back to 2020, no other versions available
[https://ts.lantronix.com/ftp/old_rel/mss100/ Older versions], going back to v3.5.6 Saw on Shodan that there is some 3.6.? firmware or something
<span id="reverse-engineering"></span>
= Reverse engineering =
<span id="xxdhexdump"></span>
== xxd/Hexdump ==
<syntaxhighlight lang="hexdump">00000000 16 67 4f f2 bb 7a d5 7d 00 00 00 00 ff ff e1 36 |.gO..z.}.......6|
00000010 e1 36 00 00 01 01 00 00 40 40 56 00 01 00 15 00 |.6......@@V.....|
00000020 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 |................|
*
000000f0 01 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 |................|
00000100 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 |................|
*
00000200 0a 00 00 07 00 00 00 00 00 00 00 00 00 00 00 00 |................|
00000210 00 1c 46 0f 01 0b 00 00 00 0b cf 68 00 00 5e f0 |..F........h..^.|
00000220 00 00 c5 34 00 02 01 88 00 02 00 00 00 0e bd e0 |...4............|
00000230 2e 74 65 78 74 00 00 00 00 02 00 00 00 02 00 00 |.text...........|
00000240 00 0b cf 68 00 00 01 48 00 00 00 00 00 00 00 00 |...h...H........|
00000250 00 00 00 00 00 00 00 20 2e 67 6c 75 65 00 00 00 |....... .glue...|
00000260 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 |................|
00000270 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 20 |............... |
00000280 2e 76 65 72 73 00 00 00 00 0d cf 68 00 0d cf 68 |.vers......h...h|
00000290 00 00 00 48 00 0b d0 b0 00 00 00 00 00 00 00 00 |...H............|
000002a0 00 00 00 00 00 00 00 40 2e 72 64 61 74 61 00 00 |.......@.rdata..|
000002b0 00 0d cf b0 00 0d cf b0 00 00 ee 30 00 0b d0 f8 |...........0....|
000002c0 00 00 00 00 00 00 00 00 00 00 00 00 00 00 80 20 |............... |
000002d0 2e 64 61 74 61 00 00 00 00 0e bd e0 00 0e bd e0 |.data...........|
000002e0 00 00 5e f0 00 0c bf 28 00 00 00 00 00 00 00 00 |..^....(........|
000002f0 00 00 00 00 00 00 00 40 2e 62 73 73 00 00 00 00 |.......@.bss....|
00000300 00 0f 1c d0 00 0f 1c d0 00 00 c5 34 00 00 00 00 |...........4....|
00000310 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 80 |................|
00000320 2e 64 69 73 6b 00 00 00 00 0f e2 04 00 0f e2 04 |.disk...........|
00000330 00 00 9a 20 00 0d 1e 18 00 00 00 00 00 00 00 00 |... ............|
00000340 00 00 00 00 00 00 00 20 ea 00 00 60 ea 00 00 32 |....... ...`...2|</syntaxhighlight>
There is a standard Lantronix firmware header at <code>00000000</code>, also seen in [https://netzhansa.com/lantronix-lat-master-password/ this blog post] and [[IQeye 511]]. <code>000000f0</code> is of an unknown relevance, but it also appears in the linked blog post. <code>00000200</code> starts some kind of [https://en.wikipedia.org/wiki/COFF COFF]. This is similar to the blog post, but the initial bytes are different and there are additional sections.
Virtual Jaguar, [https://github.com/OpenEmu/VirtualJaguar-Core/blob/master/VirtualJaguar/src/file.cpp#L624 this] has another example of a COFF file with the magic bytes from that blog post. Makes sense as the [https://en.wikipedia.org/wiki/Atari_Jaguar Atari Jaguar] also used a Motorola 68k processor.
Not sure what to make of these sections. Apple [https://opensource.apple.com/source/gcc/gcc-1640/gcc/collect2.c.auto.html references] <code>.glue</code>. Ghidra [https://ghidra.re/ghidra_docs/api/constant-values.html references] <code>.glue</code>. [https://github.com/ARM-software/u-boot/blob/master/arch/arm/lib/crt0_arm_efi.S#L26 ARM’s u-boot loader for PE/COFFs] thinks the header should be <code>0x01c2</code>.
[https://www.ti.com/lit/an/spraao8/spraao8.pdf?ts=1712473389471 COFF Reference] Page 4 is File Header Structure Bytes 0-1 are Version ID - Our’s is <code>0a 00</code> is this the magic bytes for an [https://chromium.googlesource.com/chromiumos/third_party/binutils/+/refs/heads/stabilize-7019.B/include/coff/arm.h#79 ARM COFF] or did the guy just make it up, as the comment says? - [https://www.ti.com/lit/an/spraao8/spraao8.pdf?ts=1712473389471 Table 3] says <code>00a0h</code> is the magic number for [https://www.ti.com/microcontrollers-mcus-processors/msp430-microcontrollers/overview.html MSP430 device family], a 16-bit microcontroller. [https://www.ti.com/tool/MSP-CGT#included MSP430 Code Generation Tools] - [https://www.ti.com/sc/docs/products/micro/msp430/userguid/as_2.pdf Introduction to the COFF Format for MSP430 Family] - I tried importing our <code>.o</code> file into Ghidra as an MSP430, but it doesn’t like it Bytes 2-3 are Number of Section Headers - Our’s is <code>00 07</code>, and we have 7 sections! Definitely a COFF Bytes 4-7 are a timestamp of when the file was created - Our’s is all <code>00</code> Bytes 8-11 are the symbol table’s starting address - Our’s is all <code>00</code> Bytes 12-15 are the number of entries in the symbol table - Our’s is all <code>00</code> Bytes 16-17 is the number of bytes in an optional header. Either 0 or 28 - Our’s is <code>00 1c</code>, which is 28! We have an optional header of 28 bytes Bytes 18-19 are flags - Our’s is <code>46 0f</code>
<pre>0100 0110 0000 1111 # Our flags
0000 0000 0000 0001 # Relocation stripped
0000 0000 0000 0010 # File is relocatable, no unresolved external references
0000 0000 0000 0100 # Line numbers stripped
0000 0000 0000 1000 # Local symbols stripped
0000 0010 0000 0000 # Big endian
0000 0100 0000 0000 # Mystery flag
0100 0000 0000 0000 # Mystery flag</pre>
Bytes 20-21 Target ID/Magic number - Our’s is <code>01 0b</code>, which is not in Table 3. This is also the same value as in the [https://netzhansa.com/lantronix-lat-master-password/ blog post]!
Optional Header Bytes 0-1 are an optional file header magic number. Example given is <code>0x0108</code>, similar to above - Our’s is <code>00 00</code> Bytes 2-3 is a version stamp - Our’s is <code>00 0b</code> Bytes 4-7 is the size in bytes of the executable code - Our’s is <code>cf 68 00 00</code>, or 3,479,699,456 in decimal. Roughly 3.5GB - Our whole firmware file is less than 1MB… strange - Without the trailing zeroes, <code>cf 68</code> is 53,096 which makes a bit more sense. ~53kb Bytes 8-11 is the size in bytes of the initialized data - Our’s is <code>5e f0 00 00</code>, <code>0x5ef0</code> = 24,304 in decimal. ~24kb Bytes 12-15 is the size in bytes of the uninitialized data - Our’s is <code>c5 34 00 02</code> = 3,308,519,426 in decimal. Doesn’t make sense Bytes 16-19 is the entry point - Our’s is <code>01 88 00 02</code> - Btw, our file goes to <code>000dba40</code>, that includes all the zip archive as well - Maybe it needs to be read <code>00021088</code> or 135,304 in decimal. that makes sense Bytes 20-23 is the beginning address of the executable code - Our’s is <code>00 02 00 00</code> Bytes 24-27 is the beginning address of initialized data - Our’s is <code>00 0e bd e0</code> - <code>bde0000e</code> is way out of our file size, and so is <code>000ebde0</code>
todo: put the above information in a table
Section headers We have 7 of them: <code>.text</code>, <code>.glue</code>, <code>.vers</code>, <code>.rdata</code>, <code>.data</code>, <code>.bss</code>, and <code>.disk</code> There’s two versions of COFF section headers - COFF1 and COFF2 I don’t know what the difference is between “TMS430” and “MSP430” Let’s say we’re dealing with COFF2 and see if everything makes sense or not Conclusion: We’re using [https://www.ti.com/lit/an/spraao8/spraao8.pdf?ts=1712473389471 COFF1], which TI says is for C5400 only I can’t find much information about C5400 online, and nothing regarding whether it’s supported by Ghidra
Bytes 0-7 are an 8 character section name padded with zeroes - Let’s start with <code>.text</code> Bytes 8-11 are the section’s physical address - Our’s is <code>00 02 00 00</code>, just like the beginning address of executable code above Bytes 12-15 are the section’s virtual address - Our’s is <code>00 02 00 00</code>, just like the physical address above Bytes 16-19 is the section size in bytes (words for COFF1) - Our’s is <code>00 0b cf 68</code> - same bytes as the version stamp and the lower bytes of the size of the executable code from the optional header. weird as those are totally separate things Bytes 20-23 is a file pointer to raw data - Our’s is <code>00 00 01 48</code> - Does this translate to <code>00000348</code>? This is right after the end of the <code>.disk</code> section - Value at the location is <code>ea 00 00 60</code>. Not making sense just yet Bytes 24-27 is a file pointer to the relocation entries - Our’s is all <code>00</code>, makes sense as the relocation stripped flag is set Bytes 28-31 are reserved Bytes 32-35 are the number of relocation entries Bytes 36-39 are reserved (or is this a TMS430?) (in COFF2) - Our’s is <code>00 00 00 20</code> - This makes more sense as a COFF1 section, as this is the end of the section header Bytes 36-37 are flags (in COFF1) - Our’s is <code>00 00</code> Byte 38 is reserved Byte 39 is the memory page number - Our’s is <code>20</code>, or 32 in decimal
todo: put the above information in a table
So does our <code>.text</code> section begin at <code>00000400</code> since our COFF file begins at <code>00000200</code>?
Debian used to ship [https://manpages.debian.org/stretch/binutils-msp430/msp430-objdump.1.en.html <code>msp430-objdump</code>] which I might be able to use to follow along with [https://netzhansa.com/lantronix-lat-master-password/ that blog]. That is, assuming we are using an MSP430.
Equipped with this information, it was time to start Ghidra, open a new project and import the binary file selecting “68000” in the “Language and Compiler Specification” dialog. In the Code Browser, I defined the mapping from the object file to memory locations using the “Memory Map” tool. First, the automatically created “ram” section needed to be removed, then I could define “text”, “data” and “bss” sections according to the <code>objdump</code> output.
Let’s try doing that with our file, at least the <code>.text</code> section
For some reason, the maximum address size for MSP430 in Ghidra is <code>0xffff</code>, which makes sense for a 16-bit CPU. Makes me think this isn’t our microprocessor.
<span id="strings"></span>
= Strings =
<code>Punix version B3.0/165(051018)</code>
<pre>Portions of Punix Universal C (PUC) are derived from EiC V4.1.0, an online
bytecode C interpreter (www.anarchos.com/eic), and are used with permission.</pre>
In [https://web.archive.org/web/20000817174324/http://www.anarchos.com/eic/ Archive.org]
<pre>anonymous
biteme
anonymous login ok, proceed.
Password required.</pre>
<code>disk rm -r /ram/*</code>
<code>Server: Gordian Embedded1.0</code>, see also [[IQeye 511]], another product that legitimately uses this. In general, there’s 308 servers on Shodan matching this header, and I think all of them are honeypots.
[https://www.sec.gov/Archives/edgar/data/1114925/000101706202001163/0001017062-02-001163.txt SEC Archive]
<pre> Lantronix also announced that it has signed an agreement with Gordian
Corporation that gives Lantonix joint ownership of the Gordian intellectual
property that is embodied in the products Gordian has designed for Lantronix.
Lantronix will pay Gordian $6.0 million to acquire an interest in the Gordian
intellectual property. Lantronix will also purchase $1.5 million for engineering
and support services from Gordian over the next 18 months.
A copy of the press release issued on May 30, 2002 is attached hereto as
Exhibit 99.1 and the Agreement dated May 28, 2002 between Gordian Corporation
and Lantronix, Inc. is attached hereto as Exhibit 10.16.</pre>
<pre>POST
application
x-www-form-urlencoded
Set-Cookie: %s=%s
/oem/version.txt
/oem/factory.cmd
/oem/startup.cmd
/oem/README</pre>
My hypothesis that the microcontroller architecture would be referenced in the strings was confirmed:
<pre>ARM-COFF
r0 = %08lx r1 = %08lx r2 = %08lx r3 = %08lx
r4 = %08lx r5 = %08lx r6 = %08lx r7 = %08lx
r8 = %08lx r9 = %08lx r10 = %08lx
fp = %08lx ip = %08lx lr = %08lx
pc = %08lx sp = %08lx psr = %08lx prc_cur = %s</pre>
Need to try opening in Ghidra as ARM. Tried as ARM v4, Ghidra didn’t like it
Hypothesis: As the firmware includes a C interpreter, there must be C source code included to be interpreted
<span id="relationships"></span>
= Relationships =
[https://ltrxdev.atlassian.net/wiki/spaces/LTRXTS/pages/106954830/How+to+Translate+MSS+Configuration+Settings+for+a+UDS+Device+Server Lantronix Teck Support Public Confluence] “the MSS runs on a different operating system than the UDS”
<pre>C:\>telnet 172.18.32.3
Password = access (You may not be prompted for a password. If you are, access is the default password, or use the password you've defined)
Username = <any name></pre>
<pre>Telnet into the UDS IP Address at port 9999:
C:\>telnet 172.18.32.4 9999
Press Enter to get into Setup Mode. <-- Press Enter within 3 seconds</pre>
https://ltrxdev.atlassian.net/wiki/spaces/LTRXTS/pages/106889366/Emulate+a+direct+serial+connection+over+the+LAN+-+MSS+Serial+Tunnel
<pre>To be able to configure the settings below you need to become a privileged user. The default password is "system"
To do this enter on both MSS units the following:
Local> SET PRIVILEGED
Password> system <- does not echo
The prompt will change to: "Local_n>>", indicating that you are now a privileged user, where n is either 1 if you are configuring the MSS through the serial interface, or some larger number if you connected to the CLI via telnet.</pre>
[https://www.ti.com/lit/ta/sszt447/sszt447.pdf?ts=1713154994724&ref_url=https%253A%252F%252Fwww.ti.com%252Ftool%252FTIDA-00226 Overcoming Ethernet Connectivity Challenges on the Power Grid]
The specific Net+ARM CPU is referenced in [https://patentimages.storage.googleapis.com/ea/da/1b/f62fb06e2fd019/US6889266.pdf this patent]
<span id="todo"></span>
= TODO =
* Contribute to <code>file</code> and <code>binwalk</code> recognition of Lantronix firmware files
** <code>16 67 4f f2 bb 7a d5 7d 00 00 00 00 ff ff e1</code>
** Maybe this also applies to other types of files
** Doing a search on VirusTotal using a Yara rule might find more