why do hackers love strings?

Sdílet
Vložit
  • čas přidán 1. 11. 2022
  • Hackers have been trying to steal information since the beginning of the information age. Buffer overflow attacks have been one of the ways they do it. By taking advantage of logic bugs in programs, hackers have been able to get access to computers and steal information which they later sell on the dark web. Buffer overflows have been one of the most common ways they get in.
    In C, strings are a little weird. Because there is no length encoded with the string type, string functions in C are extremely easy to use incorrectly. When used in an unsafe way, hackers can abuse the way that functions call each other to give them access to your computer.
    🏫 COURSES 🏫 Learn to code in C at lowlevel.academy
    📰 NEWSLETTER 📰 Sign up for our newsletter at mailchi.mp/lowlevel/the-low-down
    🙌 SUPPORT THE CHANNEL 🙌 Become a Low Level Associate and support the channel at / lowlevellearning
    🛒 GREAT BOOKS FOR THE LOWEST LEVEL🛒
    C Programming Language, 2nd Edition: amzn.to/3OKh3q2
    Computer Systems: A Programmer's Perspective: amzn.to/3N3PqHe
    Blue Fox: Arm Assembly Internals and Reverse Engineering: amzn.to/4394t87
    Practical Reverse Engineering: x86, x64, ARM, Windows Kernel, Reversing Tools, and Obfuscation : amzn.to/3C1z4sk
    Practical Malware Analysis: The Hands-On Guide to Dissecting Malicious Software : amzn.to/3C1daFy
    The Ghidra Book: The Definitive Guide: amzn.to/3WC2Vkg
    🔥🔥🔥 SOCIALS 🔥🔥🔥
    Low Level Merch!: www.linktr.ee/lowlevellearning
    Follow me on Twitter: / lowleveltweets
    Follow me on Twitch: / lowlevellearning
    Join me on Discord!: / discord
  • Věda a technologie

Komentáře • 565

  • @anon_y_mousse
    @anon_y_mousse Před rokem +1990

    Most important message to be conveyed here, *never* trust user input. Always check it, always restrict what you do with it.

    • @31redorange08
      @31redorange08 Před rokem +304

      Most important message to be conveyed here, never have users.

    • @MorningNapalm
      @MorningNapalm Před rokem +40

      Most important message here: make your code safter and safter, until it is as saft as possible.

    • @peesicle
      @peesicle Před rokem +60

      @@31redorange08 Most important message to be conveyed here, never have code

    • @MizzMaster_
      @MizzMaster_ Před rokem +27

      @@peesicle Most important message to be conveyed here, never have a programming experience

    • @peesicle
      @peesicle Před rokem +34

      @@MizzMaster_ Most important message to be conveyed here, never have a computer

  • @RobbCorp
    @RobbCorp Před rokem +677

    Be really fun to see your 'secure' server broken live and record the actual memory. Great video!

    • @LowLevelLearning
      @LowLevelLearning  Před rokem +58

      Glad you enjoyed it!

    • @adammontgomery7980
      @adammontgomery7980 Před rokem +16

      I don't know how that's done. As far as I know, the program is loaded into a random address so you would need to know the offset from the program counter to the desired function.

    • @geekzombie8795
      @geekzombie8795 Před 6 měsíci +3

      @@adammontgomery7980 Trial and error then? I’m not quite too sure…

    • @Zooiest
      @Zooiest Před 5 měsíci +2

      ​@@adammontgomery7980 yeah, that's address space layout randomization. You'd probably need to exploit the global offset table (is there a Windows equivalent?) to get remote code execution, although I'm not sure if it's _completely_ impossible without it.

  • @eluraedae
    @eluraedae Před rokem +154

    In this reality some hackers love strings more than physicists.

    • @patrickday4206
      @patrickday4206 Před rokem +1

      Lol

    • @eluraedae
      @eluraedae Před rokem +1

      @enrique amaya Bro tell that to the starving kids in other countries.

    • @ishid_anfarded_king
      @ishid_anfarded_king Před 6 měsíci +7

      I don't know why hackers need to like physicists, but okay.

    • @luvmakin9342
      @luvmakin9342 Před 3 měsíci +1

      @@ishid_anfarded_king playing a pun to "string theory"

    • @Anonymous-fr2op
      @Anonymous-fr2op Před 2 měsíci

      ​@@luvmakin9342damn, it slipped through my mind entirely😂😂 f'cking genius

  • @sledgex9
    @sledgex9 Před rokem +337

    Technically you must read at most 63 bytes/characters. The 64th byte in the array is the null byte. And you need to remember to set it to null when creating the array.

    • @pawmeowzing2906
      @pawmeowzing2906 Před rokem +3

      I don't get it why at most 64?

    • @sledgex9
      @sledgex9 Před rokem +50

      @@pawmeowzing2906 I was refering to the example code in the video. He creates an array of 64 elements. The last element must be the null byte.

    • @damurichannel
      @damurichannel Před rokem +7

      @@pawmeowzing2906 just dont code in C 😂. Use C++ or Java

    • @Gupatik
      @Gupatik Před rokem +72

      @@damurichannel bro r u serious, the power of c is only limited by your skills

    • @def_not_here
      @def_not_here Před rokem +74

      @@damurichannel Really? I'd love to see you write a program in Java for a microcontroller, which has like 16kb of memory

  • @mk72v2oq
    @mk72v2oq Před rokem +362

    And all this just because someone decided that extra few bytes for storing the length is too expensive.
    Which is kinda strange, because in fact pre-determined length can increase performance dramatically. There is a known recent story about GTA modder who cut the game loading time by 70% just by eliminating strlen() calls.

    • @rb1471
      @rb1471 Před rokem +61

      Automation? In my C?

    • @jeffspaulding9834
      @jeffspaulding9834 Před rokem +165

      That someone is probably Dennis Ritchie, who created C for the purpose of porting assembly code between architectures for machines that would only ever be accessed by his fellow employees and never connect to a network (networking barely existed then). It was a useful way of getting around the hard coded size limits of strings in languages like Pascal. User accounts and passwords mostly existed to prevent people from modifying other people's files, 'cause accidents happen and some people are jerks. Security was handled by the guard at the gate and the lock on the computer room door.
      If he'd been able to see into the future and know how popular C (and computing in general) would become, maybe he'd have done it differently.

    • @asston712
      @asston712 Před rokem +41

      @@rb1471Nahhhh no one would be so heartless as to make C *easier* (🤢) and *safer* (🤬).

    • @5FT6MAN
      @5FT6MAN Před rokem +2

      how tf did he get the codellll

    • @taragnor
      @taragnor Před rokem +83

      The other thing to remember is that back then, those machines were super primitive, so optimizing things for speed and minimal memory usage was absolutely necessary. Back then the size of things was a lot more important than it is now, so adding that extra 2 bytes to store an integer length was something they probably weren't willing to commit to unless it was needed for the task. It's hard to imagine with a modern mindset where we can throw a few extra megabytes at something and not even care.

  • @FreshSmog
    @FreshSmog Před rokem +89

    You can always implement strings as structs and store the length data. It's C, you can do anything. Unfortunately, you still need to get the data back out pretty frequently as the usual null terminated char arrays in order to use other functions.

    • @petrlaskevic1948
      @petrlaskevic1948 Před 9 měsíci +2

      Unless you modified other functions too

    • @nunnukanunnukalailailai1767
      @nunnukanunnukalailailai1767 Před 7 měsíci +3

      That's a cool way to do it as it makes strlen an o(1). Also renders str(n)cat pretty useless as memcpy works for that, and fwrite can be used in place of printf. But like you said, most of string.h expects null termination. It also has to be ensured that the length stays in sync with the actual contents always.

    • @poutineausyropderable7108
      @poutineausyropderable7108 Před 6 měsíci +2

      struct for the wins.
      I don't know why some C coder don't like using them.

    • @EphemeralObsequious
      @EphemeralObsequious Před 5 měsíci

      When you save the string at the outset you just always set the last slot in the array as \0 as a guarantee then never check again.

  • @Agryphos
    @Agryphos Před rokem +100

    We should all be grateful that code is getting safter

  • @jorgeherrera1074
    @jorgeherrera1074 Před rokem +108

    Honestly there are no excuses for buffer overflows in your programs today. With all the tools available to devs you have no reason for this to still happen.

    • @williamdrum9899
      @williamdrum9899 Před 8 měsíci +2

      Hell, even in ASM it's not hard to prevent.

    • @aurelia8028
      @aurelia8028 Před 5 měsíci

      I just tried creating the same program on my computer and it didn't even give me a segmentation fault, so I don't think it's possible to even do this anymore.

    • @williamdrum9899
      @williamdrum9899 Před 5 měsíci

      @@aurelia8028 Oh don't be so sure! Computers actually randomize the locations of things in memory just to make this exploit harder. But it is still very possible. x86 hasn't changed in that regard

    • @jp46614
      @jp46614 Před 5 měsíci +18

      I have to disagree. As a security consultant, I see a lot of low level applications being developed and these mistakes happen all the time, even when using modern suites and tools which should in theory make this behaviour difficult or warn developers. But often low level APIs have to be used, especially when it comes to writing performant code (a lot of guaranteed safe alternatives for code often have a cost of performance) and that's where the protections go away and mistakes are made. Developers are also often under a lot of stress and pressure to meet deadlines, and corners have to be cut (think TODO's you never come back to).

    • @fw-190
      @fw-190 Před 2 měsíci

      We are human, we make mistakes, no matter our experience and our skills, if you think I am wrong, look on the internet why planes started to use checklist

  • @ReptilianXHologram
    @ReptilianXHologram Před rokem +134

    I think you should make a course on how to program in C securely/safely for beginners.

    • @mfaizsyahmi
      @mfaizsyahmi Před rokem +41

      Abandon C. Become a Rustacean.

    • @SkegAudio
      @SkegAudio Před rokem +21

      Just learn Rust at this point

    • @ReptilianXHologram
      @ReptilianXHologram Před rokem +22

      @@mfaizsyahmi Linux is still written in C so I have to learn it.

    • @ReptilianXHologram
      @ReptilianXHologram Před rokem +12

      @Clemens Horn Wait what? Rust is more secure but what's the point if it is rarely used yet? I'm focused on learning things that will apply to what I will be doing for a job as I am going for Computer Science.

    • @wrong1029
      @wrong1029 Před rokem +11

      @@ReptilianXHologram rust will only grow from here on out. I graduated in 2020 and had no struggle finding a rust backend engineer position that pays super well. I'm literally getting spammed on LinkedIn by recruiters looking for rust devs

  • @younesmdarhrialaoui643
    @younesmdarhrialaoui643 Před 5 měsíci +1

    I have to say this channel is very, very, very good. You really are delivering quality wise.

  • @coolbrotherf127
    @coolbrotherf127 Před 7 měsíci +3

    That's why the newer secure versions of these input functions also include a max data value so they can ignore any input over the intended amount making them much more difficult to exploit with buffer over flows.

  • @quipyowert9933
    @quipyowert9933 Před 10 měsíci +2

    4:59 "Randomize Memory Data Structure" Perl 5 does this with hashes starting in 5.8.1 and the Perl porters improved the feature in version 5.18. It's in the perlsec manual under the section "Algorithmic Complexity Attacks".

  • @donjindra
    @donjindra Před rokem +7

    As a C programmer I would never uses gets() in a professional program. I always bound check when copying to buffers.

    • @hikefka8001
      @hikefka8001 Před rokem

      Yeah and compilers should warn about it.

    • @donjindra
      @donjindra Před rokem

      @@hikefka8001 Good programmers shouldn't have to be warned.

  • @RealNekoGamer
    @RealNekoGamer Před rokem +19

    In Pascal-style strings, the length is encoded as a byte at string[0], or sometimes the first 2 bytes (first 2 indices). This is a practice that the Macintosh pre-Intel era used in its API, and how strings are usually stored in binary file formats.

    • @BitwiseMobile
      @BitwiseMobile Před 8 měsíci

      ASCIIZ has been around since PDP-11 times. It was an assembler directive. Pascal does go back that far though. I believe it was released in the early 70s - maybe even late 60s I don't recall .... edit, I just looked it up - 1970 - so yeah, it was around during the PDP-11 heyday.

    • @williamdrum9899
      @williamdrum9899 Před 8 měsíci

      Who was writing strings longer than 255 bytes back then lmao

  • @stevenc5140
    @stevenc5140 Před rokem +7

    Coding is definitely getting SAFTER

  • @garyhalsey7693
    @garyhalsey7693 Před rokem +10

    Having just completed my CompTIA Network+, Security+ & PenTest+, this is a perfect example of the need for sanitisation of user input!!! Great video and you’ve just got a new subscriber!!

    • @LowLevelLearning
      @LowLevelLearning  Před rokem +2

      Glad it was helpful!

    • @noviccen388
      @noviccen388 Před 8 měsíci +1

      @@LowLevelLearning Please make vidoes on how to secure C from Buffer Overflow. :)

  • @nick9198
    @nick9198 Před rokem +52

    Remember to pass the -fno-stack-protector flag when compiling your C programs for added stack based security.

  • @unknownlordd
    @unknownlordd Před rokem +11

    more buffer overflow please because I've always watched videos about them but never have "clicked" as simple as this one

  • @vladislavkaras491
    @vladislavkaras491 Před 5 měsíci

    It was informative!
    Thank you!

  • @adibemaxwell6111
    @adibemaxwell6111 Před 7 měsíci

    This is why when printing something, I was told it's always best to use fprintf() or sprintf() instead of basic printf().

  • @jamesleecoleman
    @jamesleecoleman Před rokem +5

    This is great! I wish I had this years ago when I was learning more about Buffer Overflows for a pentesting cert. It took me like a year to actually perform my first BO but it was still messed up but it worked lol.

  • @hanzo2228
    @hanzo2228 Před rokem +5

    great video ! how did you get the function description in c 2:30 ? as a beginner that would really help me understanding the functions in depth

    • @surv5k
      @surv5k Před 7 měsíci +3

      youve probably found the answer by now, but on a unix-like system you can type `man (name of function)` and it will show a manual page for it

  • @23trekkie
    @23trekkie Před 6 měsíci +1

    That's why you're supposed to use fgets, which gets both string and it's size.
    fgets(string, sizeof(string), stdin);
    In case of scanf, you can define the number of characters...
    char array[64];
    scanf("%63s", &array);
    But I guess there is a way to overflow those too... Not that I know about it.

  • @rodtronics771
    @rodtronics771 Před rokem

    I am so glad your videos are short. Theyre so good.

  • @vanlepthien6768
    @vanlepthien6768 Před 5 měsíci

    The problem comes down to - in a large part - null terminated strings. I thought it was a lousy string implementation back in the dark ages. Nothing since has changed my mind.

  • @davidgomez79
    @davidgomez79 Před rokem +13

    Only thing more fun than a buffer overflow is a string format exploit Stack canaries, ASLR, not executable stack made buffer overflows rare now.

    • @spambot7110
      @spambot7110 Před rokem +2

      no they don't. they make it harder / less likely for it to be possible to exploit a given buffer overflow, that's it.

    • @davidgomez79
      @davidgomez79 Před rokem

      @@spambot7110 you're not contradicting me. I work so I type in a hurry. "rarer".

    • @williamdrum9899
      @williamdrum9899 Před 8 měsíci +1

      Never let the user write the format string

  • @eduardostarz
    @eduardostarz Před 20 dny

    3:50 it's written "incldue" instead of "include" in line two that's why it's unsafe code, hope it helps
    great video btw

  • @christiangamers2254
    @christiangamers2254 Před 4 měsíci +1

    In C++, we have a similar problem when we use a char pointer.
    One solution I found was to use cin.width(length) and cin.ignore(some large number)
    These two commands ensure to consider a string upto length and ignore the rest of the characters entered. Is there a problem with this approach?

  • @rebok232
    @rebok232 Před 8 měsíci

    To don't have buffer overflow there is a simple way: ditch low level langs, for langs like: for ex. kotlin, or rust

  • @stopper0203
    @stopper0203 Před rokem +6

    I absolutely LOVED this video! Keep up the good work 😊!

  • @mostafaseyedashor8768
    @mostafaseyedashor8768 Před rokem +3

    what a good and neat explanation and not a fast and nerdy voice! thank you

  • @alfredomenezes8814
    @alfredomenezes8814 Před rokem +2

    Very interesting, please do a video about the mitigations!

    • @ytg6663
      @ytg6663 Před rokem

      Use modern Compilers they already warn you when you use unsafe functions

    • @JorgetePanete
      @JorgetePanete Před rokem

      Going to Rust

  • @sp3ct3r71
    @sp3ct3r71 Před rokem +6

    crystal clear explanation.. could you please make a video about basics of assembly also??

    • @stopper0203
      @stopper0203 Před rokem +1

      I would love to know the assembly code for Intel's processors. I only learnt the assembly code for Atmel's microcontrollers at university, so knowing a more widespread assembly language would be great.

    • @deang5622
      @deang5622 Před rokem +1

      It's easy. Just go look up the instruction set for the processor you are interested in.
      You don't need someone else to do that for you. And you will learn more by obtaining the instruction set for you.
      And over the decades authors have written books for each microprocessor teaching you the instruction set and how to program it. "Programming the xxxx" where xxxx is the part number of the microprocessor you are interested in, was one popular family of books.

    • @williamdrum9899
      @williamdrum9899 Před rokem +2

      Chibiakumas has a few good videos on it. Watching the Z80 or 8086 tutorials will give you a good idea about how Intel CPUs work

    • @stopper0203
      @stopper0203 Před rokem

      @@williamdrum9899 Thanks, I'll definitely check these out

  • @HenrikBerg1965
    @HenrikBerg1965 Před rokem +4

    If someone reads this know that strncpy is broken and should not be used.
    If input is larger than buffer, no nul is added to the buffer. Never use strncpy without the line after:
    buffer[sizeof(buffer) - 1] = ‘\0’;
    If you don’t like to write this every time, use strlcpy.

  • @MegaCrossfire007
    @MegaCrossfire007 Před 5 měsíci

    I don't quite get it. If we change the return address with the buffer overflow we are outside the main function, but that doesn't automatically mean that we end up in the debug function, does it? And why does the buffer owerflow changes the return address, shouldnt it simply change the value of the address which comes after the allocated memory for the string?

  • @jonsunderland7708
    @jonsunderland7708 Před rokem +6

    Current GCC wont even compile gets()
    It will explicitly tell you "Dont be a dumbass, use fgets()"

  • @fabienb3432
    @fabienb3432 Před rokem +10

    Awesome video ! Thanks a lot for explaning about buffer overflows with an example.

  • @user-rh2xc4eq7d
    @user-rh2xc4eq7d Před 4 měsíci

    What I don't understand is how the hacker would know what value to set the return address to. They would have to have access to the code or decompile the binary or something.

  • @Endar92
    @Endar92 Před 3 měsíci

    Interesting fact, nowadays as memory is relatively cheap, programmers reserve more bytes for a string as would be needed. Instead of 64 bytes, they reservre 1024 bytes and so on. This simple trick can be helpful in mitigating the overflow attack as it's harder to overflow.

    • @ZT1ST
      @ZT1ST Před měsícem

      Not just mitigating the overflow, but making it significantly more obvious if someone is trying to overflow it - because they'll be using all 1024 bytes worth of characters.

  • @MisterDan
    @MisterDan Před rokem +1

    Nice and clear presentation

  • @Masa-san
    @Masa-san Před 5 měsíci

    3:00 - this is incorrect in AArch64/64-bit ARM. Without compiler optimizations turned on, arguments would be pushed to first and second general registers. With optimizations turned on, this function would be completely ignored and compiler would just calculate it in compile time. So this issue is defined by different rules under different architectures, and I guess (since I'm not working with X86 assembly) what you have pointed out is X86_64 thing.

  • @platin2148
    @platin2148 Před rokem +7

    The dumb idea of zero termination pascal has a bit more safety. Also in C you typically use the n functions to minimize potential damage. Store strings in strechy buffs and never use functions that don’t allow you to take the max len with them.
    I doubt this add will push anything to the stack i suspect it will directly use registers as there are still plenty of them open and passing via stack is in comparison really expensive. The macOS arm64 calling convention is a but of a weird one when we then go to structures..

    • @williamdrum9899
      @williamdrum9899 Před 8 měsíci

      Until you add 2 to your string pointer and now you have no idea when it enda

    • @platin2148
      @platin2148 Před 8 měsíci

      @@williamdrum9899 That’s why you don’t pass a pointer to the memory of the string but just a slice/view which is nothing more than ptr+offset and it doesn’t matter if you lose track down the line as you aren’t the owner of the memory in the first place also never ever move a pointer in place.

  • @ancientgearsynchro
    @ancientgearsynchro Před 5 měsíci

    I always questioned why my teacher told me to put hard limits on the length of passwords my users can even input, let alone check. Guess this was one of the reasons.

    • @ThatJay283
      @ThatJay283 Před 3 měsíci

      another safe way is to use heap allocated strings with %ms. for example, using scanf with %ms, you can pass a pointer to an unallocated string, and the result will be allocated by scanf.
      also ideally, there should even be a limit for how long a password should be. how long a password is shouldn't matter, because you shouldn't be storing passwords anyways. processing passwords properly will make them a fixed size.

  • @guilherme5094
    @guilherme5094 Před rokem +1

    Thanks again👍!

  • @semibiotic
    @semibiotic Před 11 měsíci

    Unfortunatelly, strncpy(3) (and strncat(3)) is vulnerable too. It adds no NUL if source string size is equal to "n" argument.
    You should use strlcpy(3) instead, if impemented (or invoke strncpy(buffer, src, sizeof(buffer)-1); and make sure that buffer[sizeof(buffer)-1] = '\0';).
    Also, strncpy(3) fills the rest of buffer with NULs, which creates performance issue.

  • @Jmcgee1125
    @Jmcgee1125 Před rokem +6

    Read the gets(3) man page if you feel like having some fun. It's not long. Opens with "Never use this function" and ends with "ISO C11 removes the specification of gets() from the C language." It also mentions that "there can be no guarantees that the function will even return" - which is due to the return address manipulation exploit in this video.
    5:14 I wouldn't recommend using strncpy(3). It does not guarantee that the result will be null-terminated, so it's just another thing to keep in mind when copying. Use snprintf(3) instead, even if strncpy(3) is technically safe.

    • @williamdrum9899
      @williamdrum9899 Před 8 měsíci

      I suppose it was a product of its time, if gets() is used correctly it's fine but there are bad people on the internet who turn it into goto()

  • @mastershooter64
    @mastershooter64 Před rokem +2

    Didnt know hackers were interested in theories of quantum gravity as well ;)

  • @TheGeckoIsKing
    @TheGeckoIsKing Před 11 měsíci

    So happy “Code is getting safter”

  • @Stratelier
    @Stratelier Před 5 měsíci

    Makes me wonder why gets() is even still supported in any compilers if it's _so_ deprecated that its documentation literally says "don't do this". (Okay, apparently it was removed entirely from the C11 standard, but anything based on C99 is still more or less required to include it.)
    And why null-terminated strings became the preferred implementation is weird when (at least for common strings less than 256 chars) adding a separate byte to specify the length up front not only avoids much of the buffer overflow scenarios, but doesn't even add any memory cost! You'll have to reserve one extra byte in memory either way (either a null byte, or a length byte), and how much space you might need to (dynamically) allocate to hold a string is a separate problem.

  • @wsurferdude_ct
    @wsurferdude_ct Před rokem

    Well explained! Thanks

  • @spacespyder
    @spacespyder Před rokem

    Great Video thank you for explanation :)

  • @noam2802
    @noam2802 Před 2 měsíci

    but isnt it solvable like in 3 lines of code?
    In a project im currently doing I just did a loop that kept reading from the buffer until it reached '\0'

  • @ZeroDayEx
    @ZeroDayEx Před 3 měsíci +1

    why is the function still there if even the dev said to not use it????

  • @shadowchasernql
    @shadowchasernql Před 8 měsíci

    I find it funny that c is the scapegoat for string overflow

  • @shadowchasernql
    @shadowchasernql Před 8 měsíci +1

    I love how c is inexplicably the scapegoat for every single buffer overflow ever

    • @williamdrum9899
      @williamdrum9899 Před 8 měsíci

      I don't even see assembly get any grief for it either lol

    • @shadowchasernql
      @shadowchasernql Před 8 měsíci

      @@williamdrum9899 It's funny because the only languages I have ever experienced a memory overflow in have been in ones without manual memory management.

    • @williamdrum9899
      @williamdrum9899 Před 8 měsíci

      @@shadowchasernql You mean like Java and its NullPointerException?

    • @shadowchasernql
      @shadowchasernql Před 8 měsíci

      @@williamdrum9899 Not quite

    • @williamdrum9899
      @williamdrum9899 Před 8 měsíci

      @@shadowchasernql I'm curious how that's even possible anyway since the language won't let you fix it

  • @GamersGoneExtinct
    @GamersGoneExtinct Před rokem +7

    Would love to hear more about the other mitigations and how to use them

  • @19adhin
    @19adhin Před rokem +1

    How would a hacker find the address to the debug function? @4:15

  • @rb1471
    @rb1471 Před rokem +2

    I'd be interested in how they know the address of the function they would want

  • @allumallu6580
    @allumallu6580 Před 5 měsíci

    Now i get it ! thx

  • @markchristophergemzon1052

    If you are trying to overflow the buffer and placing the address of the 'debug' function as the return address, how do you find out the address of the debug function? Also, how do you know when to input the address of the debug function so that it exactly goes into the return address?

    • @dzhimy6266
      @dzhimy6266 Před rokem +1

      You know when the return address is on the stack because the stack frame will (in almost every single case) be the same size on subsequent executions of that function.
      How you actually get the return address of the debug function depends. Without modern exploit mitigations, you could simply just hard-code the address into the overflowed buffer.
      With modern exploit mitigations, you will need to chain the buffer overflow vulnerability with a memory address leak vulnerability that points to somewhere within the .data section of the program because one of the many modern mitigations that exist is Address Space Layout Randomisation (ASLR), which randomises the virtual address that the executable code is loaded into memory at on a per-run basis of the program.
      There are other exploit mitigations similar to this, but with just ASLR, you will need to leak a memory address, and then in the same runtime of that program use that address in the buffer overflow in another part of the program to successfully redirect code execution to the debug function.

    • @nick9198
      @nick9198 Před rokem

      Use a debugger, if there is a potential overflow you can just overflow the buffer with random characters and then the debugger will crash and dump the part of the string you supplied and based on that you can calculate the distance, if you will, from the overflow to the return address on the stack. Getting the address of the function is harder (if not impossible) because of ASLR (address space layout randomization), there are ways to get around this though, one popular method is known as ROP (return oriented programming), which can in some instances allow you to circumvent ASLR and execute code arbitrarily.

    • @williamdrum9899
      @williamdrum9899 Před rokem

      For your second question it depends on the CPU architecture. Typically, a C function in x86 assembly will CALL main (which pushes RIP) and then PUSH RBP at the start of the function. So the offset RSP+8 is where the return address will be.

  • @insoft_uk
    @insoft_uk Před 8 měsíci

    It’s not that prints gets were bad at the time, just sloppy programming not checking before using, now newer safer replacements were added to enforce checks tho still majority of programmers are not fully checking and I don’t think this will ever change and forever have exploits that should of never been

  • @0xfrijolito
    @0xfrijolito Před rokem

    4:45 printf is also a vulnerable fuction if you direcly pass a string without format

    • @erikkonstas
      @erikkonstas Před rokem

      Eh, I'm not very sure about that... the danger comes if your string might have "%" characters in it, but I don't know of any format specifier in any implementation that could execute code or write to memory.

    • @piaIy
      @piaIy Před 8 měsíci

      @@erikkonstas %n writes to memory

    • @erikkonstas
      @erikkonstas Před 8 měsíci

      @@piaIy Hm, you'd have to have the correct pointers very strategically in the stack, and also potentially a very, very long string to make the value from %n large enough... oh, and you also cannot decrement that value.

    • @williamdrum9899
      @williamdrum9899 Před 8 měsíci

      It's vulnerable if you allow the end user to write the format string

  • @IamSholiSJ
    @IamSholiSJ Před rokem +1

    These vulnerabilities r present in C++ iostream library functions or not?

    • @tbyz2572
      @tbyz2572 Před rokem

      存不存在取决于你是怎么写的

  • @US-Air-Forces
    @US-Air-Forces Před 5 měsíci

    Just don't keep sensitive information in memory unsecured

  • @THEBESTPINEAPPLEY
    @THEBESTPINEAPPLEY Před 5 měsíci +1

    4:10 Line 2 Syntax Error: Did you mean "#include"?

  • @awesomesauce1157
    @awesomesauce1157 Před 7 měsíci

    bro your thumbnails are absolutely hilarious

  • @hodayfa000h
    @hodayfa000h Před 2 měsíci

    🤯
    I never knew it was like this

  • @smeboo9044
    @smeboo9044 Před rokem +3

    If the string has to be local to the return instruction on the stack, how would you ensure that where you’re storing is actually on the stack and not in a register? I’ve had this question for a while now and I feel like I’m missing some important concept.

    • @Ronaldo-se3ff
      @Ronaldo-se3ff Před rokem +2

      it's how a value in a subroutine is returned at the machine level. some insight into how subroutines work in assembly language should clear this up.

    • @daryl9915
      @daryl9915 Před rokem +2

      The compiler usually adds instructions to do that. I think I saw a machine code/compiler tutorial somewhere years ago that explains how the stack works, but I can't remember exactly where now.
      Either way, registers are too small for most strings (usually 8 bytes for general purpose registers in 64-bit architectures); it's reasonable to expect any compiler to store strings somewhere in memory - stack or heap

    • @dzhimy6266
      @dzhimy6266 Před rokem +2

      Strings are never stored in a register unless you pack the data in such a way that they make up the bytes of a multi-byte integer. Generally you will store strings on the heap, not the stack. Default configurations for modern compilers such as CLANG will - by default store local variables such as strings in a secondary stack known as the shadow stack, which does not store return addresses and therefore cannot be used to redirect code execution using the return-value overwrite method. To guarantee your data is stored on _the_ stack and not a shadow stack or the heap, you will use a function called "alloca", which is similar to malloc, except that you don't have to free the address it returns because that address is on the stack, all this function does is move the stack pointer further down the stack by the size you provide it (usually this is compiled inline, but can appear at runtime too).

    • @smeboo9044
      @smeboo9044 Před rokem +1

      Okay! That makes sense. I might have been overthinking it a bit then, but just to clear up in my head a bit, if a function took 3 arguments; int x, string y, int z, is it correct to assume that %rdi would hold x, %rsi would hold a pointer to the stack where y is stored, and %rdx would hold z.
      That is if we’re using the same x86 isa when I “learned” this all? Lol

    • @daryl9915
      @daryl9915 Před rokem +2

      Pretty much. Depending on the language, string y in the function parameters is most likely a pointer to either a char array allocated on the heap (via malloc() or new) or an object/instance of the language's string class, again probably allocated from heap memory rather than on the stack. Been a long time since I actually did any programming though, especially in C

  • @vikingthedude
    @vikingthedude Před 8 měsíci

    Does Zig have these problems?

  • @ExecutionErrorSmough
    @ExecutionErrorSmough Před 8 měsíci

    I got a good laugh out of the stock video at 0:10

  • @hiftu
    @hiftu Před rokem +35

    The real issue is that a huge amount of projects rely on c libraries.
    It would take decades the change all the programs.
    Than you have to check all the c++ libraries as well.
    After that all the libraries from another unsafe programming languages.

    • @5FT6MAN
      @5FT6MAN Před rokem

      examples?

    • @trayambakrai
      @trayambakrai Před rokem +9

      Most of these, if not all can be mitigated via simply taking care of what you're writing -- no need to use a "safe" programming language like Rust.

    • @techsupport1294
      @techsupport1294 Před rokem

      If you know how those libraries are used then you'd know the library simply changing a gets isn't going to require changes in your code.

    • @deang5622
      @deang5622 Před rokem +6

      No. Buffer overflows occur in C because a string is just a pointer to a block of memory and there is no bounds checking done, which is down to you as the programmer to code up, and check you don't go beyond the end of the allocated memory for the string.
      So it's within your hands to go through the code and identify everywhere you are writing into a string or block of malloc'ed memory and ensure you don't write beyond it.
      You don't need to edit libraries. Now if those library functions are fairly sophisticated and are doing tasks such as getting the input and writing it into the string for you, then you have a problem.

    • @white-bunny
      @white-bunny Před rokem +1

      @@trayambakrai You can use a library like GLib, as it has the GString struct which is used in a lot of code in C (as long as you're not writing for upstream kernel or upstream projects).

  • @lambiwins4499
    @lambiwins4499 Před rokem +1

    Guys I started studying in a university ( computer science and programming ) so I have a question how can I detect if my Programm is getting buffer overflow ?

    • @williamdrum9899
      @williamdrum9899 Před rokem

      Some compilers add extra code using what's called a stack canary. It's a secret variable stored between your string and the return address, that the programmer can't access at compile time. Its value is set at the start of a function, and checked at the end. If it changed, then the function won't be allowed to return and will instead segfault

  • @ejonesss
    @ejonesss Před 5 měsíci

    if gets is so dangerous then why is it still included?
    unless to maintain backward compatibility as some binaries still use that and so it was left in the os to support the older binaries.
    for example you may have a binary blob from the 80s or 90s and it still serves a valid function today but the source code is lost or it is proprietary so the blob may be included to provide the function since a replacement is not around.
    it could be a print driver for an interface like parallel port and there is no usb driver not even a usb to parallel adaptor.

  • @anonymous_4276
    @anonymous_4276 Před rokem +1

    So if the return address is corrupted thanks to buffer overflow in C, why does the program enter the debug function? I don't see the connection there. It seems to me like the program should just crash incase the return address is overwritten as it now has nowhere to return after encountering the return statement.

    • @YouAreUnimportant
      @YouAreUnimportant Před rokem

      you are right. you have to place the right number on the right position of the stack for that to work. otherwise you most probably access memory you aint have permission to and the operating system will stop you.

    • @williamdrum9899
      @williamdrum9899 Před rokem

      If a hacker knows the address of the code they want to run, putting it on the stack where the old return address was will cause the return command to act as a goto. Effectively the RET instruction on most CPUs is "goto TopOfStack"

  • @DeeArr
    @DeeArr Před rokem

    ..Good reason to use a managed language such as open source C#

  • @LoesserOf2Evils
    @LoesserOf2Evils Před rokem +3

    Please: more on the buffer overflow; and some on mitigating against it and protecting against it.

    • @JorgetePanete
      @JorgetePanete Před rokem +1

      Going to Rust fixes it

    • @williamdrum9899
      @williamdrum9899 Před rokem +1

      Easiest way is to use a language that manages it for you. If that's not an option, the 2nd best way is to restrict user input. If you're expecting a 10 byte string, don't let the user overfill it.

  • @jackpatteeuw9244
    @jackpatteeuw9244 Před rokem +2

    I come from the world of VAX/VMS. They handled strings/pointers VERY DIFFERENTLY, likely because one of their priorities during development of the heavily intertwined hardware and software, SECURITY WAS A PRIOTIY !
    This was the early 80s, so VAX was a 32 bit computer. A "descriptor" (fancy C pointer) was FOUR entities. An 8 bit "class", an 8 bit "data type" and a 16 bit "length". A CLASS could be a fixed or variable length entity. Fixed length was most common. The data type (DTYPE) could be many things making it a descriptor to a byte, word, long word, quad word, etc. So CLASSS=1 and DTYPE=24 was a fixed lenght string.
    Buffers were ALWAYS defined to have a fixed length and any system library/service routine respected that length !
    There were other hardware devices that prevented access to different parts of memory that did not belong to your process.

    • @williamdrum9899
      @williamdrum9899 Před rokem

      I guess C was meant to be as lean as possible. I code in assembly and I found myself creating something similar to your method when programming a neo geo game. For sprite data I stored the width and height at the start of the array and used those as loop counters to copy what came after into video memory, that way the routine always stopped when it was supposed to

  • @raptoress6131
    @raptoress6131 Před rokem +4

    I'm just going to assume that all users are criminals

  • @xr.spedtech
    @xr.spedtech Před rokem +1

    No more null bytes from now on ..
    Use unsigned for a counter ...

  • @nathanoy_
    @nathanoy_ Před rokem

    0:09 did someone notice the CZcams video playing on this mans computer in the stock footage?

  • @oglothenerd
    @oglothenerd Před 2 měsíci +1

    Hey Rust, we need your help.

  • @tonym5857
    @tonym5857 Před rokem

    Small and powerfull video 👏👏👏👏

  • @-21_26
    @-21_26 Před rokem +2

    Hey, I am at a freshman year at automation of atomic and energetic process at my university. I was told to not use gets() no way, only fgets() , but they didn't told me about this part . I hope to see more videos about C from you.

    • @williamdrum9899
      @williamdrum9899 Před rokem

      This is pretty much the reason they tell you not to use gets()

  • @enderger5308
    @enderger5308 Před rokem +4

    That's one of Zig's nicer improvements: it uses fat pointers for strings so that a class of buffer overflows can be ignored (and, provided you pre-allocate buffers, most user input is safe by virtue of using the buffer size).

  • @yepee1
    @yepee1 Před rokem

    Why do we still have gets() if it's broken??

  • @littlerogue4788
    @littlerogue4788 Před 5 měsíci

    it's getting safter?

  • @aaaaanh
    @aaaaanh Před rokem +1

    Basically the user/threat actor gaslights the vulnerable program into submission and giving up the data it has

    • @williamdrum9899
      @williamdrum9899 Před rokem

      It's more like they're in the passenger seat while the computer is using a GPS to drive home, and the hacker takes the GPS while the driver isn't looking and sets the destination to somebody else's house.

  • @Enter_channel_name
    @Enter_channel_name Před 8 měsíci

    Is it really that hard to bounds check user input?

  • @mobslicer1529
    @mobslicer1529 Před rokem +2

    i love me a good buffer overflow

  • @TonyDaExpert
    @TonyDaExpert Před rokem +1

    Using sprintf while watching this 💀
    Was just trying to convert a float to string on a micro controller 😢

    • @reroman
      @reroman Před rokem

      Use snprintf function.

    • @TonyDaExpert
      @TonyDaExpert Před rokem

      @@reroman the compiler I was using had an issue with using that lol

  • @JarppaGuru
    @JarppaGuru Před rokem +1

    4:26 yeah lets change gets function not accept more than lenght is. fixed! and if write bigger then password is wrong it would not run debug. kinda bad example. overflow would not correct password. it would return anyway correct position

  • @bdidue6998
    @bdidue6998 Před rokem +3

    At this point in time, buffer overflows should be inexcusable.

  • @sneedmane
    @sneedmane Před rokem

    4:10 Song name?

  • @372leonard
    @372leonard Před rokem +2

    is this just a security issue with c and c++ or are other languages like javascript and C# also vulnerable to it?

    • @v01d_r34l1ty
      @v01d_r34l1ty Před rokem

      They can exist everywhere, however 99% of them are probably just from C programs. C operates on a very low level with a very minimalist STL. Makes it very hard to secure and optimize. With modern development standards and procedures, languages like C++ and Rust make it much much less likely to be a problem. Even higher level languages can still suffer from it, but this typically comes down to a flaw in the compiler or interpreter rather than your code itself.

    • @ailijic
      @ailijic Před rokem +2

      This might be a bit padantic. At this time all of the CPUs that is mere mortals will encounter are stack machines. So they are all vulnerable to buffer overflow attacks. That being said, we have come up with a lot of ways to mitigate this type of attack; try searching for address space layout randomization (ASLR). An attack is composed of multiple parts. Simple terms would be vulnerability, exploit, and payload; I might be missing one or two. The buffer overflow is the vulnerability. Next, is the exploit; the attacker has to figure out how to use the exploit to run other parts of the code. Finally, you have the payload; the code that is run via the exploit. It could be a virus, a worm, randomware, or code that gives you access to the system. Moral of the story, there is no such thing as a nontrivial bug free program. You can reduce the number of bugs but you never get rid of all of them. It's an arms race, hackers and security go back and forth.

    • @v01d_r34l1ty
      @v01d_r34l1ty Před rokem

      @@ailijic +1 for mentioning ASLR

    • @sledgex9
      @sledgex9 Před rokem

      Not a problem with C++, unless you specifically decide to do strings with C way in C++.

    • @v01d_r34l1ty
      @v01d_r34l1ty Před rokem

      @@sledgex9 automatic allocators in C++ are a godsend

  • @nitsuj1001
    @nitsuj1001 Před rokem

    This mitigation wouldnt take only a video rather than a 2 full university courses

  • @joeldoonan-ketteringham5174
    @joeldoonan-ketteringham5174 Před 2 měsíci

    Never trust a user, always assume that they are trying to hack you and your other users.

  • @thescientist8599
    @thescientist8599 Před rokem +1

    Lol, I literally had a lesson about the NUL an hour ago

  • @cheesebusiness
    @cheesebusiness Před rokem

    Is storing the buffer length not an option for C developers?

    • @sumitbhoi4070
      @sumitbhoi4070 Před rokem

      Storing buffer length is an option nonetheless buffer overflow can occur

  • @Stabruder
    @Stabruder Před 5 měsíci

    4:48
    "Code is getting safter"
    Read again..
    (Safter)?

  • @mahsumsaetgareev
    @mahsumsaetgareev Před rokem +2

    4:16 but we should know the address of the debug function in memory right? How can we do that? (for learning purpose only)

    • @DerMigi
      @DerMigi Před rokem

      I would like to know that as well!

    • @jonshouse1
      @jonshouse1 Před rokem

      printf("Address of function debug is %p
      ",debug);

    • @jonshouse1
      @jonshouse1 Před rokem +1

      PS If you mean "know" the address externally from the executable the answer is you cant. The best you could do if it was open source would be the compile it on the same arch (or dig into binary) and guess the most probable. See "Address_space_layout_randomization" on Wikipedia for why that probably wont help much (in the case of Linux).. Ignoring the minor issues that physical to virtual mappings are also dynamic, so guessing an offset into a binary will still fail to give an absolute address even the stack use where not also obfuscated.

    • @LowLevelLearning
      @LowLevelLearning  Před rokem

      If the binary is not compiled position independent, the address of debug is the same every time regardless of ASLR.

    • @user-dh8oi2mk4f
      @user-dh8oi2mk4f Před rokem

      @@LowLevelLearning So is it still possible to get the address of debug() if it is compiled position independent? And how would you get the address even if it wasn't?