Open vidarrt9 opened 3 years ago
Hi @vidarrt9 ,
You are not bothering at all, the opposite. You're welcomed. I'm very pleased that someone finds my reverse on SMEG unit useful. To be honest I never though that someone would use it. So back to you question, I can't remember precisely has I don't have my laptop in my hands. I'll have a look tonight to confirm you.
To clarify, all my statements are hypothetical, only based on code analysis. I did some testing on my car unit, but I tried to be as gentle as possible to avoid any critical situation what would imply to explain to my car dealer that I broke my SMEG :)
That being said, from what I remember, I think I had identified a part in the code where the VxWorks checks what has been connected on USB. Thanks to the graph view I think you can find the CDC_EEM branch, and within this part all the supported VID/PID checked. I'll check if my memories are correct if I can retrieve this part in ghidra tonight.
I'm pretty disappointed in VxWorks.md file, many information are missing. I guess I forgot to update it. I spent a lot of time in reading and understanding the VxWorks inner mechanics, that I can't retrieve in the document.
Ok I just found in ghidra that CDCEEM is in fact the very last item configured. Thus, i guess it won't such an helper in case of bricking.
void usrRoot(undefined4 param_1,undefined4 param_2)
{
uint uVar1;
int in_r13;
excIntNestLogInit();
uVar1 = vxMsrGet();
vxMsrSet(uVar1 | *(uint *)(in_r13 + -0x7e40));
usrKernelCoreInit();
cpuPwrFrameWorkInit(1,0,300,1000,100,0);
cpuPwrLightMgrInit();
poolLibInit();
memEdrInit();
memInit(param_1,param_2,0xbb0);
memEdrInit2();
memEdrShowInit();
memPartLibInit(param_1,param_2);
memInfoInit();
usrAimMmuConfig();
usrSysctlInit();
usrMmuInit(param_1,param_2);
usrPmInit();
usrEdrInit();
edrSystemDebugModeInit();
usrTextProtect();
excOsmInit(0x1000,0x1000);
usrKernelIntStkProtect();
taskStackGuardPageEnable();
taskStackNoExecEnable();
sysClkInit();
edrStubInit();
setLibInit();
usrIosCoreInit();
usrKernelExtraInit();
usrIosExtraInit();
sockLibInit();
usrNetworkInit();
usrDsiInit2();
selTaskDeleteHookAdd();
cplusCtorsLink();
usrCplusLibInit();
cplusDemanglerInit();
usrUsb2HelperInit();
usrUsb2MscInit();
usrUsb2EndInit();
usrUsb2Serial3GInit();
usrUsbDataServicesInit();
usrUsbLinksysWusb54EndInit();
usrToolsInit();
usrMMComponentsInit();
usrAppInit();
usb2CdcInit();
return;
}
I can't remember exactly if last Ghidra archive was such analyzed. I'll upload a new one on GIT.
Not sure what your experience with RCE is, but my plan is to waste as little time as possible one the reverse engineering of VxWorks. And I already noticed that one of the really really important tools from IDA which I love to use to know what parts I don't need to care about is missing: FLIRT.
But I'll check how to work around it, if at all possible.
I've also looked at the list of CVEs for VxWorks and there is only one that might give instant admin access (CVE-2010-2965, basically requires that the debugger is listening on some port, if I got that right), but I don't think it's applicable to this firmware at all. But the dhcpd and IGMP3 issues seem promising.
Given the manifold ways the Linux kernel can be tricked into all sorts of evil stuff (well not as much anymore, but the VxWorks version in the SMEG+ is old enough to share these mistakes), I have hope that the GreatFET can get me privileged access. But I will only try that on the SMEG+ which isn't in my car, for the same reasons you outlined above 😁
Since I just noticed that in the Ghidra project only a handful of names were actually named as per the symbol files, I wanted to quickly let you know that you can easily fix this.
My approach isn't refined yet, but it's a start. Among other things it's crude because it doesn't distinguish the type (see nm
for the meaning of the middle column of symbols_bsp.txt.gz
. And read here how I brought the input into the shape in which the .map
file now is (see below).
Use this as the input to the Ghidra ImportSymbolsScript.py
script (see Window -> Script Manager).
There are still duplicates in this map file, which I need to weed out. But this will give meaningful names to all of the functions. I am still working on refining this a little more (via IDA).
Hope this is useful to you.
To recap, here's what I plan on doing with the symbol files:
T
and t
sound logical, but on the other hand I already found data aplenty in .text
)... in addition to this I am currently looking into attempting to use ret-sync to be able to share my IDA and Ghidra work. I found that there are numerous things in IDA that I am much more familiar with (no wonder after nearly 20 years of experience) and some of which are "foreign" in Ghidra. On the other hand Ghidra has a neat decompiler (well, Hopper as well ... but then Hopper is lacking in other aspects). Anyway, long story short: this should speed up my effort as I can then use the best from both worlds.
Never mind my last comment regarding the symbols. I just noticed that from the symbol dump you obtained, you deliberately chose to leave out certain items (i.e. you limited the address range in which you were renaming them).
I think I'll play around a bit with your symbol dump in order to match it with what we have from the firmware upgrade bundle.
I think I remember you mentioned using IDA in the beginning. Does that mean you crafted some FLIRT files already? If so, would you mind sharing them? If not, that's one of my next tasks. There's at least OpenSSL and zlib in there and I need to weed out all the uninteresting library stuff to concentrate on the juicy bits.
I think I remember you mentioned using IDA in the beginning. Does that mean you crafted some FLIRT files already? If so, would you mind sharing them? If not, that's one of my next tasks. There's at least OpenSSL and zlib in there and I need to weed out all the uninteresting library stuff to concentrate on the juicy bits.
Correct I remember having started with IDA at the beginning, but as being not a professional reverse engineer, I had some legal licensing troubles. Even more if I had to share the result of my analysis. Lucky me, Ghidra was just released, perfect opportunity to discover new tools. You can reach me on Telegram if you want (same username).
Regarding OpenSSL, there are interesting entry points in ghidra which points to "OpenSSL 0.9.8l 5 Nov 2009" What would be the advantage of FLIRT with IDA given that vxWorks embeds all symbols, including those from Std Libraries (maybe i'm wrong on that last point, maybe not all of symbols are embedded) ?
@bousqi I actually just checked in the symbol names for both OpenSSL 0.9.8l and zlib 1.2.3 which I retrieved by building the respective shared objects for Linux. This will not be a 100% match, but very close.
What would be the advantage of FLIRT with IDA given that vxWorks embeds all symbols, including those from Std Libraries (maybe i'm wrong on that last point, maybe not all of symbols are embedded) ?
Two advantages in my book:
idb2pat.py
one could create patterns which could be applied to other versions of the SMEG+ firmware. Some of the folks I have been in contact with have been very interested in knowing what actually changed between all those individual releases.On another note, did you already encounter this?:
usb(0,0)host:vxWorks h=192.168.10.2 e=192.168.10.1 u=5121 pw=5121 f=0x0 tn=DB600
... looks awfully interesting to me. Still not sure what it is about. Also I noticed that one particular Linksys adapter gets special treatment in the firmware.
I am also looking through the VxWorks symbols, in particular I am looking to filter well-known C library names (after all we know VxWorks is supposedly POSIX compliant).
=== Number of objects by type
a 115
A 399
T 11065, matched: 3036
t 6510, matched: 14
W 214
V 341
G 655, matched: 3
g 804
D 458, matched: 9
d 579
S 553, matched: 1
s 217
b 366
B 212
=== Matched library symbols: 3053
So out of the symbols in the text section (t
and T
) more than 17% are library symbols we can disregard right away. I don't care how OpenSSL implements something, I can look it up in source, if I need to. Given the sheer number of symbols, I think that's a nice win.
Curious, a number of symbols (including library symbols) appear twice. So apparently the linker didn't elide these dupes ... or there's something else to them. Will keep you updated.
@vidarrt9 I think I can answer this one:
On another note, did you already encounter this?:
usb(0,0)host:vxWorks h=192.168.10.2 e=192.168.10.1 u=5121 pw=5121 f=0x0 tn=DB600
... looks awfully interesting to me. Still not sure what it is about. Also I noticed that one particular Linksys adapter gets special treatment in the firmware.
You can get this line when you telnet into the car, for example by using my special USB key that allows you to connect to the car (https://github.com/Mwyann/psakey). You get a lot of telnet commands, one of them is:
-> version
VxWorks (for Freescale MPC5121E ADS (Rev 0.1)) version 6.7.
Kernel: WIND version 2.12.
Made on May 26 2017, 13:23:36.
Boot line:
usb(0,0)host:vxWorks h=192.168.10.2 e=192.168.10.1 u=5121 pw=5121 f=0x0 tn=DB600
value = 92 = 0x5c = '\'
And a small nmap on it:
Starting Nmap 7.40 ( https://nmap.org ) at 2017-12-29 12:47 CET
Nmap scan report for 192.168.0.1
Host is up (0.00092s latency).
Not shown: 996 closed ports
PORT STATE SERVICE
23/tcp open telnet
111/tcp open rpcbind
3333/tcp open dec-notes (GPS data)
20000/tcp open dnp
MAC Address: 12:34:00:00:00:F2 (Unknown)
You can get this line when you telnet into the car, for example by using my special USB key that allows you to connect to the car (https://github.com/Mwyann/psakey). You get a lot of telnet commands, one of them is:
-> version VxWorks (for Freescale MPC5121E ADS (Rev 0.1)) version 6.7. Kernel: WIND version 2.12. Made on May 26 2017, 13:23:36. Boot line: usb(0,0)host:vxWorks h=192.168.10.2 e=192.168.10.1 u=5121 pw=5121 f=0x0 tn=DB600 value = 92 = 0x5c = '\'
Thanks for chiming in, @Mwyann. The Boot line:
sort of confirms my suspicion that this looks awfully like a kernel command line (in Linux you find that in /proc/cmdline
), which on embedded devices is often used to pass "hardcoded"1 information to the kernel. But take another look at what you do there:
Starting Nmap 7.40 ( https://nmap.org ) at 2017-12-29 12:47 CET Nmap scan report for 192.168.0.1
... see what I see? That's right, the subnet you're on with the nmap
and telnet
session is a totally different one from the subnet that seems to be be referenced on the "Boot line". My working theory here is that this is for some sort of special access. Could be that Linksys WiFi adapter which gets special treatment in the code, could be if you plug in a CDC_EEM device, there are numerous possibilities. But the u
and pw
also look like the credentials to whatever access will be available on either of those IP addresses. And the 5121
used as value to these keys also looks familiar, doesn't it ("MPC5121E", the CPU)?
Anyway, one of the next tests I'll do in the car - i.e. with the live head unit - will be to plug in a WUSB54GC adapter and see if this gives me any sort of additional access.
Also did you see this (and this directly related tool)? Either they're embellishing the vulnerability or that vulnerability doesn't have a CVE assigned. CVE-2019-12258.
1 Hardcoded only in the sense that typically the device needs to be placed into a special state (when fully booted) to access the location which normally holds this. Examples: the U-Boot environment in some NAND partition, the bootloader itself in some NAND partition which can be reflashed by placing the (embedded) device into a special state.
Thanks for chiming in, @Mwyann.
I was following this thread silently until now ;-)
Starting Nmap 7.40 ( https://nmap.org ) at 2017-12-29 12:47 CET Nmap scan report for 192.168.0.1
... see what I see? That's right, the subnet you're on with the
nmap
andtelnet
session is a totally different one from the subnet that seems to be be referenced on the "Boot line".
Well, to be honest, the key that I'm simulating is configured with both subnets, like the original key was. It is supposed to have both IPs 192.168.10.3 and 192.168.0.2. The curious thing is, the car is reachable at IP 192.168.0.1, but I couldn't access those other IPs 192.168.10.{1,2}, even by trying to use the car as a "gateway" (Destination Net Unreachable).
BTW, if needed, my script can also be used to emulate all sorts of devices of course, I'm currently emulating the Peugeot Connect Apps key because that's the target I was working on at the time (to be able to use the embedded IE6 browser) but maybe there are more PID/VIDs to try out, which would give more access. The telnet access is a good entrypoint I guess, for someone who understands how the system works. There's a lot to do there. You can start/stop tasks, display and even modify memory... Lots of things to crash too I guess :-)
Well, to be honest, the key that I'm simulating is configured with both subnets, like the original key was. It is supposed to have both IPs 192.168.10.3 and 192.168.0.2. The curious thing is, the car is reachable at IP 192.168.0.1, but I couldn't access those other IPs 192.168.10.{1,2}, even by trying to use the car as a "gateway" (Destination Net Unreachable).
Could be a mere configuration issue or it's filtered or something else. TBH my train of thought was more along the lines of getting that Linksys Wifi adapter to work with that other subnet, but I could be wrong. It's just that this particular adapter receives a special treatment in the system initialization routine and I find that intriguing. I got myself one from Belgium, which arrived by mail today. Probably will not be able to test it before the weekend, though.
This URGENT/11 business looks quite promising actually, if the device is prone to it. This could even affect the SMEG+Iv2, but I don't have that available. However, from what I saw in the (hardware) specs for SMEG+Iv2 I may have the correct hardware, but need a way to put the newer firmware on.
Has anyone actually ever tried that? Plug an update key with SMEG+Iv2 upgrade package into a SMEG+I?
Lots of things to crash too I guess :-)
As I understand it the device will be hard to brick this way. Which is good. Still, I am hoping to be able to bring the "offline" SMEG+ unit to life by emulating the handshake with the BSI.
maybe there are more PID/VIDs to try out, which would give more access.
We'll get there. However, I think the types available via CDC are fairly limited.
It would be interesting to change VID/PID of PSAKey simulated by RPI zero. Potentially you might be able to gain 5121 user ID with maybe different rights.
I don't have that much time later these days. I won't be able to test on my car.
I checked in the logs I saved back in the days. Using my CDC_EEM key, connected through a telnet session, i got an empty User ID with whoami
c4_telnet_session.log
You should cycle through all VID/PIDs recognized. I'll try to look in ghidra if a special processing is done for one of them.
I just remembered that USB also support Wifi interface. PSA allows to connect a Wifi token to the SMEG Unit. Maybe the 192.168.10.0/24 is the subnet dedicated to wifi Host AP.
It would be interesting to change VID/PID of PSAKey simulated by RPI zero. Potentially you might be able to gain 5121 user ID with maybe different rights.
I don't have that much time later these days. I won't be able to test on my car.
I checked in the logs I saved back in the days. Using my CDC_EEM key, connected through a telnet session, i got an empty User ID with
whoami
c4_telnet_session.logYou should cycle through all VID/PIDs recognized. I'll try to look in ghidra if a special processing is done for one of them.
Do you have a list of potential VID/PIDs to try out, eventually with associated functions? (always EEM or...?). Maybe I could try some of them myself. If it's supposed to be a Wifi dongle well, I'll be out of luck of course.
(I too have an empty whoami response BTW).
(I too have an empty whoami response BTW).
Perhaps you need to use iam
first ... it appears in the list of shell commands?!
@bousqi If you refer to the Linksys WUSB54, that's exactly the one I bought off of Ebay. It's ancient (2006), it's huge but I am hoping for some revelation. And if there's no revelation we can at least document it for others.
Edit 1: did you try this?
Works wonders to prefill certain symbols, but doesn't seem to be quite as complete as the gzipped text file. The screenshot is of the Ghidra Script Manager.
@bousqi If you refer to the Linksys WUSB54, that's exactly the one I bought off of Ebay. It's ancient (2006), it's huge but I am hoping for some revelation. And if there's no revelation we can at least document it for others.
Oh that sounds good... which one have you bought ? How much have you paid for it ? Thinking of this hardware, i'm not sure of the purpose in having wifi hotspot in car, connected to SMEG.
Edit 1: did you try this?
Works wonders to prefill certain symbols, but doesn't seem to be quite as complete as the gzipped text file. The screenshot is of the Ghidra Script Manager.
Yeah, I've seen this one. I started handling symbols by myself, and some weeks later I discovered ghidra plugins, which had a vxWorks symbol parser. I did gave a chance to it, but it was not enough. I spent lot of time in identifying commands structure and location, with callbacks associated.
Do you have a list of potential VID/PIDs to try out, eventually with associated functions? (always EEM or...?). Maybe I could try some of them myself. If it's supposed to be a Wifi dongle well, I'll be out of luck of course.
(I too have an empty whoami response BTW).
I will try to retrieve the code part that identifies VID / PID. I'm stupid, I forgot to bookmark it when I was working on this part.
You can have a look at USB-Devices wiki page @Mwyann, can you please remind me the VID/PIDs of PSAKey ?
Oh that sounds good... which one have you bought ? How much have you paid for it ?
Precisely the one you mention on that Wiki page. It was about 12 €. Interestingly there were quite some more expensive offers. As if there's something special to it.
Thinking of this hardware, i'm not sure of the purpose in having wifi hotspot in car, connected to SMEG.
It could be merely the external variant of what they added later to the SMEG+Iv2 or it could be something meant to be used with some sort of "repair kit" (think laptop plus more, incl. software) they were handing out to their garages. It's just guessing at this point, we'll know more if it works and if I can see anything special with it.
Yeah, I've seen this one. I started handling symbols by myself, and some weeks later I discovered ghidra plugins, which had a vxWorks symbol parser. I did gave a chance to it, but it was not enough.
I just updated a script that is based on my attempts to parse and make sense of the symbol table. And I am at over 3000 symbols which have the default name of FUN_BAADF00D
(last 8 digits are the hexadecimal address). So lots to rename. Gotta figure out the Ghidra Python API tomorrow.
Btw, "The Ghidra Book" was released within the last two weeks. It's by the same author as "The IDA Book" and a co-author. Got my electronic copy already, expecting the hardcopy soon. Perhaps I can befriend Ghidra after all. Can't hurt to expand the repertoire a little 😉
I spent lot of time in identifying commands structure and location, with callbacks associated.
Yikes, that sounds tedious. I am hoping to automate as much of that as I can. The Python API (Jython internally) seems a little limiting, but with this ghidra-bridge RPC server I can process much of my stuff in Python 3 and apply "findings" to the Ghidra database. My goal is to make this as accessible as possible to everyone else who is interested and willing to chime in with the analysis.
Had no luck with ret-sync, yet. Will keep trying, though.
These seem to be all the call sites to the function doing the filtering of vendor ID and device class (not product ID!):
00513a9c bl usb2VendorClassSpecific
00513b74 bl usb2VendorClassSpecific
00513c44 bl usb2VendorClassSpecific
0051d8a0 bl usb2VendorClassSpecific
0051d92c bl usb2VendorClassSpecific
0051ff28 bl usb2VendorClassSpecific
0051ffb8 bl usb2VendorClassSpecific
0052008c bl usb2VendorClassSpecific
0052912c bl usb2VendorClassSpecific
0052b5d4 bl usb2VendorClassSpecific
0052eb44 bl usb2VendorClassSpecific
00530d88 bl usb2VendorClassSpecific
00530f44 bl usb2VendorClassSpecific
00531e70 bl usb2VendorClassSpecific
0053e9e4 bl usb2VendorClassSpecific
0053fff4 bl usb2VendorClassSpecific
005400f4 bl usb2VendorClassSpecific
0054019c bl usb2VendorClassSpecific
00540244 bl usb2VendorClassSpecific
00540324 bl usb2VendorClassSpecific
00540438 bl usb2VendorClassSpecific
00540554 bl usb2VendorClassSpecific
005405b8 bl usb2VendorClassSpecific
00540660 bl usb2VendorClassSpecific
00540708 bl usb2VendorClassSpecific
005407b0 bl usb2VendorClassSpecific
00540970 bl usb2VendorClassSpecific
005411dc bl usb2VendorClassSpecific
Well found !
**************************************************************
* FUNCTION *
**************************************************************
undefined usb2VendorClassSpecific()
undefined r3:1 <RETURN>
undefined4 Stack[-0x40]:4 local_40 XREF[1]: 00511610(W)
usb2VendorClassSpecific XREF[29]: FUN_0052908c:0052912c(c),
FUN_0052b540:0052b5d4(c),
FUN_0052eae4:0052eb44(c),
usb2MscBulkOnlyMassStorageReset:
usb2MscBulkOnlyGetMaxLun:00530f4
usb2MscCBICommandTransfer:00531e
usb2MscCompliancePreliminaryProc
usb2MscComplianceClassSpecificRe
usb2MscComplianceClassSpecificRe
usb2MscComplianceClassSpecificRe
usb2MscComplianceClassSpecificRe
usb2MscComplianceClassSpecificRe
usb2MscComplianceClassSpecificRe
usb2MscComplianceClassSpecificRe
usb2MscComplianceClassSpecificRe
usb2MscComplianceClassSpecificRe
usb2MscComplianceClassSpecificRe
usb2MscComplianceClassSpecificRe
usb2MscComplianceErrorRecoveryTe
usb2MscComplianceErrorRecoveryTe
Most of them are related to USB compliance code validation. Among the three top functions, two a related to 3G modems from Huawei. The first one seem to be generic (ACM related)
That makes seems, EEM and ACM are classes. Thus vxWorks register listeners on those classes. Thus whatever the VID/PID, listeners are triggered once connected and offering compatible USB class. I'll keep looking just in case there is a late filtering.
@vidarrt9 I just remembered that regarding LinkSys, SMEG+ has a firmware in it, ready to be pushed in LinkSys device. I remember I identified the offset and dumped it... where did i stored that ?
Have a look at void linksyswusb54FirmwareUpload(void)
Hey @bousqi
sorry for bothering you again.
In VXWORKS.md you claim that VxWorks appears to be waiting for a CDC_EEM device.
You are then listing:
While you make that statement, I didn't find any reference as to how you come to that conclusion?
Or do you mean to say that the VxWorks device simply supports these CDC_EEM devices? Your wording suggests that there may be a delay specifically to connect such a device:
... am I reading too much into it? If not, could you point me to the file which made you draw this conclusion?
During the weekend I plan to start experimenting with GreatFET and a Beaglebone Black in an attempt to get into the SMEG+.
Thanks for any insights you can share - and again for your prior work on all this. It really helps being able to look through what you've done to look for clues for what I am attempting.