Jump to content

Leaderboard

Popular Content

Showing content with the highest reputation on 11/18/22 in all areas

  1. James Chiappetta Oct 31 A Dive Into Web Application Authentication A closer look into Web Application Authentication and what it means at a basic level for consumers and businesses. By: James Chiappetta, with guest contributions from Jeremy Shulman Disclaimers: The opinions stated here are the authors’ own, not necessarily those of past, current, or future employers. The mentioning of books, tools, websites, and/or products/services are not formal endorsements and the authors have not taken any incentives to mention them. Recommendations are based on past experiences and not a reflection of future ones. Background Take a moment and ask yourself, 10 years ago, which applications did you use that you still use today? Now think about how you authenticated to those apps, was Multifactor Authentication (MFA) an option? In recent years, authentication implementations have matured, for example many companies have made MFA mandatory. We will take a look why some of these changes have occurred and at application authentication more broadly. It’s useful to understand where we are today, how we got here, and where we may be in 10 years. Web Authentication Authentication Explained First Things First Innovation is something that happens naturally and gradually for various problem/solution pairs. There are usually very passionate people on both ends of a problem. One end agitates the problem while the other end works to create or improve upon solutions. As this relates here, authentication is a vital function for nearly all consumer and business applications. To get to the heart of what authentication is, here is what we will we cover: What is authentication and how is it different from authorization? Why do we need multifactor authentication? How does “sign in with” work (hint: OAuth 2.0) and should you use it? What is Single Sign On (SSO)? What is Passwordless Authentication? What is API Authentication? Bonus: What are Deep Links? Let’s get to it! What is Authentication and how is it different from Authorization? Authentication vs Authorization — Simply put, Authentication is the process an application performs to verify an identity’s credentials are valid. If valid, the user or system will be moved onto the next step which is typically an authorization check. Authorization is distinctly different from authentication and is a process to determine if a valid identity has access to a specific resource. Typical Authentication Example — You must be thinking, well how does an application know who I am? Obviously, you would need to be registered with the application first. Here is a basic example: Let’s say you want to subscribe to a new online service that will send you a different jelly each month. You navigate to the website and select the “create a new account” option. You pick your username and then set a password. You will likely need to provide an email and prove ownership of it. There you have it, you now have a registered identity in the application and can further enter your personal information to receive your jelly each month. Passwords — These are secrets set for each unique identity of an application. The problem with passwords, and passcodes for that matter, is that they are set by humans and humans often will seek the path of least resistance. Think of a sticky note on your grandma’s monitor. Passwords often get reused across many applications, set so they are easier to remember, and stored in insecure locations. This is why a second factor in the authentication process has become commonplace (more on this next). Super Basic Web Authentication Flow with MFA Pro tip: Back to Authorization for a second. Authorization describes what access you have. So it’s important to remember that it’s not just “what you have access to” but also “what data you can leverage with the access”. Fetching a specific person’s name is different than being able to fetch every person’s name. Why do we need MFA? In 2012 and LinkedIn reported one of the largest data breaches of the time occurred. Nearly 6.5 million passwords that they knew about became compromised. About 4 years later they discovered another 100 million were actually compromised. This was one of many credential breaches that can be searched on Troy Hunt’s Have I Been Pwned (HIBP) database of hundreds of millions of records. Unfortunately, this is just a fraction of the billions of leaked credentials floating out there. This has translated to a rise in credential stuffing attacks, where a known set of credentials from a compromised service are used on a completely separate one. The industry is seeing double digit growth in these attacks each year. Companies and consumers are usually both on the losing end of these attacks. What is MFA? Multifactor Authentication (MFA) — Enter the obvious solution, Multifactor Authentication (MFA). MFA is a common technique to prevent attackers from gaining access to user accounts even if credentials (username+password) are known or guessed. The impact of antiquated password policies has been known for a while and NIST is helping catch things up with their 800–63B publication. The idea behind MFA is to use at least two different factors for authentication. The three common factors used for MFA: 1) something you know, like a passcode, in addition to your password 2) something you have, like a soft token (software on your phone) or hard token (USB key) 3) something you are, like a biometric (face, eye, finger, or speech). Current state of MFA — Back to 2012, there weren’t many companies actively considering implementing MFA. Yet, here we are 10 years later with near ubiquity around its adoption. We can partly attribute security breaches in widely used platforms like LinkedIn and games like Fortnite for this. That of course doesn’t mean the end users are enabling it. A simple Google search trend analysis would help illustrate interest in MFA over time. Source: Google Trends Challenges with MFA — We are in a far different spot because of the security events that have transpired over the past 10 years. Our guess is that many generations now know what MFA is and use it in some way today. MFA is here to stay for now and we will see it continue to evolve. A focus on a better end-user experience will be key to its increased adoption as other solutions like Passwordless mature. More on that later. That all said, with any technology, there are challenges. Here are a few with MFA to be aware of: Consumer Adoption — Despite the billions of brute force attacks happening each year, people still don’t think the risk/reward of enabling MFA makes sense. Phishing Scams/Smishing — There are nearly endless counts of phishing attempts happening each day. Attackers have kept up with advancements in security measures and still can convince users to provide their multifactor token. Obviously, never provide anyone with any authentication tokens or secrets. MFA Push Fatigue — Those using an authentication app that supports notifications for approving a login attempt are susceptible to this. It happens when an attacker has user credentials and they spam the user with MFA requests, in hopes they click approve to make the notifications go away. Device Compatibility — Not everyone has a smartphone and this means they can’t install an authentication app for soft tokens or MFA push notifications. This means SMS or a hard token are the only options which come with trade offs. There is a wonderful list of scenarios maintained by NIST and some implementation guidance by Okta for further reading. Pro tips: For the software developers and engineers potentially reading this: It’s easy to make something that should be simple, like authentication, complicated. Don’t make it complicated. Avoid adding any business logic in your Authentication flows. MFA bypasses based on a specific identity/username (think “testuser”) is a common mistake. Hardware tokens (something you have) remain one of the strongest multifactor solutions today but have a high operational overhead and can be lost. Pick where you want to use this based on risk. How does “Sign In With” Work? If you are reading this article, I would hazard a guess that you have seen “sign in with” on various websites. Medium’s Sign in with page Heck, even Medium has this feature. This is where you would use your already established identity with another application, such as Google, Facebook, Apple, or the like, to authenticate to another application. This is possible because of widely adopted industry standards like OAuth2 and OIDC which are used for authentication. It is worth noting that OAuth2 was purely designed as an authorization protocol and not authentication. These two terms are often confused. The kind folks in the OAuth2 community have done a fine job walking through this here. This sign in with capability is possible because you are authenticating once with your Google account and then establishing a trust relationship between Google and whatever the third party application is to allow access (authorized) to that application post-authentication. Super Basic “Sign In With” Flow Is it safe? — Generally, yes, it’s safe when implemented correctly, however there are a large quantity of threat scenarios to consider which unfortunately manifest in the real world (1) (2) (3). One of the biggest issues in these flows is the implicit trust that sign in providers have, meaning applications generally trust the data in Google/Facebook/Apple to be true and accurate. The implementation isn’t just the only thing to be concerned with but the permissions across the two systems is also important. The service you are looking to sign in to may request access to your personal data, so look out for what applications are requesting. You should also periodically review and prune based on usage. What is Single Sign On (SSO)? Hopefully you have read the previous section about “sign in with”. The concept is quite similar, but usually in practice Single Sign On (SSO) uses a different protocol, called SAML 2.0, to perform the authentication between the identity provider, idP, (Google in the previous section) and the service provider, SP, (third party application you want to access). SAML 2.0 is very similar in concept to OAuth 2.0 in that it requires an exchange of identity information between trusted parties. applications. If you want your users to have accounts on many different services, and selectively grant access to various applications, use OAuth (application focused). SSO is usually employed for business to business applications. This enables business users to maintain a single account and access many applications with it. There are quite large organizations that specialize in SSO as a product. One of the biggest is Okta. Super Basic SSO SAML Flow Pro Tip: Many businesses have decided to charge for SSO, despite it being an implementation of an industry standard. Feel free to peruse some known companies that do this at https://sso.tax/. What is Passwordless Authentication? The concept of “Passwordless” authentication is to use a non-password factor (see above in the MFA section for the list of common factors) as your primary factor for authentication instead of a password. In movies this is often a retinal scan, because it looks cool. In reality, there is Apple PassKey which is now accepted as a primary factor for consumers. This is indeed a strong way to ensure the requesting user owns the credentials being provided to the system. However, there are some drawbacks with this. Currently, there is a very high and difficult bar to implement passwordless authentication at scale. The cost benefit analysis tips towards those with lots of privileged access in organizations, similar to hard tokens. Furthermore, the most likely passwordless factor is biometric, which raises privacy, accuracy, data storage concerns. A human’s biometrics can’t be changed if compromised. Microsoft has a detailed write up on how their Passwordless implementation works, with pictures of course. The FIDO (Fast IDentity Online) Alliance is focused on helping with open authentication standards that reduce password based authentication. The FIDO2 standard incorporates the web authentication (WebAuthn) standard, which we have written about on this blog. Pro Tip: We think for consumers passwordless authentication is still over the horizon, though Microsoft is getting close. For business users, we think players in the space are getting close, but really for only specific and highly privileged users. What is API Authentication? Let’s first start with: What is an API — Back to the jelly of the month subscription application example again. Let’s assume that the jelly of the month service has a feature to enroll you into a jelly enthusiast weekly newsletter that is provided by a third party. In order to subscribe to the newsletter, the jelly website will pass your email address to an API (application programming interfaces) that the newsletter makes available. This API will validate the jelly of the month website using some form of authentication. Super Basic API Authentication Flow Amazon Web Services (AWS) is one of the most prolific examples of APIs we can think of. It is an immense collection of APIs that its customers can use, mainly through HTTP, which is core to the internet. These APIs are designed to be accessible to the public internet. While they may be open to the broader internet, they require an identity to access, unless a resource is explicitly made open, such as static images for a marketing website. OK, now onto API authentication… Basic Authentication — As indicated by its name, basic Authentication is basic. This means it’s a username and a password, that’s all. The username and password will be base64 encoded and added as an HTTP header for the server to decode and validate. Note: Encoding is NOT encryption. This is why TLS (HTTPS) is important. OAuth 2.0 Access Tokens — As mentioned earlier, OAuth is a standard protocol used for authorization but in the case of APIs, used in a specific way in the authentication flow of APIs. OAuth has what is known as access tokens, also known as JWT bearer tokens, which are provided by an OAuth Authorization server. There is a wonderful post by Nordic APIs on how this all works. These tokens authorize a relying party to act on behalf of those for whom the token is issued to. They are frequently used to access user profile information such as the user’s name and email address. Mutual TLS (mTLS) — mTLS allows for each party in a connection, the client and the server, to verify each others’ identities. This form of Authentication leverages public key cryptography and the TLS encryption protocol. Trust is acquired from known certificate authorities. This differs from TLS where only the server provides its identity for verification by the client. More on the differences here. Pro Tip: In practice you may see additional security controls placed on APIs, such as IP address or system based restrictions. This is not Authentication and should be treated as a secondary factor. Bonus: What are Deep Links? What happens when you try to access your email and you’re not logged in? You get redirected to the login page. After logging in, though, you are seamlessly redirected back to your email without having to manually navigate. How does this work? Enter deep links. Deep links — A service provider/relying party user experience implementation detail. They allow a user to be sent directly to a specific application and/or page post-Authentication. Deep links are not explicitly part of the Authentication specs we have discussed but all said specs have a means of supporting them via a pseudo-session state. In SAML2, this is the “RelayState” parameter. In OAuth2/OIDC, this is the “state” parameter. An identity provider or Authorization server will always send this value back to the service provider/relying party post-Authentication. Deep links are a type of link that sends users directly to an app instead of a website or a store. They are used to send users straight to specific in-app locations, saving users the time and energy locating a particular page themselves — significantly improving the user experience. Deep linking does this by specifying a custom URL scheme (iOS Universal Links) or an intent URL (on Android devices) that opens your app if it’s already installed. Deep links can also be set to direct users to specific events or pages, which could tie into campaigns that you may want to run. Pro tip: Deep Links and any Authentication flow for that matter can be fraught with security considerations that need to be accounted for. Issues such as open redirects, cross site request Forgeries, and clickjacking are serious concerns with Authentication. Takeaways Authentication is a simple process to validate a registered identity within an application. There are a lot of security implications with getting authentication wrong, which is why getting it right is so important. Authorization is not authentication. It is the process to confirm an authenticated identity has access to something. Passwords alone are no longer adequate to keep applications secure. MFA is here to stay for now and needs serious consideration by those companies who haven’t implemented it yet. For the strongest MFA today, use a hard token, but know that comes at a high management cost. There is a lot of behind the scenes magic that happens to make authentication as frictionless as possible. The use of “sign in with” and Single Sign On (SSO) are becoming more widely adopted, which is fine, but be sure you review the permissions and data of each application. We are eager for a phishing resistant and passwordless authentication solution, but there are a lot of challenges ahead to finding the right balance between cost and reward. Innovations that are happening today with FIDO2, Web Authn, and privacy standards are beginning to help. Even more complicated authentication work flows, like deep links, make it convenient for the end user to get to resources but can be vulnerable to many different issues. For the security practitioners reading, we recommend you find the time reviewing your company’s authentication implementations. Words of Wisdom Authentication isn’t something we simply can’t ignore. Despite the collective decades of experience implementing and securing Authentication for companies, we remain with a feeling of continued curiosity as it evolves over time. The only true wisdom is in knowing you know nothing. — Socrates Contributions and Thanks A special thanks to those who helped peer review and make this post as useful as it is: Marshall Hallenbeck, Keshav Malik, Abishek Patole, Evan Helbig, Byron Arnao, Sean McConnell, Luke Young, and Anand Vemuri. A special thanks to you, the reader. We hope you benefited from it in some way and we want everyone to be successful at this. While these posts aren’t a silver bullet, we hope they get you started. Please do follow our page if you enjoy this and our other posts. More to come! Sursa: https://betterappsec.com/a-medium-dive-into-web-application-authentication-342d1d002a61
    1 point
  2. Dumping and extracting the SpaceX Starlink User Terminal firmware Towards the end of May 2021 Starlink launched in Belgium so we were finally able to get our hands on a Dishy McFlatface. In this blog post we will cover some initial exploration of the hardware and we will explain how we dumped and extracted the firmware. Note that this blog post does not discuss any specific vulnerabilities, we merely document techniques that can be used by others to research the Starlink User Terminal (UT). Towards the end of this blog post we will include some interesting findings from the firmware. Note that SpaceX actively encourages people to find and report security issues through their bug bounty program: https://bugcrowd.com/spacex We first set up our UT on a flat section of our university building’s roof and played around with it for a few hours, giving the UT and router the chance to perform a firmware update. We did run a few mandatory speed tests and were seeing as much as 268 Mbps download and 49 Mbps upload. Teardown: Level 1 After a few hours of playing around it was time to get our hands dirty and disassemble the UT. There have been a few teardown videos of the UT but none of them went into the details we were interested in: the main SoC and firmware. Nevertheless, these prior teardowns ([1, 2, 3]) of the dish contain a lot of useful information that allowed us to disassemble our dish without too much damage. It appears that there a few hardware revisions of the UT out there by now, certain parts of the teardown process can differ depending on the revision, something we learned the hard way. One of the aforementioned teardown videos shows the Ethernet and motor control cables to be detached from the main board before the white plastic cover is removed. On our UT, a tug on the motor control cables pulled the entire connector from the PCB; luckily it appears we can repair the damage. In other words, do not pull on those cables but first remove the back plastic cover, for those of you in the same boat: JST BM05B-ZESS-TBT. After removing the back plastic cover we can see a metal shield covering the PCB, with the exception of a small cut-out containing the connectors for the Ethernet cable and motor control cable. There is one additional, unpopulated connector (4 pin JST SH 1.0mm), that we assumed would contain a UART debug interface as was shown in [4]. Note that the early teardown videos had an additional connector that is no longer present on our UT. The UART interface After hooking up a USB to serial converter we could get some information on the UT’s boot process. The output contains information regarding the early stage bootloaders before showing the following output. We can see that the UT is using the U-Boot bootloader, and that typing ‘falcon’ may interrupt the boot process. While this may give us access to a U-Boot CLI we can also see that the serial input is configured as ‘nulldev’. Unsurprising, spamming the serial interface with ‘falcon’ during boot did not yield any result. U-Boot 2020.04-gddb7afb (Apr 16 2021 - 21:10:45 +0000) Model: Catson DRAM: 1004 MiB MMC: Fast boot:eMMC: 8xbit - div2 stm-sdhci0: 0 In: nulldev Out: serial Err: serial CPU ID: 0x00020100 0x87082425 0xb9ca4b91 Detected Board rev: #rev2_proto2 sdhci_set_clock: Timeout to wait cmd & data inhibit FIP1: 3 FIP2: 3 BOOT SLOT B Net: Net Initialization Skipped No ethernet found. * + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + Board: SPACEX CATSON UTERM ====================================== = Type 'falcon' to stop boot process = ====================================== Continuing through the boot process we can see that U-Boot loads a kernel, ramdisk and Flattened Device Tree (FDT) from a Flattened uImage Tree (FIT) image that is stored on an embedded MultiMediaCard (eMMC). We can also see that the integrity (SHA256) and authenticity (RSA 2048) of the kernel, ramdisk and FDT is being checked. While we would have to perform some more tests it appears that a full trusted boot chain (TF-A) is implemented from the early stage ROM bootloader all the way down to the Linux operating system. switch to partitions #0, OK mmc0(part 0) is current device MMC read: dev # 0, block # 98304, count 49152 ... 49152 blocks read: OK ## Loading kernel from FIT Image at a2000000 ... Using 'rev2_proto2@1' configuration Verifying Hash Integrity ... sha256,rsa2048:dev+ OK Trying 'kernel@1' kernel subimage Description: compressed kernel Created: 2021-04-16 21:10:45 UTC Type: Kernel Image Compression: lzma compressed Data Start: 0xa20000dc Data Size: 3520634 Bytes = 3.4 MiB Architecture: AArch64 OS: Linux Load Address: 0x80080000 Load Size: unavailable Entry Point: 0x80080000 Hash algo: sha256 Hash value: 5efc55925a69298638157156bf118357e01435c9f9299743954af25a2638adc2 Verifying Hash Integrity ... sha256+ OK ## Loading ramdisk from FIT Image at a2000000 ... Using 'rev2_proto2@1' configuration Verifying Hash Integrity ... sha256,rsa2048:dev+ OK Trying 'ramdisk@1' ramdisk subimage Description: compressed ramdisk Created: 2021-04-16 21:10:45 UTC Type: RAMDisk Image Compression: lzma compressed Data Start: 0xa2427f38 Data Size: 8093203 Bytes = 7.7 MiB Architecture: AArch64 OS: Linux Load Address: 0xb0000000 Load Size: unavailable Entry Point: 0xb0000000 Hash algo: sha256 Hash value: 57020a8dbff20b861a4623cd73ac881e852d257b7dda3fc29ea8d795fac722aa Verifying Hash Integrity ... sha256+ OK Loading ramdisk from 0xa2427f38 to 0xb0000000 WARNING: 'compression' nodes for ramdisks are deprecated, please fix your .its file! ## Loading fdt from FIT Image at a2000000 ... Using 'rev2_proto2@1' configuration Verifying Hash Integrity ... sha256,rsa2048:dev+ OK Trying 'rev2_proto2_fdt@1' fdt subimage Description: rev2 proto 2 device tree Created: 2021-04-16 21:10:45 UTC Type: Flat Device Tree Compression: uncompressed Data Start: 0xa23fc674 Data Size: 59720 Bytes = 58.3 KiB Architecture: AArch64 Load Address: 0x8f000000 Hash algo: sha256 Hash value: cca3af2e3bbaa1ef915d474eb9034a770b01d780ace925c6e82efa579334dea8 Verifying Hash Integrity ... sha256+ OK Loading fdt from 0xa23fc674 to 0x8f000000 Booting using the fdt blob at 0x8f000000 Uncompressing Kernel Image Loading Ramdisk to 8f848000, end 8ffffe13 ... OK ERROR: reserving fdt memory region failed (addr=b0000000 size=10000000) Loading Device Tree to 000000008f836000, end 000000008f847947 ... OK WARNING: ethact is not set. Not including ethprime in /chosen. Starting kernel ... The remainder of the boot process contains some other interesting pieces of information. For example, we can see the kernel command line arguments and with that the starting addresses and lengths of some partitions. Additionally, we can see that the SoC contains 4 CPU cores. 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 [ 0.000000] 000: Detected VIPT I-cache on CPU0 [ 0.000000] 000: Built 1 zonelists, mobility grouping on. Total pages: 193536 [ 0.000000] 000: Kernel command line: rdinit=/usr/sbin/sxruntime_start mtdoops.mtddev=mtdoops console=ttyAS0,115200 quiet alloc_snapshot trace_buf_size=5M rcutree.kthread_prio=80 earlycon=stasc,mmio32,0x8850000,115200n8 uio_pdrv_genirq.of_id=generic-uio audit=1 SXRUNTIME_EXPECT_SUCCESS=true blkdevparts=mmcblk0:0x00100000@0x00000000(BOOTFIP_0),0x00100000@0x00100000(BOOTFIP_1),0x00100000@0x00200000(BOOTFIP_2),0x00100000@0x00300000(BOOTFIP_3),0x00080000@0x00400000(BOOTTERM1),0x00080000@0x00500000(BOOTTERM2),0x00100000@0x00600000(BOOT_A_0),0x00100000@0x00700000(BOOT_B_0),0x00100000@0x00800000(BOOT_A_1),0x00100000@0x00900000(BOOT_B_1),0x00100000@0x00A00000(UBOOT_TERM1),0x00100000@0x00B00000(UBOOT_TERM2),0x00050000@0x00FB0000(SXID),0x01800000@0x01000000(KERNEL_A),0x00800000@0x02800000(CONFIG_A),0x01800000@0x03000000(KERNEL_B),0x00800000@0x04800000(CONFIG_B),0x01800000@0x05000000(SX_A),0x01800000@0x06800000(SX_B),0x00020000@0x00F30000(VERSION_INFO_A),0x00020000@0x00F50000(VERSION_INFO_B),0x00020000 [ 0.000000] 000: audit: enabled (after initialization) [ 0.000000] 000: Dentry cache hash table entries: 131072 (order: 9, 2097152 bytes, linear) [ 0.000000] 000: Inode-cache hash table entries: 65536 (order: 7, 524288 bytes, linear) [ 0.000000] 000: mem auto-init: stack:off, heap alloc:off, heap free:off [ 0.000000] 000: Memory: 746884K/786432K available (6718K kernel code, 854K rwdata, 1648K rodata, 704K init, 329K bss, 39548K reserved, 0K cma-reserved) [ 0.000000] 000: SLUB: HWalign=64, Order=0-3, MinObjects=0, CPUs=4, Nodes=1 [ 0.000000] 000: ftrace: allocating 23664 entries in 93 pages [ 0.000000] 000: rcu: Preemptible hierarchical RCU implementation. [ 0.000000] 000: rcu: RCU event tracing is enabled. [ 0.000000] 000: rcu: RCU restricting CPUs from NR_CPUS=8 to nr_cpu_ids=4. [ 0.000000] 000: rcu: RCU priority boosting: priority 80 delay 500 ms. [ 0.000000] 000: rcu: RCU_SOFTIRQ processing moved to rcuc kthreads. [ 0.000000] 000: No expedited grace period (rcu_normal_after_boot). [ 0.000000] 000: Tasks RCU enabled. [ 0.000000] 000: rcu: RCU calculated value of scheduler-enlistment delay is 100 jiffies. [ 0.000000] 000: rcu: Adjusting geometry for rcu_fanout_leaf=16, nr_cpu_ids=4 [ 0.000000] 000: NR_IRQS: 64, nr_irqs: 64, preallocated irqs: 0 [ 0.000000] 000: random: get_random_bytes called from start_kernel+0x33c/0x4b0 with crng_init=0 [ 0.000000] 000: arch_timer: cp15 timer(s) running at 60.00MHz (virt). [ 0.000000] 000: clocksource: arch_sys_counter: mask: 0xffffffffffffff max_cycles: 0x1bacf917bf, max_idle_ns: 881590412290 ns [ 0.000000] 000: sched_clock: 56 bits at 60MHz, resolution 16ns, wraps every 4398046511098ns [ 0.008552] 000: Calibrating delay loop (skipped), value calculated using timer frequency.. [ 0.016871] 000: 120.00 BogoMIPS (lpj=60000) [ 0.021129] 000: pid_max: default: 32768 minimum: 301 [ 0.026307] 000: Mount-cache hash table entries: 2048 (order: 2, 16384 bytes, linear) [ 0.034005] 000: Mountpoint-cache hash table entries: 2048 (order: 2, 16384 bytes, linear) [ 0.048359] 000: ASID allocator initialised with 32768 entries [ 0.050341] 000: rcu: Hierarchical SRCU implementation. [ 0.061390] 000: smp: Bringing up secondary CPUs ... [ 0.078677] 001: Detected VIPT I-cache on CPU1 [ 0.078755] 001: CPU1: Booted secondary processor 0x0000000001 [0x410fd034] [ 0.095799] 002: Detected VIPT I-cache on CPU2 [ 0.095858] 002: CPU2: Booted secondary processor 0x0000000002 [0x410fd034] [ 0.112970] 003: Detected VIPT I-cache on CPU3 [ 0.113025] 003: CPU3: Booted secondary processor 0x0000000003 [0x410fd034] [ 0.113160] 000: smp: Brought up 1 node, 4 CPUs [ 0.113184] 000: SMP: Total of 4 processors activated. Finally, when the UT completes its boot process we are greeted with a login prompt: Development login enabled: no SpaceX User Terminal. user1 login: While making a few attempts at guessing valid login credentials we started realising that this UART interface would be unlikely to result in an easy win. We had to go deeper. Teardown: Level 2 The back metal cover of the UT is glued to the assembly around the outer edge and additional glue is applied between the ribs in the metal cover and the underlying PCB. To loosen the glue at the edge of the metal cover we used a heat gun, prying tools, isopropyl alcohol and a lot of patience. Specifically, we first applied heat to a small section, used a prying tool to loosen that section, added IPA to help dissolve the glue and another round of the prying tool. Having removed the metal cover we are greeted by an enormous PCB measuring approximately 55 cm in diameter. The parts of interest to us are shown in the picture below. The flip-chip BGA package with the metal lid is the main SoC on this board (marking: ST GLLCCOCA6BF). Unsurprisingly the SoC is connected to some volatile DRAM storage and non-volatile flash storage in the form of an eMMC chip. Identifying eMMC test points An embedded MultiMediaCard (eMMC) contains flash storage and a controller and is quite similar to an SD-card. The UT contains a Micron eMMC chip with package marking JY976, Micron offers a convenient tool to decode these package markings to the actual part number: https://www.micron.com/support/tools-and-utilities/fbga. The eMMC chip in question has part number MTFC4GACAJCN-1M and contains 4GB of flash storage in a BGA-153 package. In most scenarios we would desolder such an eMMC chip, reball it and dump it using a BGA socket. However, in this case we first attempted to dump the eMMC in-circuit to minimize the odds of damaging our UT and the eMMC chip. eMMC chips are similar to SD cards in that they share a similar interface; the eMMC chip does support up to 8 data lines whereas SD-cards support up to 4 data lines. Both eMMC chips and SD-Cards support the use of only a single data line at the cost of lower read/write speeds. To read the eMMC chip in-circuit we have to identify the clock (CLK), command (CMD) and data 0 (D0) signals. The 10 test points above the main SoC drew our attention, as 10 test points could be a CMD, CLK and 8 data lines. Additionally, all of these test points have a 30 Ohm series resistor connected to them which is relatively common for eMMC connections. We soldered a short wire to each test point, allowing us to create a logic analyser capture during the UT boot process. Using such a capture it is relatively straightforward to identify the required signals. The CLK signal will be the only repetitive signal, CMD is the signal that is first active after the clock starts toggling and D0 is the first data line to send out data. Determining the remaining 7 data lines is luckily unnecessary to dump the eMMC contents. Dumping the eMMC in-circuit To dump the eMMC chip we can connect a reader (that supports 1.8V IO) to the identified test points. Commercial readers that are mostly aimed at phone repair exist and should work well for this purpose (e.g. easy-JTAG and Medusa Pro). Alternatively you can use a regular USB SD-card reader (one that supports 1-bit mode) with an SD-card breakout with integrated level-shifters (e.g. https://shop.exploitee.rs/shop/p/low-voltage-emmc-adapter ). You can also whip something up yourself if you have some parts laying around. The picture below shows a standard USB SD-card reader connected to a TI TXS0202EVM level-shifter breakout board. We only provide power to the eMMC to prevent the main SoC from interfering. The eMMC can be powered through two nearby decoupling capacitors, 3.3V is provided by the SD card reader and 1.8V is provided using a lab power supply. Once everything is hooked up properly we can create a disk image for later analysis. Note that reading eMMC in circuit is not always an easy task; wires that are slightly too long can already prevent reading from succeeding. In this case it was rather straightforward and the system appears to function normally even with these relatively long wires attached. Unpacking the raw eMMC dump Unfortunately, Binwalk was not able to extract the full filesystem hence a manual analysis was required. From the boot log it was clear that U-Boot was loading 49152 blocks of data starting at block 98304. Meaning that U-Boot is reading 0x1800000 bytes (blocksize of 512 (0x200) bytes) starting from address 0x3000000. We also know from the U-Boot output that this chunk of data is a FIT image. However, when trying to read the FIT image header information using the dumpimage tool (part of the u-boot-tools package) we weren’t getting any useful information. Luckily SpaceX released their modifications to U-Boot on Github for GPL compliance: https://github.com/SpaceExplorationTechnologies By looking at this code it became clear that certain parts of the firmware are stored in a custom format that contains Error Correcting Code (ECC) data. Stripping Reed-Solomon ECC words The file spacex_catson_boot.h contains interesting information related to how the device boots. The following snippets show how data is being read from eMMC (mmc read8) and the definition for startkernel. 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 #define SPACEX_CATSON_COMMON_BOOT_SETTINGS \ "kernel_boot_addr=" __stringify(CATS_KERNEL_BOOT_ADDR) "\0" \ "kernel_load_addr=" __stringify(CATS_KERNEL_LOAD_ADDR) "\0" \ "kernel_offset_a=" __stringify(CATS_KERNEL_A_OFFSET) "\0" \ "kernel_offset_b=" __stringify(CATS_KERNEL_B_OFFSET) "\0" \ "kernel_size=" __stringify(CATS_KERNEL_A_SIZE) "\0" \ "setup_burn_memory=mw.q " __stringify(CATS_TERM_SCRATCH_ADDR) " 0x12345678aa640001 && " \ "mw.l " __stringify(CATS_TERM_LOAD_ADDR) " 0xffffffff " __stringify(CATS_BOOTTERM1_SIZE) " && " \ "mw.l " __stringify(CATS_TERM_TOC_SER_ADDR) " " __stringify(CATS_TERM_TOC_SER_VAL) "\0" \ "startkernel=unecc $kernel_load_addr $kernel_boot_addr && bootm $kernel_boot_addr${boot_type}\0" \ "stdin=nulldev\0" #define SPACEX_CATSON_BOOT_SETTINGS \ SPACEX_CATSON_COMMON_BOOT_SETTINGS \ "_emmcboot=mmc dev " __stringify(CATS_MMC_BOOT_DEV) " " __stringify(CATS_MMC_BOOT_PART) " && " \ "mmc read8 $kernel_load_addr ${_kernel_offset} $kernel_size && " \ "run startkernel\0" \ "emmcboot_a=setenv _kernel_offset $kernel_offset_a && run _emmcboot\0" \ "emmcboot_b=setenv _kernel_offset $kernel_offset_b && run _emmcboot\0" The definition of startkernel is particularly interesting as it shows how the address where the kernel was loaded is being passed to a command called unecc. From the unecc command definition it is quite clear that this functionality is performing error correction on the data read from the eMMC. 1 2 3 4 5 6 7 8 9 10 U_BOOT_CMD( unecc, 3, 0, do_unecc, "Unpacks an ECC volume; increments internal ECC error counter on error", "<source> <target>\n" "\tReturns successfully if the given source was successfully\n" "\tunpacked to the target. This will fail if the given source\n" "\tis not an ECC volume. It will succeed if bit errors were\n" "\tsuccessfully fixed.\n" "\t<source> and <target> should both be in hexadecimal.\n" ); The unecc command calls the do_unecc function implemented in unecc.c. Eventually this will result in calling the ecc_decode_one_pass function defined in ecc.c. 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 /** * Decodes an ECC protected block of memory. If the enable_correction * parameter is zero, it will use the MD5 checksum to detect errors and will * ignore the ECC bits. Otherwise, it will use the ECC bits to correct any * errors and still use the MD5 checksum to detect remaining problems. * * @data: Pointer to the input data. * @size: The length of the input data, or 0 to read until the * end of the ECC stream. * @dest: The destination for the decoded data. * @decoded[out]: An optional pointer to store the length of the decoded * data. * @silent: Whether to call print routines or not. * @enable_correction: Indicates that the ECC data should be used * to correct errors. Otherwise the MD5 checksum * will be used to check for an error. * @error_count[out]: Pointer to an integer that will be incremented * by the number of errors found. May be NULL. * Unused if !enable_correction. * * Return: 1 if the block was successfully decoded, 0 if we had a * failure, -1 if the very first block didn't decode (i.e. probably * not an ECC file) */ static int ecc_decode_one_pass(const void *data, unsigned long size, void *dest, unsigned long *decoded, int silent, int enable_correction, unsigned int *error_count) ecc.h contains several relevant definitions: 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 #else /* !NPAR */ #define NPAR 32 #endif /* NPAR */ /* * These options must be synchronized with the userspace "ecc" * utility's configuration options. See ecc/trunk/include/ecc.h in the * "util" submodule of the platform. */ #define ECC_BLOCK_SIZE 255 #define ECC_MD5_LEN 16 #define ECC_EXTENSION "ecc" #define ECC_FILE_MAGIC "SXECCv" #define ECC_FILE_VERSION '1' #define ECC_FILE_MAGIC_LEN (sizeof(ECC_FILE_MAGIC) - 1) #define ECC_FILE_FOOTER_LEN sizeof(file_footer_t) #define ECC_DAT_SIZE (ECC_BLOCK_SIZE - NPAR - 1) #define ECC_BLOCK_TYPE_DATA '*' #define ECC_BLOCK_TYPE_LAST '$' #define ECC_BLOCK_TYPE_FOOTER '!' In the end what it boils down to is that, in this implementation, an ECC protected block of memory starts with the magic header value SXECCv followed by a version byte (1). This magic value marks the start of the ECC protected data, but also the start of the header block. The header block itself contains (in addition to the magic value and version byte), 215 bytes of data, an asterisk (*), and 32 bytes of ECC code words. The header block is followed by multiple data blocks. Each of these data blocks is 255 bytes long and contains 222 bytes of data followed by an asterisk symbol (*) and 32 bytes of ECC code words. The last data block contains a dollar sign ($) instead of the asterisk and is followed by a final footer block. This footer block starts with and exclamation mark (!) that is followed by the number of data bytes in the ECC protected block of memory (4-bytes) and MD5 digest over those data bytes. At this point it should be clear why Binwalk did not succeed in extracting the kernel, initramfs and FDT. Binwalk is able to pick up on the magic values that indicate the start of a particular file, but each block of the file had additional data that prevented Binwalk from extracting it. We used a simple Python scrip to remove the extra ECC data before using Binwalk to extract the image. Similarly, we can now also use dumpimage to get more information on the FIT image. The FIT image and board revisions The following snippet contains some of the dumpimage output. The FIT image contains 13 boot configurations, all configurations use the same kernel and initramfs images but a different Flattened Device Tree (FDT). FIT description: Signed dev image for catson platforms Created: Fri Apr 16 23:10:45 2021 Image 0 (kernel@1) Description: compressed kernel Created: Fri Apr 16 23:10:45 2021 Type: Kernel Image Compression: lzma compressed Data Size: 3520634 Bytes = 3438.12 KiB = 3.36 MiB Architecture: AArch64 OS: Linux Load Address: 0x80080000 Entry Point: 0x80080000 Hash algo: sha256 Hash value: 5efc55925a69298638157156bf118357e01435c9f9299743954af25a2638adc2 Image 12 (rev2_proto2_fdt@1) Description: rev2 proto 2 device tree Created: Fri Apr 16 23:10:45 2021 Type: Flat Device Tree Compression: uncompressed Data Size: 59720 Bytes = 58.32 KiB = 0.06 MiB Architecture: AArch64 Load Address: 0x8f000000 Hash algo: sha256 Hash value: cca3af2e3bbaa1ef915d474eb9034a770b01d780ace925c6e82efa579334dea8 Image 15 (ramdisk@1) Description: compressed ramdisk Created: Fri Apr 16 23:10:45 2021 Type: RAMDisk Image Compression: lzma compressed Data Size: 8093203 Bytes = 7903.52 KiB = 7.72 MiB Architecture: AArch64 OS: Linux Load Address: 0xb0000000 Entry Point: 0xb0000000 Hash algo: sha256 Hash value: 57020a8dbff20b861a4623cd73ac881e852d257b7dda3fc29ea8d795fac722aa Default Configuration: 'rev2_proto2@1' Configuration 0 (utdev@1) Description: default Kernel: kernel@1 Init Ramdisk: ramdisk@1 FDT: utdev3@1 Sign algo: sha256,rsa2048:dev Sign value: bb34cc2512d5cd3b5ffeb5acace0c1b3dd4d960be3839c88df57c7aeb793ad73a74e87006efece4e9f1e31edbb671e2c63dc4cdcb1a2f55388d83a11f1074f21a1e48d81884a288909eb0c9015054213e5e74cbcc6a6d2617a720949dcac3166f1d01e3c2465d8e7461d14288f1a0abef22f80e2745e7f8499af46e8c007b825d72ab494f104df57433850f381be793bfe06302473269d2f45ce2ff2e8e4439017c0a94c5e7c6981b126a2768da555c86b2be136d4f5785b83193d39c9469bd24177be6ed3450b62d891a30e96d86eee33c2cbfc549d3826e6add36843f0933ced7c8e23085ee6106e3cc2af1e04d2153af5f371712854e91c8f33a4ea434269 From the U-Boot code (spacex_catson_uterm.c) it becomes clear that the boot configuration is decided based on the state of 5 GPIO pins. 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 /** * Check board ID GPIOs to find board revision. * The board IDs are mapped as follows * id_b0:pio12[2] * id_b1:pio12[3] * id_b2:pio12[0] * id_b3:pio12[1] * id_b4:pio20[4] */ u32 pio12 = readl(BACKBONE_PIO_A_PIO2_PIN); u32 pio20 = readl(BACKBONE_PIO_B_PIO0_PIN); u32 board_id = (((pio12 >> 2) & 1) << 0) | (((pio12 >> 3) & 1) << 1) | (((pio12 >> 0) & 1) << 2) | (((pio12 >> 1) & 1) << 3) | (((pio20 >> 4) & 1) << 4); /* * https://confluence/display/satellites/User+Terminal%3A+Catson+ID+Bits */ switch (board_id) { case 0b11111: board_rev_string = BOARD_REV_1_1P3; break; case 0b11100: board_rev_string = BOARD_REV_1_2P1; break; case 0b11000: board_rev_string = BOARD_REV_1_2P2; break; case 0b10100: board_rev_string = BOARD_REV_1_3P0; break; case 0b10000: /* rev1 pre-production */ board_rev_string = BOARD_REV_1_PRE_PROD; break; case 0b11110: /* rev1 production */ board_rev_string = BOARD_REV_1_PROD; break; case 0b00001: board_rev_string = BOARD_REV_2_0P0; break; case 0b00010: board_rev_string = BOARD_REV_2_1P0; break; case 0b00011: board_rev_string = BOARD_REV_2_2P0; break; } } printf("Detected Board rev: %s\n", board_rev_string); The following picture shows where these pins are being pulled high/low to indicate the board revision. Note from the earlier serial bootlog that our UT boots using the rev2_proto2 configuration (case 0b00011). In a recent video Colin O’Flynn pulled some of these pins high/low and could observe that the UT tried booting using a different FIT configuration and thus different devicetree [5]. We compared some of the FDTs but did not spot any differences that would be interesting from a security perspective. A first look at the firmware The login prompt Recall that after the boot process has completed we are greeted with a login prompt. For further research it would be useful to gain the ability to log in, allowing us to interact with the live system. However, by looking at the shadow file it becomes clear that none of the users are allowed to log in. During boot the UT does read a fuse to determine if it is development hardware or not. If the UT is unfused it will set a password for the root user, allowing log in. Starlink UTs that are sold to consumers are of course production fused, disabling the login prompt. 1 2 3 4 5 6 7 8 9 10 root:*:10933:0:99999:7::: bin:*:10933:0:99999:7::: daemon:*:10933:0:99999:7::: sync:*:10933:0:99999:7::: halt:*:10933:0:99999:7::: uucp:*:10933:0:99999:7::: operator:*:10933:0:99999:7::: ftp:*:10933:0:99999:7::: nobody:*:10933:0:99999:7::: sshd:*::::::: Development hardware Development hardware often finds its way into the wrong hands [6, 7]. The engineers at SpaceX considered this scenario and appear to try to actively detect unfused development hardware that is no longer under their control. Development hardware is geofenced to only work in certain predefined areas, most of which are clearly SpaceX locations. SpaceX is likely notified if development hardware is used outside these predefined geofences. Interestingly, some of these geofences do not seem to have a clear connection to SpaceX. While we will not disclose these locations here, I will say that the SNOW_RANCH looks like a nice location to play with development hardware. Secure element From references in the firmware it became clear that (our revision of) the UT contains a STMicroelectronics STSAFE secure element. The purpose of the secure element is not entirely clear yet, but it may be used to remotely authenticate the UT. The SoC Some people have asked which processor is being used: the answer is a Quad-Core Cortex-A53 and each core has been assigned a specific task. 1 2 3 4 5 6 7 8 9 10 11 12 13 14 ############################ # System Information ############################ # # The user terminal phased-array computers are Catson SoCs with a quad-core # Cortex-A53. # # We dedicate one core to control, while leaving the other three to handle # interrupts and auxiliary processes. # # CPU 0: Control process. # CPU 1: Lower-MAC RX process. # CPU 2: Lower-MAC TX process. # CPU 3: PhyFW and utility core - interrupts, auxiliary processes, miscellaneous What’s next That’s it for now. We will likely continue looking into the Starlink UT and provide more details in future blog posts if there is interest. At the time of writing we were able to obtain a root shell on the UT, but it’s too early to publicly share more information on that matter. References [1] MikeOnSpace – Starlink Dish TEARDOWN! – Part 1 – https://youtu.be/QudtSo5tpLk [2] Ken Keiter – Starlink Teardown: DISHY DESTROYED! – https://youtu.be/iOmdQnIlnRo [3] The Signal Path – Starlink Dish Phased Array Design, Architecture & RF In-depth Analysis – https://youtu.be/h6MfM8EFkGg [4] MikeOnSpace – Starlink Dish TEARDOWN! – Part 2 – https://youtu.be/38_KTq8j0Nw [5] Colin O’Flynn – Starlink Dishy (Rev2 HW) Teardown Part 1 – UART, Reset, Boot Glitches – https://youtu.be/omScudUro3s [6] Brendan I. Koerner – The Teens Who Hacked Microsoft’s Xbox Empire – https://www.wired.com/story/xbox-underground-videogame-hackers/ [7] Jack Rhysider – Darknet Diaries EP 45: XBOX UNDERGROUND (PART 1) – https://darknetdiaries.com/episode/45/ Sursa: https://www.esat.kuleuven.be/cosic/blog/dumping-and-extracting-the-spacex-starlink-user-terminal-firmware/
    1 point
  3. Mai bine scoate de acolo cat oferi si te intelegi cu omul. Nu o sa te apeleze nimeni la ce ai scris acolo.
    1 point
×
×
  • Create New...