Hello everyone. Thank you very much for having me. Yesterday we were going to be talking about physical attacks against smartphones. So the crux of this talk is that I was seeing a huge number of different conference talks about extremely complex attacks against smartphones due to the high measures of security that are placed on them from the boot level all the way up to the high level OS. Despite this, there are still times when very simple techniques can be used to bypass the security on smartphones and escalate privileges or get unauthorised access in ways that you would consider very simple in a general sense. So we're going to be doing two 20-minute case studies for this. The first one is going to be gaining root access on a smartphone with no bootloader unlocking capability. This is where the manufacturer removes the ability to unlock the bootloader and root it by itself. And the second is going to be gaining code execution in the bootloader of a Samsung smartphone in order to bypass secure boot and execute your own kernel and do other malicious things. So case study one, rooting on a locked bootloader. Essentially I bought a brand new phone and wanted to root my old one so that I could use it for app tech testing and that sort of thing. Install mode certificates, ad reader, et cetera. However, on this particular device, the manufacturer had gone into the code of the bootloader and removed the checks to allow you to access the USB interface. This meant that I would never be able to get into the fast boot mode and unlock a bootloader, add root access and that sort of thing. OEMs very rarely do this and they usually just add restrictions onto the bootloader that requires them to you to sign up with their services in order to do this properly. The target device was a smartphone from a Chinese OEM released in 2019 that used an OEM developed for Android which had its own security features and other tweaks to it that were going to be the target of this particular project. So while I say that it didn't have bootloader and locking capabilities in the traditional sense, what it did have was a special engineering app that permitted bootloader and locking. This used a signature stored in a partition on the device which was inaccessible to standard users but could then be used as an engineering app with special permissions and written into it. And then when the device rebooted it would give other engineering level access. It was not publicly available though there were some leaks online and required an approved user account which was a long-winded process I didn't want to go through. So when bootloader and locking isn't available it's obvious that you're going to need some kind of exploit in order to escalate privilege to root. And with no direct access to the bootloader USB interface which is my standard approach for attacking a device like this a vulnerability was needed in the Android fork itself. I didn't think I'd find anything in Android that would be particularly actionable in this sense and I thought the changes that I'd made to it would be probably the area where I'd find the most critical vulnerabilities I could use. What I found was the Android fork contained a high number of custom system and root level applications which could be potentially exploited in different ways. So the Android fork had a service running as a root at all times that was called by the system level applications for the facilitation of cloud upload and archiving of app data so we would take all the data from the users protected application called and off partitions package it all together and upload it to the cloud where it could be downloaded again if needed. Brief analysis of this binary found that it had an immediate command injection vulnerability where if you had a file within the file system with back ticks in the name you could execute commands within it. What would happen is you would upload this file and then download it again and as it was restoring the file it would then execute whatever command was in the back ticks so very basic. Unfortunately for me Android also employs SE Linux which is an extremely strong security measure to cordon off different components of the operating system even if they are all running as root. This meant that even though I had root access superficially I only had access to the app data sections of the device rather than having the access to other components I wanted to modify. I found that pretty much every instance of a command injection I could find on the device had a similar issue so I'd have to find another way of getting escalated privileges. Most vulnerabilities that are limited by SE Linux context could probably be bypassed with a kernel exploit however a kernel exploit is a very complex thing to do and not something you want to be doing for a very basic simple project you're just doing in your spare time. As the boot loader was locked down and the OS exploits were out of the question I decided to go for my next specification which would be recovery mode on the device. Recovery mode on an Android device traditionally is a very simple menu which you use the volume buttons and the power button in order to navigate through it. I found that on this Android 4 they'd actually updated this to include Wi-Fi access access to more parts of external storage and a few other options as well as having the touchscreen enabled which I found was due to the fact that they'd taken their Android kernel and dumped it into the recovery partition meaning that if I'd gain access to it I'd have access to all the same hardware components the traditional Android operating system was. I wanted to find an update image for the entire operating system of the device so that I could extract recovery and then find a simple vulnerability. Unfortunately downloading the updated the update files for this device found that they never updated the recovery partition meaning that I couldn't find it within the operating system. That meant that I would have to work out any vulnerabilities blind and just guess and just try things until something worked. So yeah, with no recovery image to reverse engineer I just tried very basic attacks of again with. As the menu option included the option to load in these encrypted zip files the OTA update images I decided to attempt those first. So as I found a command injection of vulnerability in the high-level operating system I thought I would probably find one in the recovery image as well. So I took a legitimate encrypted update file for the device and renamed it to contain Bactics and Sleep 30000. What happened is if I had successfully executed this command the phone would be spending a few hours trying to update itself with never succeeding. Yes, and this did indeed cause the update process to hang demonstrating that I'd found yet another command injection of vulnerability in the device. I disclosed all the command injection of vulnerability sites found to the OEM who very very swiftly remediated them and updated new versions of the software. But as the recovery mode command injection was very likely to be running as root and have no restrictions on it this would be a good basis for me to then gain further root access to Android. So I started with root cause analysis just so I could get out of the way and found that it was a SHA-1SUM check for some logging that was checking data on the SHA-1SUM of the update file which was then just executing the Bactics because there was a sprintf into an exec command so very basic. As there was a command injection of vulnerability in the file name this could probably be used to update a more complex script. So if I wrote a more complex script a base 64 encoded it and piped it into a system bin SH a shell script could then be loaded to this more complex from the file system and executed so this script here literally just cats from the user data partition a much more complex script that can be used. Unfortunately the file system used by Android's user data does not support all special characters for instance the pipe character I would need to perform as exploit so I would have to find a way around this. Luckily I found that they had modified the recovery image to also support which is rare on Android and usually when you put in the XT4 SD card into an Android device it says unsupported file system and then tries to format it. Luckily for me it didn't do that so I could just load my more complex update file onto that and execute it. So I wanted to get a more concrete shell on the device so I would have a look around and also work out what was going on in a more accessible manner. So what I did was I run the IT command and run it into the user data partition so that if I wanted to reboot the phone I would then find it was running ID root or ID system or what was going on. I also wanted to see if I could disable SE Linux to bypass all of the context that were there and found that that also worked and then I also wanted to enable ADB on the device so I had a root shell into recovery which also worked quite well. So root access and recovery mode is great but you've then got a phone that's in a very not very fairly fleshed out mode I can't access any apps from there I can't modify my files in any real way and I can't usually access the internet Bluetooth or anything like that. What I wanted to do was find a way to switch from recovery to Android without ever having to reboot the device and go to the bootloader because as soon as I do that I would lose my shell on the device because there was no persistence in an attack like this. My first pull of call was to try to use Kexec now Kexec is a kernel component which allows you to load a new Linux kernel onto a Linux device and then execute that essentially switching from one Linux kernel to another. If I could do that that would be a very quick way for me to switch to the Android kernel and everything else but unfortunately even compiling the module from scratch was blocked because it was using some deny listed module components so I decided to try to do something that was in the user space rather than in the kernel itself. Luckily there was Ptrace as a system call allowing one process to observe and control another for debugging purposes. Typically this is for things like logging and tracking and debugging on things that are running on the operating system and doing things like the Strace command within Linux. It can even modify memory that is right denied in the standard processes which means you can modify running code even if they are not meant to be able to do that in the particular elf that you're working with. What I wanted to do was use Ptrace to essentially latch on to the init process and restart that but in the Android context. So init is always process ID one which means that it has some special privileges within Linux and also it has a lot of control over the rest of the system. What I wanted to do was use the execute command which executes a command within one process that uses the same process ID to run more commands that would then get me to switch out init. Luckily for me if I did this I could execute init but never have to return back to it. I could just keep things going as one long process switching from one data to the other. This could be very tribly done with a bit of assembly code so just moving in the parameters and then executing the service call. Switch route is what's used during the boot process usually to switch from the init ramfs so the ramdisk which contains some of the lower level stuff for mounting the more complex file systems into the new one. It's a very common feature on Linux based devices and what I intended to do was switch from one init ramfs to the Android init ramfs which would then load into the system operating system. This could be very easily done if I just mounted a new ramdisk and then loaded the data in and then hopefully I could then switch it instead if I needed. So the process for init usually looks like you have the init process that starts as one then it sets up SE Linux and then it does init second stage which has all the hardware set up and everything and that's where the process sits most of the time. Essentially what I wanted to do was inject in a switch route command into init which would then start the whole process again killing the old recovery process and introducing a new one that was running Android. There are a few caveats with this however because the ones really intended to switch from one init ramfs to another and you're meant to reboot to get into other systems like this. So a core component of switch route is the remounting of mounted folders however most of the mounted folders that occur in Android at this point are shared. This means they're handled in slightly different ways than how you expect when it comes to things like moving the mounts to different places. However this could be tribly resolved by using a small shell strip that went through all the mounts found out if they were shared and made them private instead and private means Also I found that init binary was checking proc command line within the file system for whether the image required SE Linux to be enabled and if it did and it found it was disabled it would enable SE Linux forcibly re-enabling it even though I disabled it. Luckily for me ptrace allows you to override system calls so I modified the read system call whenever it touched the proc command line file to override the check for enforcing SE Linux with one that allowed it to be permissive which was nice and easy. I also found that this caused a lot of kernel panics because init also does all the system hardware services setup. This includes things like saying go out of the wife interface bluetooth etc but the recovery operator side of the things had already done this so doing this again caused the kernel to not really know what to do. What I did was in the same way as I did with proc command line just make it return empty files whenever it tried to access these .rc files. I did this to modify them within the file system which would cause the device to not be able to work in a non-rooted manner. I also found that when I tried to unlock my phone after getting through this entire process and getting it to boot that I could no longer use my pin because all of the security services were still running in the recovery context. Luckily for me I could just kill all these processes and let it restart them again right as I was starting this whole process up. While this was pretty much a read only file, by re-rooting the device I'd lose all of this root access. What I could do was still override some read only files. The system partition which stores a lot of the system data is a read only file system. It uses dm verity to make sure it's got appropriate signatures working throughout the file system. However if you use the mount-bind command you can override the files there temporarily with your own meaning that if I wanted to modify for instance frameworks which had root detection in and things like that I just need to do that temporarily and it would work without damaging the device in any way. I'm going to do a quick demo of this boot process now before I move on to the next one. Hopefully this won't go to the next one. Brilliant, sorry guys. As you can see I've just pressed my little commander and now it's running through the init process. It's running through the files recovery which was running the screen at that point and starts the Android process booting up. Then starting the full Android operating system and giving me root access. I also found the trend off the phone when I started this I needed to reboot the screen otherwise I couldn't use the touchscreen. I have a telnet root backdoor into the device. Thank you. I observed something quite interesting after this. I was quite happy to have root access but I realised that during the debugging process I'd kept a busybox telnet server within the recovery context of the device. When I'd remounted the new init RAM FS I'd found that the old recovery one was still sitting in memory and accessible. So there was a telnet service running in a file system that Android had no idea about. Switch root had deleted all the files within this file system because it was stored in RAM but just using busybox I could repopulate all the tools and it gave me this secret little section of the device which Android could have access to. Because it was hidden from Android I could do a lot of interesting things accessing the hardware and stuff but I could also access the rest of Android itself without Android knowing that I was there. So by seeding or shrooting into the directory proc1root which was the root file system that the init process is using recovery could access the Android root file system as root without Android knowing about it which was fantastic. What I decided to do was expand this out however and add a whole Debian root file system to it. So I had a lot of debugging and testing tools that I could also use to continue to compromise the device in further ways. So in conclusion root access to this method was very consistent. I left the thing running with the init parasite ptrace tool attached to it for days at a time without any crashes. They would just keep running and running and running and no problem whatsoever. I also found that just by rebooting the device I had no effect and it could operate normally going back to a standard way. And I also found that the biggest benefit for this whole project was having ptrace there so if you're compiling a kernel do remove that if you need to. Now we've gone to the second case study which is a bit more technical and a bit more exciting because we're not going for a device that I wanted to root for my own purposes but I just wanted to exploit in some way. So external space devices have had a significant amount of research done on them on this stage and at Black Hat we've focused on the download mode of the bootloader so this is a high level protocol used by Samsung to write and read files in different ways and debug the device and unbreak it in many ways. Because it all focused on the high level download protocol I decided to start a project to try and manipulate the low level USB stack that was in use to see if I could find a vulnerability that was as actionable as what had already been found. For this I found the cheapest Samsung device I could that was still a decent Samsung Galaxy A04S which was actually quite a decent phone after I bought it. It was released in August 2022 and used an Exynos 850 chip set and I knew that it would be quite an interesting target because it had a lot of the security features like NOX in place that more expensive, more modern or more higher end Samsung devices do. So the secondary bootloader which is what I was going for with this project is called S-boot in Samsung and it facilitates a few things. It facilitates standard boot from the primary bootloader and it facilitates download mode which is the protocol we're just talking about. On my device it also had fast boot mode which is the standard Android administration's bootloader tool and upload mode which is what's usually found when you hit an unrecoverable error in some way. All of this was encompassed in a single firmware binary called sboot.bin but because of this I thought all three USB protocols so download, fast boot and USB would probably be using the core USB stack underneath and it would have broken all of those in one go. So when I'm talking about the core USB stack I'm talking about USB control transfers. So control transfers are used to send and receive like debugging information, or not debugging information, configuration information about the device. Sometimes it's used for more complex things for instance iPhone and DFU modes also use control transfers but generally there's a very standardised approach for these and they use standard parameters which are BM request type, B request, so what I really wanted to do was just fuzz it and find an actual exploit just by running a very basic fuzz it. Now control transfers are mostly extremely stateless. They do their own thing, you read and write data and at a very high level there's just not much else you need to do. With this you can just randomise all the parameters and send a randomised buffer size with randomised data in it and see what happens. So as you can see there my very complex fuzz it way better than AFL of rand, rand, rand, rand for every parameter. As you can see on the right when I was running this you'll see the minus nine errors which are Lib USB errors which is where the device has gone I don't know what the hell to do with this. All the ones without the minus is where data has been transferred back and forth so very simple to keep track of. However during my initial fuzzing attempts I was sending purely random data and it caused the device to reboot into a failure mode that I couldn't recover from. Every time I tried to reboot it said the same thing an error has been done but it occurred updating the device software and I thought I'd now got a brick on my hands. This occurred when the OXF6 value was sent as the B request parameter which was very interesting because I didn't know why that would be because it's not a standard commander or anything like it. However I found it was recoverable and back to a working device by using the download mode tool so I used the command line tool in Heimdall which is an open source tool for manipulating download mode that's accessible on GitHub and as soon as I tried to do anything with that tool the device decided it was working again so clearly it just didn't like my tool. So I kept fuzzing and fuzzing and fuzzing for about half an hour and found that the device would crash and reboot after a certain set of transfers. Luckily I had a seed in this fuzzing so I knew exactly what could be done and I could just run the hole on target fuzz again and see what happened. What I did was essentially remove transfers in the sequence to see which ones were actually causing the crash in the first place and essentially got that down to two control transfers over about 10,000 which was nice. The first transfer was a malformed get descriptor request so in that instance it's got get and it was sending data instead of receiving it and the second was a valid get descriptor request which was causing the crash. Now get descriptor is a core component of the USB stack and it's control transfers that retrieves descriptors about the device. These are configuration data which includes things like strings about who manufactured the device ID's and also what the device does which is very nice. In these descriptors the first byte of the data is always going to be the size of the buffer itself so you can see B length is 18 which is the size and if you can overwrite this you can then make your memory access push into the linked list next to it which is where the other descriptors are stored usually. So what's interesting is most USB stacks don't check the control transfer direction. They're usually protected by how their own USB hardware works so they have send and receive functions so for instance in this case this is the STM32 USB D stack where if you send it a get device descriptor request it will explicitly send a control send data request to its own hardware meaning that it can't receive data back from it. However in this instance I could send data to it meaning that I had full control overwriting data in memory which was very nice. So what I did was I tried to overwrite that first byte just by sending data to the same memory that was there however this was ineffective and it did change the byte however it didn't alter the size of the data received. Luckily for me there was just a buffer overflow there anyway so I was quite happy. Because of this the data next to the buffer could be overwritten but I didn't know what there was there yet but I could just try and guess. So by sending a large buffer that caused the device to crash I knew that I had a traditional buffer overflow hitting something so I decided to do a binary check until I found a data size that didn't cause the device to crash. Then I made that size one byte larger and saw if it crashed and then if it did crash changed the value of that last byte incrementing by one until I found a value that didn't crash. Essentially it was brute forcing my way up via JSON memory until I found fully working memory that I could then manipulate if I wanted. What was excellent about this was next to it was a link list to other descriptors which would then be overwritten themselves and this had two key benefits to me. Number one this could be used for a cold boot attack. So for instance if I had someone's something phone and rebooted it the memory wouldn't be cleared at that time and I could dump the entirety of memory at EL1 so all of the external RAM and then get their secrets out of it something they'd been typing, anything that was stored in RAM at that time. The second thing I could do was write to all of that data as well including to the boot loader. So the first thing I did was when I dumped the memory of the device so I knew the memory layout of the boot loader itself so I could then manipulate it later. So I found that all of the pointers I was looking at were between OXF9 and 6.0s and OXF8 and 6.0s. So I made a memory dump of a bit of data right before that just to see if I could find the code of the boot loader itself right next to the RAM which is what I expected. Luckily for me the boot loader could start at OXF8 and 5.0s which meant that I could then dump it and just use it in GEDA if I need it to. What I really wanted to do was get code execution so I could then modify the functionality of the device to simply bypass the cure boot and get a bit more access to things, modify the kernel etc. But I found that they'd actually implemented depth on the device so data execution prevention meaning that I couldn't overwrite the code in the boot loader in RAM because the memory management unit had disabled this. When I tried this it caused the device to hang because it hit a hardware error and it was configured well. And trying, however, I found that attempting to execute code outside of the code that had been allocated for the boot loader was possible. So if I just dumped a bunch of code just outside of what had been mapped already I could execute code from anywhere at the same exception level as the boot loader itself. So with this I could patch in new functions if I wanted to and when I'm writing even exploits of boot loaders I like doing this in C. And just by using the GCC static no-lib flags and using object copy you can create a raw memory of any functions you're writing as long as you're not using standard libraries. So you would have to re-implement mem copy but you've still got a lot of ease overwriting ARM assembly all day. And because I could write these into directly into memory if I wanted to then write into the stack to point to them that would be very easy as well but I had another idea instead. So fast boot mode was used to the basis of this exploit because I just really like fast boot mode but also because it uses string based commands for all of its functions you'll find on boot loaders using fast boot is there will be a table of strings for the commands themselves and then point us to specific functions. And this is usually stored in writable RAM regardless of where it is because they're loaded in via other functions and by modifying this table it would allow me to have easy code execution without modifying the stack that I need to do other complex things. I found that fast boot in this instance wasn't really used in administration at home you had two commands which were get fire because it was easier. So the table usually looks like this so you have an address pointing to the string so reboot and then address point into the function itself. This would mean that if there were any really complex things like stack canaries in place where I could still bypass them very easily they wouldn't be a problem at this point because I was actually going to see someone loading an address itself and execute them. Because I had code execution it meant that secure boot bypass would be possible. So I could then modify the kernel without hopefully tripping knocks and add malicious code into someone's phone when it was booting and do other interesting things. However I found that none of the USB base modes so fast boot download etc had the capability of just booting the phone itself which would be a good way to hook into for this particular attack. What I would have to do was call into the boot functionality that was already there for the standard boot mode so I found that this crashed the phone itself which meant that I would actually have to implement boot functionality in a boot loader myself. So there are two options for the re-implementing the boot process. The first was to copy the entirety of working memory from the boot loader and put it somewhere where I could modify as I wanted to or just re-implement the boot functionality from scratch calling in functions that I needed to to things like set up the hardware, set up the site. That is the point because all I was doing. So functions in the boot loader could tribly be called by absolute addresses in C so in C you can literally say I want to call a function at this address and it will load it in and branch them and it can give it parameters and that is why I wanted to do so that I could just load in and check things that didn't work right etc or say change parameters or just remove functionality I didn't need for instance if the boot loader had already executed certain hardware set up I wouldn't y byddwyd yn ymlaen i am gyfrifiad i yn ôl y byddwydstei yr yma. Felly y ffordd eu gymryd ymlaen i'r newydd yn cael eu bod yn gweithio unrhyw rhaid o'i byddwyd dros y dybogwch yn ystod y gwaith yn cyfeirio, roedd y ffyrdd ymlaen i'r boedau, yn cael cefnogi, dwi'n gweithio'n job i'r cyr Polfod FxF 0700. Byd hallai'r bood pwy o gw feddwl i'ch gwir ymarfer o wahanol, gallw'r hyn yw'rhewchberg sydd i gynnal â gynnal y ffyrdd yma. Rhywbeth i wahanol i dda i'r gyda'r hyn yn gwneud y bydd hwnnw i'r bwc pwysig hynMCol yn gwneud y presbytion yn gwneud y gondig gweld yn yn gwinell. Mae'n rhoi gwneud yn tre middomeg'i booth yma, felly mae'r prysg bwysig yn eich bwysig. Maen nhw, o救 pwysig hyn, yma wrth gwrs wrth glwg. Felly sy'n rhoi'r boblodeau i'r bhwysig Eеляu Sialer Holderwyr yw ni'nouldwch y clin-dodi yn achos o erd i. Pan mae'r Mu yn gymoedd oeddaeth gyda'r cyntaf i bod ni'n rhaid i ychydigol. Rwy'n gwybod dda'r cyntaf i'n gallu amddangos a unigodd y Cymru a bach at bullywنتau cymaint o bobl ym Yngyrch Cymbr Sfiad, ymgyrch Cymbr Cymbr fel chi wedi'u annigodd ac yn ystod yn cael eu gwirioneddiaeth. Am wnaeth i adnodd ybryd o fyfiol fel ni'n fcyniau i ddweud yn dechrau'r cyntaf i ddweud is being around that the device was freezing after the kernel re-initialized the MMU. A key component of the kernel is it reinitializes a lot of the hardware registers that the bootloader has already done because they're not necessarily anymore. And so as soon as it was re-initializing the MMU with its own rear-arrangement of the memory, so setting up things like the kernel memory protection and things, it was causing the rest of the device to hang. And the reason for that was most likely going to be that the bootloader itself ac mae'n gwiswch yn ymgyrch yn ymlaen, mae'n ddweud bod yn gweithio'r ddweud yn y cwmwysgol. Mae'r Android boolod yn ystod y cyd-drygu'r gweithio arall. Mae'r Android yw'r start-up, mae'r interrupt yn ymgyrch, ac mae'r USB yn ymgyrch, ac yn ymgyrch arall, mae'n gwybod i'r adeiladau ar A-B, ac mae'n gwybod i'r Android yr adeiladau. Mae'r S-boolod yn ymgyrch i'r Arthos, ac mae'n ddweud yn ymgyrch yn ymgeisio'r ddweud, a ddweud i ddaethol cyhoedd yn ymddorol combiwnol veggies. Dydedwch yn ymddorol, maen nhw'n mynd i'r ffordd ar yr hyn ac ymddorol yn gyllidol. Pas ddod wrth gennych eich cyflym o grampau sy'n fynd, rydyn ni'n ddweud am yr lleol lle mae'n rhoi ei ddweud am dyfodol i'r hefyd yn cyffredinol, ac mae'n hynny roedd yn cerdd. Oherwydd mae'r gyfan y floseg, trafodau'r cyffredinol e'n credu eu papill i'r hefyd, Mae gennym i eu gweld i'r hollun, ac mae'n gweithio'r rydyn ni'n cwmein henderfyn ar y rai. Felly, ti'n wneud am 3 rhai ar gyfer y dyfodol, ond mae'n rhaid i gweithio'r gweithio, mae'n fynd i'r gweithio'r gweithio, mae'n allan o'r troleu'r dyfodol, i'r bobl yn gweithio, ac mae'n gweithio'r cyffredin o gyhoedd SBC, ond mae'n gweithio'r ffasbydd, ac mae'n gweithio'r gweithio'r gweithio. Llwyddo gyfaint eich hanffras, o'r cwmaint ydw'r newid gyda gennym, ac erddw i ddim drafod yma eich sut yng Nghaerdydd, ond ond nid o'r ddiolch yn Gwenllian papurau. A dwi'n cael cymaint ar gyfer y solutio cyllid yma oedd gwylio, ac nid o'r llwyddo gyda'r llwyddo ac yn oaf. Felly, y llwyddo gyhoeddol, ym nid o'r llwyddo gyfaint, ddweud yr llwyddo cyff fynd i gael i'r llwyddo, something that's very timing or security critical and also recovering from the exception wouldn't be required because we were trying to access the canal which would then resettle off the exception registers and things so I could literally just dump the canal bootstrapping code into that hopefully and get where I want it to be. So VBAR EL1 which was the table that you just saw in the last slide is a register that points to a table in memory which includes sequences of different exceptions which are stored in 128 byte chunks so every 128 bytes is a different exception type. I didn't really want to work out which exception was what so what I ended up doing was doing a knob sled throughout the entirety of the exception table into my bootstrapping code at the end of memory which would then execute it. So even with the canal booting like this and it did work it's got further down the line Android was still failing to start reverting to a special recovery mode that was telling me that the file system manager was failing. The error message that I saw was suggested that it was due to the user data partition not being decrypted so on most Android devices now user data is encrypted and using hardware key which needs to be set up during boot to make sure that you can access your files. What this implied to me is that I'd messed up somewhere and that the key storage or something else was not being enabled properly or had been broken in some manner by my bootstrapping. So analysing the logs prior to boot found that there were multiple hardware initialisations I'd missed or ignored because I was being quite lazy with this project and this was due to the fact that they'd already been initialised by fastboot that required them for other purposes. This included things like reading data and setting other things up but essentially I was running the same functions twice for setting up the TE etc. By looking at the logs I could see the error messages for instance key storage in it failed and T-gris register handler rat minus one meaning I'd have to do something to bypass this. So both of these particular functions were enabled by a very very large and complex function that would take a long time to modify or bring back from scratch however I did end up doing that by fully re-implementing it but checking for every if statement throughout the function for different self hardware initialisations and ignoring the code paths that I didn't think it would hit. However with these errors removed the phone could then complete booting to Android. So I'm going to do another demo now hopefully. So here's the phone in fastboot mode and you'll see it very quickly go into the boot screen before switching back so that screen you just saw was the one that happens when you just hold the power button on a tunnel on the phone but as part of the boot process it required it. It then shows the secured by knock screen which I'm not quite sure is true anymore at this point in the process. You'll see a flicker occasionally in the screen where the kernel is rewriting that secured by knock screen and then you'll see that disappear. Now at this point I was very excited because this was meaning that we'd bypassed all of the hard issues or the other issues I'd had in this process and we're now getting to the point where I was executing my custom modified kernel which I'll be peaking and poking into through this process. So in a second we'll see the home screen and we'll know that my modified kernel was executing which I was very happy with. So there's a lot of things that can be done with kernel code execution. You can disable security features and things like that but you have to be very careful because Samsung do put a lot of effort into making sure that there are checks in place that if you do too many scary things, knocks will blow a fuse and permanently the device will say it can't be secured in the same manner because someone's been messing with it but very easily I could modify the kernel proc version just to show you what happened in the strings. Now I did modify this further to remove things like SE Linux checks so regardless of whether it had SE Linux in place but I thought just a demonstrative picture of the version being modified was a good start for this. So some final notes on this case study. Because the exploit can now be triggered using an exception it would be much easier for me to re-implement it in the download mode which is much more common on Samsung devices which would mean that the exploit would be much more far reaching if I implemented it on a more expensive device. And while code execution was possible as I just said there was still a risk of triggering knocks however I didn't manage to do that during my analysis of this device. So in conclusion of the two case studies we've discussed today, the initial vulnerability was disclosed to, sorry we're doing the disclosure first, I'll get my slides mixed up, the initial vulnerability was disclosed to Samsung in December 2022 and they provided constant updates on progress and patched the finding within three months across all their devices which was extremely impressive considering the complexity of debugging this kind of thing. So the target device that I had after recording my demos for Defcon was updated and I found it to no longer be vulnerable to the descriptive right vulnerability meaning code execution but in this manner was no longer possible. I'll be releasing the tools for this on my github but you'll be able to find the link to my Twitter where I'll announce this in the slides which you'll find on the Defcon media server. So now conclusion. So most devices regardless of how much effort people put into protecting them will still have exploitable vulnerabilities that can be exploited simply despite their resources and even with basic vulnerabilities the effort required sometimes to go from a proof of concept to a full exploit is really rewarding. For instance you saw that there was two very basic vulnerabilities in both of those case studies. We then took a certain amount of effort to actually make into a complete attack chain and last of all even on targets which had a huge amount of research put on them there will still be a factor no one else has tried so you should try it first. Thank you very much. I think we have time for questions and there's a microphone at the back of the room. I'm also happy for people to just shout at me or I'll be outside in the hallway after this talk so whatever works for everyone.


To close out a great day of talks, we have Will Christensen and Jason Plumb. Will is a DevOps engineer with a background ranging from software tools development for non-destructive evaluation at ASIC to Linux administration. His experience with development on scientific engineering and manufacturing software, coupled with an affinity for command lines and VIM, have led to a life focused on automation. Presently, Will works as a cloud engineer at Change Healthcare. Jason is a staff engineer on the distribution team at GitLab, where he focuses on providing a large number of deployment methods for GitLab the product. He's worked extensively to build GitLab's cloud native helm charts along with GitLab's Kubernetes operator to enable the ease of use and deployment that GitLab customers have come to expect but the power of configuration and orchestration that Kubernetes provides. Today, Will and Jason will be taking us on a journey into the realm of container build optimization. With a talk entitled, One Layer Builds Dock or Not Included. Containers can bring a number of benefits but the way containers get built can quickly increase your technical debt. In this session, Will and Jason will walk us through step by step how to build one layer containers and will share the benefits of doing so. Hello, everybody. Thanks for coming out today. Today, we're going to be talking about One Layer Builds, specifically Dock or Not Included. So first off, your presenters today. I am Jason Plum. I am a staff engineer, distribution and GitLab. I'm Will Christensen. I'm Will Christensen. Also, I'm sorry, a DevOps engineer and open source contributor. And just like Jason, we also mentored people coming up and just trying to make the community a better place. So let's do a quick dive into what the actual issue we're going to talk about. It's fairly simple. It's the big oof. And in that regard, what? Yeah. So when things get heavy, there are problems. And Docker containers, well, let's just say containers in general, they're stacks of layers in the end. And the problem is when the cat gets too big, you need to stop feeding it so much lasagna, especially as thick as that apparently was. First off, a lot of people don't use multi-stage builds. These allow you to build things in stages and only put the necessary result into your end container. The next one is some layers are kind of fat. And then you go and build on top of that. And there's nothing you can do to trim that out by the nature of how layers inside of containers work. Think of it as checking in a tar ball of all of the images for a game into a Git repository.  It's not so bad. And nobody will need it if they don't do a Git pull. Well, now it's in the object. And even if you do Git RM, the moment that you pushed it anywhere else, everybody now gets a copy of that for perpetuity until somebody rewrites history to take it out. And in the case of an image, when you rewrite history to take it out, you're rebuilding the image. It's not the same image anymore. There's no way to take that out, period. Then, well, you've experienced this one personally, so I'll let you take the lean. So the impacts for how things stack up become a major pain in terms of later on in the container build process, you can start dealing with people trying to remove layer or remove something that they thought from the actual container itself. And it won't work.  And if you don't watch out, for instance, if you were building a Java container, you may see a container sometimes as large as seven gigs and many, many layers. The registry costs will balloon over time. And the biggest issue that we've seen is when people have their pull policy on their Kubernetes cluster set to always, well, every time you make a change and you include in your build process, you were paying a lot of money for your network transactions, your storage costs. But most importantly, your time is taken up because the larger the containers are, the longer it takes to populate in the registries in all the clusters downstream. And just as a simple example of what we're talking about being fat layers, here is dive and we have basically pulled the default Ruby image, the public Ruby container image. And it's eight layers. Eight layers doesn't seem like too much, sure, but it's 881 megs. Just for that. If your runtime doesn't need everything that this might need, this could be 80 megs too much, could be 400 megs too much. Hard to exactly tell. And if you look at the line right here, primarily they did apt get update. There's more involved, no argument. But that's 528 megs. That's a lot. So let's look into what we can do about that. First off, let's look at what it is to actually build one layer containers. Right? So if anybody's familiar with building containers, have you ever seen from scratch in a Docker file? This actually means zilch zero, give me nothing, give me a blank layer. And that is my base. Now, the interesting bit here is because you're working effectively with a completely scratch empty, nothing, nobody else has already preemptively put all this stuff in there for you. You can have a pre validated tar ball that contains a file system. You can bootstrap it from a distribution using debut strap or pack strap or even YUM or DNF with a remote install option. If you need to, you can basically copy your full running shrewt that you've been using for years as a production application and just pop it right into a container. The beauty of this is what comes as a result. Well, yeah, I was going to say the biggest benefit that I have seen is when you use things such as app get pack strap or the remote install is you can go directly from a repository. You can put it into the folder and you don't even need to populate even a temporary container with any of the cached files. And when in that side of that container that you are building, you don't even need to put the package manager, which reduces one more piece that may be a security vulnerability downstream and when you get to production. Who knows? Maybe there's something in those default packages that you don't actually need that requires Pearl or all of Python. But in the end, does your application need it? Step two, as a result, when we're talking about one layer builds is very simple. So let's talk a little bit about the tools. This one is build up. Yes, it's pronounced that way. It came out of Boston. It's build up. Okay. Yes. You can find more information at Delta.io. But the key things that you really want to take away from this is that it's specifically designed for building containers, not running containers, building containers that can be done with shell scripting or the CLI, or it can actually be used with existing Docker files by just telling it, you know, built from the Docker file. But the documentation for building from scratch with this project is actually very sound, very straightforward. If you have questions about what really building a container from scratch is, whether it's in Docker or with Builda, you can find solid reference here. Will, from your experience, we're going to cover the next few. Sure. So most important is for me is you can use Builda without ever touching any domain specific or some domain specific languages. You don't need to know much else other than do you know a distro? If you understand the packstrap process and you understand how the builds would go in any type of shell scripting, that is very easy to make a container. Just remember to clean up your cache files and you can make very small containers. And with only one layer, you don't have to come back and you're not haunted with previous previous efforts with the one layer containers. We are all sorry with Builda, they're all OCI compliant containers. So if you want to do a Docker pull, they are completely compatible in many of our builds that we do for open source projects, for work, we are able to build directly from Builda and use it in our Kubernetes environments with various runtime engines without a problem. Oh, and most importantly, if you are a Docker user, please consider looking at Builda just because working with the manifest for handling multi-arch builds is an absolute dream. And this is, this is where we go. No, really from scratch. And let's point out a couple very specific things. And well, you kind of touched on these a second ago. First off, because you're not operating in domain specific language in how a Docker file is declared and how these functions behave, you get less opinionated tooling, but nothing against the way the Docker file is implemented in any way shape or form. But if you're familiar, as say, assistant men and building out either existing jails or shrewds or just even a working file system directory for an application, then you actually know how to build the working directory for an application. That skill set is no longer, let me figure out how to do it in Docker file. It's instead, let me do the thing and then tell Builda to say this is a layer. It's the fastest way to go from that scratch, that bear file system into a container without having to necessarily learn anything more specific or have to worry about bumping into edge cases and optimizing over and over again until you finally get to that, that happy point that you think you can move forward towards production. And as I said, because that system administrator knowledge that, that SRE, that sysadmin, that architect view of how do I make this application function that you've got decades of experience doing, you have the ability to do these. You can integrate this skill set directly into cloud native with containers. It doesn't matter if it's OpenShift or Kubernetes or Docker or really anywhere you want to do it. Your skills are there. On top of that, we have the ability to actually accelerate the breakup of monolithic applications, not necessarily as simple as a large code base, but monolithic application suites. You can take something that you already know that you already got broken up and take just the parts of you that you need for that application to function and break it out into separate chunks. So you can build something that's got all of the parts in one. It's basically a big stack of bricks. And then you can start taking individual bricks and put them in separate containers. And your viewpoint of how did I build that whole application doesn't have to change. Only how do I ship this component for runtime? From a runtime perspective, for a get-up solution, you can bake, for instance, a Terraform container with all your providers built into them. And it makes swapping out those containers mid pipeline, very simple and very quick. We have noticed that there is a significant improvement with caching, because when you pre-bake all your containers with everything that you need, you can save about 20 to 50% of the time for your built. And if you are doing anything where you need to make API calls, you can specialize and put all the specialized libraries right in there to do each step mid pipeline very quickly. I have not seen this type of improvement, except for using multiple tagged runners, running our shell runners that have been built specifically for specific tasks. We also have the bonus of because you don't have an upstream for your image, you're not building off of, say, immediately Ubuntu 2004 off the top of my head, then you're not bound to whatever is defaultively in that image. You aren't bound to what may come up in terms of functionality or pre-existing users or items that are pre-installed. You can optimize it out of the box by having only what you actually need to operate your application. This makes it actually also very good because you can now do this doing early adopter. So say you've got a new piece of hardware or a new processor type that you want to work with. If you can build it, you can stick it in a container. If you can stick it in a container and you can get a runtime of some kind to do that, then you can get it on that hardware without having to do much modification from the viewpoint of the developer who's got hardware that's of a different type. And over on the right, let me point out, when I say because we're optimizing what's actually there, this is one of my images. I know. An example of as you come down through, I started with a tiny 69 megabytes, but then the next layer was another 111, and there's another 108. And then you get down here, oh my, what is this? Okay, by the time I'm down here, I'm adding another 100. This image is not small. This could be optimized to say at least. So as we are definitely trying to repeat over and over again, when you have one layer, you don't have to pay for the sins of previous work. Um, everything is always fresh. And it also means that you get better control over what you have and not worrying about anything that may be in the past. If you have ever had to, let's say, do a scan of a container using various tools that let's say something is flagged, but was deleted in the layer above, I have experienced being, I was being held back from using that project and trying to figure out, well, how do I go back and deal with that particular issue? And if you have to wait for a vendor container that has that violation, or sorry, that issue, you are pretty much just sitting around waiting for something to happen. When you have full access to one layer, you can address it. You get control with the one layer build. If you must, you can build your containers from the same thing your systems would. So if you have, let's say a capsule, internal mirror, anything for repositories that would use for normal patching or image builds, you can build a container from that directly. And that includes also internal libraries that you may need to build. You can include that all into a single build pipeline. Much easier to remove contents from a layer than it is to edit a previous layer. We know theoretically how we're told to remove binary from a previous layer. I haven't seen it done in practice yet. And from what I've read, it doesn't look very easy, and I don't expect most places to figure it out unless they're just really curious. And most importantly, I have noticed with one layer builds because we don't have to worry about any type of masking of previous layers. I know Jason and I talked about AUFS. There's a masking way. So if you try to remove something in higher layers, you may still pay the penalty for the space it's taking because you're not removing that. And it allows you to keep everything just neatly coupled. And when you go to compress that image, it will get the highest compression I have found for that image. So all you have to do as a contributor is just make sure are your caches cleaned up and are your temporary files for whatever you need to do inside the container removed. And let me tell you, when I've had to work with very complex images, whether in my day job or in the community work, I love dive. But if you've ever had to actually use it because you're dealing with an image that's been built on top of an image and on top of another image that's on top of another image that then gets to the application, trying to find out why there's a weird permissions problem. That's not a fun process. Dive is awesome for that. And we love dive. But you don't want to have to do this on a regular basis if you don't have to. Remove the problem from the start. Yep. So the nice part here is this can all be done in CI or CLI. This is not a point and click. Because it's not a point and click, it means that you can do this through whatever source of automation. We will later demonstrate how you can do this as a part of GitLab CI through our pipelines and using the registries that are available. But the nice part is you don't need to do anything horribly special. You already have all the necessary runtime available to you as an engineer, as a developer, as a contributor. It's there and you have access to it on any system that's available in the public right now. There's nothing that binds you to require a license or anything else. This is all open, usable and extremely accessible. On the left is literally the first container I ever made with Builda. And other than addressing in that container how to get a more minimal version of Bash, I still use it. And it's great. So if you're afraid of building containers from scratch, I started down this road and I found, at least with Arch Linux and Arch Linux ARM, it made the process very simple. So if you are restricted from using Arch, then you would replace line three with your Dev Bootstrap or your YUM or DNF remote install. That will essentially build the container that you need. With packstrap and Dev Bootstrap and multi-bootstrap, you can install into the container without worrying about a cache. With the remote YUM install, you do need to clean up that cache afterwards. But other than that, same process, pretty much every distro, this is where your sysadmins will come and all their experience will reward you with nice, simple, one-layer containers. Oh, and a major benefit is that as I talked about previously with the pipelines, if you need to make specific containers, you make one base container that has done nothing more than build a and build a. And after that, you can put on whatever you need to either do the job or to like, you know, to talk to infrastructure or you can make specific building containers that can build the artifacts that you need. Well, let's go ahead and show them how this works. Well, all right. So for the demo, we're going to build a simple pipeline. The pipeline is just going to be a very basic Ubuntu container. Please ignore the fact that we, of course, right before any talk, there was some work that we had to do last minute, but should be simple now. So we're going to go run the main branch. This will be renamed when you go to see it in your shared repository, which will be hosted on our Buzz create repository in GitLab to simply go run.  It is a one node Kubernetes runner and the base for it is also built in this particular project, which will, which is a focal runner. And we're just going to wait for the runner to wake up. I have a friend that has this runner working in his closet. It is a one node Kubernetes cluster. Anyone can build this. The runner itself is been built from Ubuntu focal. There will be an example for what it would be like to do a pull from Docker hub for Ubuntu focal and then to build the GitLab runner with it with multiple layers. And then there's what our build process does for rebuilding the container. So once the runner wakes up, the duration is 45 seconds. And on internet, on consumer internet with consumer hardware, this is quick. Let's go take a look at the, at the size of the container. Now, this is just the bare bones container, no optimization. This is also using G like C, not muscle, no, nothing special. And it's 52 mix previously, there have been some optimization efforts upstream with Ubuntu, which by the way, thank you, keep it going. Where the size of the containers were a little bit larger, but now this is just the pretty much the regular one. And that's it for the entire demo. So having listed the demo, let's do a quick comparison between a simple build from Ubuntu. Now, mind you, we're not using the aforementioned slim images that are now made by Ubuntu and Debian, Fedora, et cetera, major distributions. But let's just look at, you know, build up from basically scratch, right, on Ubuntu 2004 and build up from scratch. Will? Yeah. So the left is pretty much everything from the GitLab CI.yaml, you know, our runtime environment or our build pipeline file. And I took all that through then to a shell script, just to build an initial container to get started, which is something that if you want to use this process is someplace where everyone starts. However, once I build that container, I run the pipeline and I reference the manual container to build the next one, which is on the right. After you build it once, you can build it again. And it's pretty much a chicken-the-egg problem. But once you're in the cycle, it's easy. You click a button and you've updated your container.  Oh, cool. It's in the repos.  It makes my life as a DevOps engineer so much simpler. So what we want to do here is let's understand that we're proposing the concept of a one-layer build. That's not going to fit everybody. That's just kind of how it is. It's just like one size fits most. The most is the keyword there because some people are not the same. So a couple of counter cases to what we have going on here. But one, for example, happens to be the GitLab Cloud Native Container Suite. You're deploying a very large application suite. And if we have a common base, then every image that gets pulled to any given Kubernetes node actually now reduces the amount of time it takes to download the next image that might be running a different container. So for example, if you have our Rails code base that are serving the web assets and the API, those have a common base with the Giddily service and the Redis containers, right? So we can optimize for our runtime of our users by using a common base and then adding only what we need in as few layers as possible above that. Another obvious example for when you cannot use a one-layer container is if you're using Iron Bank, if you are in a highly regulated environment and you must use a regulated container, obviously certain solutions are not available to you. And while you can get things certified to go into Iron Bank with the solution, you're dependent upon what you're dependent upon. And there's nothing we can do to change that. Another particular case is certified Red Hat images that are included as a part of OpenShift on-prem. If you're going to have a certified operator that's going to be included directly in the OpenShift marketplace, that container has to be UBI-based. If you're going to do that for other containers that are going to end up in the Red Hat container registry that's immediately accessible as a part of OpenShift, they too need to be UBI-based. So you can work from a base image and then limit the number of layers that you put on top through a combination of the techniques that we've spoken about before. Now that we've put the caveats in play, let's make some additional benefits that are inherent to this approach. First foremost is the supply chain attack prevention. If you are familiar with certain security appliances, you know that if you leave your build infrastructure, if you do not audit very closely your build infrastructure and if you aren't aware of some of the latest techniques, your build infrastructure may be at risk. One of the best things you can do is make your build infrastructure more ephemeral. Constantly rebuilding and being able to get the latest to your build infrastructure will help you. The benefits I really enjoy is the great visibility and auditability. I don't have to tell anyone it's magic inside of the containers, I can show them. We can have discussions and it's really nice to be able to work with people that may have an issue and we can, you know, if the upstream distribution has an issue, we can build our own slipstream right into it, still want the layer for the container. No one's an EUizer and everyone's just happy. Future proofing. When your hardware changes, as long as your build chains are there, as long as your repositories are supporting that particular hardware upstream, you can take that by just simply getting build up or building build up, just trying to see if it works. And if you can build what you need with build up, you can build all your containers just by with the same knowledge you know of the distro that you're using. And finally, security scanning. As I mentioned before, with fewer layers, you fewer origins, fewer things that you need to validate before you release. And by making sure that you have the reduced attack surface and greater control, you can make sure that you can maintain the integrity of your containers. And with the ability to rebuild fast or quickly and simply, it also helps you with once again, that supply chain attack prevention. So let's give you a quick summary of the things that we've talked about. First off, save time, both for you and for your consumers. Save space, both for you in your registry, in your storage costs, but also for your consumer, because the less they have to have transferred to where they're trying to execute these things, the less it costs them to both in time and trends. And savings or savings, save money. So simple answer is 42. Four things I want you to understand in two ways. First, to minimize your images, minimize the layers. To minimize your layers, use fewer. To use fewer, make sure if you're using more than one layer, use multi-stage builds, whether it's in Docker or it's in Billa, please do this. Second, and final, if you can use one layer. And it's really as simple as that. Special thank you, Zach, Emily, and John, all of you not only helped out clutch to make this presentation, I can definitely say time was spent out of normal working hours and very late for every single one of you. So thank you. Could not do this without you. And with that, we want to say thanks everybody for coming out and feel free to join us at the happy hour chat.


Hello friends, welcome to SS Unitech. My name is Sushin Singh and this is continuation of Excel tutorial. So today we want to discuss about if and instead if functions which is a label on Excel. And it's a very important formula. In real time scenario you will face a lot of conditions where if formula will be applied. So let's move to another slide. So this is our slide as you can see here you will understand about the syntax. So if formula takes three parameters first parameter for the condition and second if the condition will be satisfied then we have to specify the value in our second parameter. If condition will not be satisfied then we have to specify the value in our third parameter. So it will be written the output. So what is the agenda for today? So we need to understand about the if then we have to understand about the if with and and then if with or at last we will understand about the the study. So let's start with if. So here you can see we have an input sheet which contains four columns. First is student ID second is to name then mark and then result. So as here you can see result column is blank. So we have to calculate the result by using if formula. So what is the condition for this result if the marks value greater or equals to 300 then we have to specify as a pass. Otherwise it would be fail. So how we can achieve this? Let's move to excel where we will apply the formula to get the output. So this is our status as I have explained we have to specify if then we have to specify our condition in our first parameter. So our condition is this marks value if this marks value is greater or equals to 300 then we have to specify comma and specify the value if this condition will be satisfied then what we want to return we want to return pass. So this is our pass and then we need to again specify the comma and our third parameter if this condition will not be satisfied then we want to display fail. So we have to specify fail over here and then close the bracket and as you can see marks value 250 is less than 300 then it's going to return fail. We can scroll and we can check if the value is greater or equal to 300 then it would be pass. So here we can see 350 is greater than 300 so pass and 450 again pass. So here we can see now we can remove this 430 to 150 and let's check the status value. So here we can see status value has been changed to fail from pass. So I hope you have understand about the if condition. So our second is if with and condition. So here we can see we want to use it but we need to check the first student ID if the student ID is greater or equal to 100 and then we need to again check marks value if the marks value is less or equal to 300 then we want to specify the pass otherwise it would be fail. So here we can see our marks value is 250 so it's less than 300 but student ID is greater than or equal to 100. So in excel sheet we can see student ID is less than 100 so it would be fail and we need to check for the sue where student ID is greater or equal to 100 so it's 107 and if the marks value is less or equal to 300 so it's 200 so it would be pass as other conditions would be fail. So let's move to excel to apply the formula to get the output. So this is our sheet and here we need to apply if then if we want to use and or or condition we have to specify just after if so we have to specify and and then we need to check the student ID if the student ID is greater or equal to 100 and so we have to specify the comma and we can put our second logic. So second logic is marks value should be less or equal to 300 if these two conditions will be satisfied we don't have any other logical condition if we have more than two logical conditions then we can put comma and specify over here if we have more than three then we can specify by using comma and add one by one so here we have only two we have to specify like this and then we need to specify comma if this condition will be satisfied then we want to return as a pass so this is our pass else we need to specify fail and then close the bracket and press enter so it's going to return fail as I have displayed so here force you it's going to return as a pass else it would be fail so I hope you have understood how we can use if condition with and formula as well we have another formula if with or so where we have specify and we can also use or so we need to add one more column result underscore we are going to use or formulas or then if and then we have to specify or and we need to check the student id is greater or equal to 100 and marks value should be less or equal to 300 then we want to specify pass so we need to specify pass and then if this condition will not be satisfied then we need to display as a frame this is our the center as we can see it's going to return pass and these two conditions are failed because the student id value is less than 100 and marks value is again more than 300 so it's going to return fail so I hope you have understand how we can use or formula with if so let's move to another slide for the nested if so this is our nested if condition so here we can see we have to check the marks value if marks value is less than or equal to 250 then it would be fail else if marks value is greater than 250 and less than 450 then it would be pass else we need to specify as a merit in our output so how we can use nested if condition over here so let's move to excel to apply the formula and get the output so here we need to add one more column with nested if this is our nested if and then we need to check if this marks value is less or equal to 250 then we need to specify as a fail so I have to specify over here and then if this value will not be satisfied then we need to again check so we have to specify if then inside if we have to use and condition because we have two conditions if the marks value is greater than 250 and then again we need to check if this marks value is less than 450 so this is our condition if this value will be satisfied then we need to specify as a pass I have to specify over here if these two values will not be satisfied then we need to specify as a merit so this is our merit so we need to close our first if condition and then we again need to close our outer if condition and then pass enter as you can see we have our first value is fail and then pass merit and we are getting the output so in our slide and here both values are same so I hope you have understood how we can use if condition and how we can use if condition with and and or formula and how we can use nested if as well so thank you so much for watching this video if you like this video please subscribe our channel for many more videos and press bell icon to get all the notifications for new updates thank you so much


Welcome back. Today we're going to do our second set of quadratic applications and this is going to be a data application. So here we have the sales of DVD players in the US have increased over the years. So here are our times, our different years that we have, and then here are our different sales that we have. Now the one thing you also want to notice here is that it says in years T since 1990. Okay, so we're going to need to scale our years. So if we have 1997, let me go back over here, so I'm going to put a T. So that's going to make that one 7, that one 8, that one 9, that one 10, and that one 11 because it's years since 1990. Okay, so we're going to be finding a quadratic function that models this data. Okay, that means we're going to be using the calculator to do some regression. So let's go to the calculator. And if you remember how to do this, then we want to go to our stat. So stat, edit. Now in our L1 and L2, if you have anything in here, you can just highlight up and then hit clear and enter, and it'll wipe out any data points you have in there. Mine are empty because I cleared them before I started the video. Okay, so remember our inputs go in L1, our outputs go in L2. So that means my time is going to be my L1 and my sales are going to be my L2. Okay, so I'm going to put a 7, enter, 8, enter, 9, enter, 10, enter, and 11, enter. Okay, toggle over to the right to get into my L2. I'm going to put in my sales then. So 0.3, enter, 0.9, enter, 3.6, enter, 9.9, enter, and 16.0. So I don't have to type anything but just 16. Okay, kind of a gut check on this one is make sure your lists have the same length. And then since it's such a small data set, I'll probably just go through really quickly and make sure I typed everything in correctly. I think it looks pretty good. Okay, also remember that our L2, so this represents sales in millions, and our L1 represents years since 1990. Okay, so we're going to go back to stat. We're going to go over to calc. Now in the past, when we wanted a linear model, we would pick option number 4. That stands for linear regression, but this one asks us for a quadratic function. So we want number 5, so that's quadratic regression. So hit 5, all right, tell the calculator to run it, and there is our model. And that's ugly, so that's why it says round to two decimal places. Okay, so I'm going to have to toggle back and forth here. Half a t is going to equal, so my a was 1.04. Now we have to use a t in here, so that would be t squared. And if you forget what this looks like, your calculator puts it up here at the top for you, so that's pretty handy. My b is going to be negative 14.73, so this will be minus 14.73. Again, t, not x, because t's our variable, plus our c value, which is 52.17. So plus 52.17. Okay, fantastic. Sketch a rough graph of your model. Okay, so there's a couple of different ways we can do this. We can just type into our y equals what I put here. Or since we have a regression, we can now go through a fancy thing here. If you go to your y equals, don't type this in, but go to your vars menu. Toggle down to number five or click on five for statistics. Then you want to put the equation in, so you notice this third menu over here says eq. Regression equation, that's what this reg eq stands for, if that's what you want to pronounce it. Symbolically or phonetically here. So go ahead and click on that, and it'll put in the whole shebang here for you. So look at how many decimal places it puts in. But again, I said rough sketch here, so if it's not perfect, that's fine too. Another thing that we can do since we have some stats in here, some data, is let's go ahead and do a zoom. And we can play around with our window like I've been showing you what we've been doing. Or we can do zoom stat, so we can do number nine. So it should fit our window, but I might have my stat plot on. No, it's okay, this window's good enough. But if you didn't have a good enough window, you want to turn your plot on first, duh. And then I can go to zoom, number nine is your zoom stat. Oh, so this gives us a much different window. So here's our data. This has kind of a curve to it, but you notice it looked more like a parabola when we had the whole window on here. And it looks like it goes through most of the points, so I would say that's pretty good. But if it were me, I'm going to go ahead and sketch out the whole thing that we have here. So remember it kind of went like this, popped down, and then went back up again. Okay, all right, according to the model, how many DVDs were sold in 1990? Okay, so 1990 is our year. T remember is years since 1990. So that means we want to look at where T equals zero. Okay, so let's take a look at our table. So if I go to second table, since I can't see much of my graph here since I did my zoom stat. If I go back to zero, it gives me 52.16666. So yeah, so we can call that 52, we can say about 52. And then our Y was in millions, so we could say about 52 million. Okay, where is this on the graph? Well, I didn't label it very well, did I? So let's say this would be it right here. So this would be the point zero comma 52. All right, keep on checking. According to the model, what was the smallest number of DVDs sold? Okay, so let's go back to the calculator. Let's turn that stat plot back off because I think that's kind of distracting. So let's turn that off and let's change our window because I want to go back a little bit before this. So let's go ahead and do zero to, that should be fine, zero to 11. I want to see more of that parabola. There we go. That looks like more parabola now. What was the smallest number of DVDs sold? Well, that would be at our vertex right here, our minimum. So you want to go to second calc. We want the minimum, so that's option number three. Left bound, so we're on the left side. Let's hit enter. Toggle on over. That's pretty good. Okay, hit enter. And our guess is going to be somewhere in the middle, about right there. Okay, so the minimum is at 7.0, whatever, and it's going to be 0.14. So it wants the smallest number of DVDs sold. So again, that's our vertex. So the smallest number, that means it wants the y value. So the smallest is, was that 0.14? See, smallest is, I don't want to print it either. 0.14 million. Okay, when did that happen? That was in 1997. Because remember, our T was seven there-ish. If you want to add a little bit more to that, you could. But remember, it said 7.06, close enough to seven in 0.14. So that's our vertex. Okay, where is it on the graph? Well, we already said it's the vertex, but let's go ahead and label it. So I'm going to go back up here, take my green, and we'll label that about right there. So that's our smallest number. Okay, using your model, find f of 19 and answer with a sentence describing the meaning of the solution. Okay, so 19, because that's inside the parentheses, that's going to be my input. So that's my T, or in this case my x, if I go to look at my calculator.  And let's toggle on down to 19. Plus, with all these decimals, it's just going to be really messy. So I think it's a lot easier to let the calculator do the work for us. Okay, so at 19, we have 148.74. So f of 19 was 148.74. Let me double check that, make sure I remembered that correctly. Yep, looks good. Okay, answer with a sentence describing the meaning of the situation. Well, 19 is our T, so let's go back up here. Remember, T is years since 1990. So that would mean in 2009, there were, since it's in the past now, about, let's see, 148.74 million DVDs sold. Using your model, find T when f of T is 100. Okay, so because this is on the other side of our equals, that means this is our output. This is our number of DVDs sold. This is our y value, so to speak. Okay, so let's take a look at our table again. You think we're going to get lucky and find 100? Close. At 17, it's 103, so I'd say that's pretty darn good. But let's go back to our y equals. Let's toggle down into our y2, and let's go ahead and put 100 in. Okay, I'm going to graph it. And I'm probably not going to be able to see what's happening here. Okay, so let's go to our window. Let's change our max. What did I say? That was 17. So let's go ahead and make our x max 20 just to be safe. And we want our y value to be 100. We only had it at 18. Okay, so let's go ahead and change that to how about 120 just to be safe. So if I hit graph, I can hopefully see the intersection now. There is the, there she goes. Perfect. Okay, so then to figure out where that point is exactly, we know it should be somewhere around 17. We can go to second calc. We want intersection, so I want option number five. First curve. So that means let's go ahead and follow our first curve until we get close to that intersection point. Maybe, maybe. Okay, that's pretty good. Hit enter. Second curve. Well, we're already pretty on our, we're on a second curve pretty darn close to our intersection point. So hit enter. Guess sounds good. And our intersection is at 16.84. Now, remember, this is talking about real life things here. So we could say towards the end of 2006 would be fine. If you could say at the beginning of 2007 or right before the beginning of 2007, however you want to state it, but that's going to be our year for that one. Okay, so I think I'm going to say at the end. At the end of 2006, there were about a hundred. Oopsie. Let me fix this one too. I don't know what happened there. A hundred. And remember our outputs are in millions. A hundred million DVDs sold. Or you could also say in 2007, I think I'd be happy with that answer too. Okay, does there seem to be model breakdown? So this is kind of a gut check with this one. But yes, I mean, do you really think that the years, the selling years started here went down and then eventually went up? No, because remember, let me clear this out. Remember, we started our date at about seven. So that was about at this minimum. So what's happening before that? I don't think it was probably more. You know, I don't know when DVDs started, but yeah, so I would probably say yes. The years before 2007, I think that's about in there are too big. But that's why we call these models. They're not perfect predictors or anything else. And, you know, I doubt that the number of DVDs is going to get that large, but it might. You just never know with some of these things. So that's where, you know, you have to do some interpretation of stuff. All right. Good luck. Keep practicing these and have a great day.