flat assembler
Message board for the users of flat assembler.

Index > Main > Is handwritten asm more dangerous than compiled C code?

Goto page 1, 2, 3  Next
Author
Thread Post new topic Reply to topic
wean_irdeh



Joined: 12 Sep 2018
Posts: 12
wean_irdeh 12 Sep 2018, 20:40
Hi guys, I was having discussion with Reddit users on vulnerability which might arise when writing asm, and their answer was the C code vulnerability also applies to asm, but worse since there are no compiler warning and mitigation

Link to the discussion:
https://www.reddit.com/r/AskNetsec/comments/9f5exx/what_vulnerability_might_arise_when_writing/
https://www.reddit.com/r/hacking/comments/9f5d5x/what_vulnerability_might_be_arise_when_writing/

Only one thing I know asm does better than C is there are no undefined behavior.

If so what are you guys gonna do to secure your handwritten code, I'm also curious on how MenuetOS handles things,
thanks in advance
Post 12 Sep 2018, 20:40
View user's profile Send private message Reply with quote
DimonSoft



Joined: 03 Mar 2010
Posts: 1228
Location: Belarus
DimonSoft 12 Sep 2018, 22:10
Avoiding vulnerabilities in your software is a matter of proper quality assurance, so it definitely has nothing to do with programming language you use. In fact, using a higher- or lower-level language does not immediately mean you’re protected better. HLLs have historically been created to avoid common mistakes in generic pieces of code and move some complexity from human to compiler. But as HLLs start to rely on “virtual machines” and “runtime environments” that introduces a new layer of software which essentially becomes part of the program you’ve written in such languages, and these parts are far more complex than your software could be and thus have higher probability of having vulnerabilities in them. Also LLLs, requiring more concentration from a programmer, make him more cautious about possible mistakes thus preventing them. And we all know which programming language is responsible for thousands of vulnerabilities due to its standard library full of unsafe functions.
Post 12 Sep 2018, 22:10
View user's profile Send private message Visit poster's website Reply with quote
wean_irdeh



Joined: 12 Sep 2018
Posts: 12
wean_irdeh 13 Sep 2018, 00:29
DimonSoft wrote:
...


Thank you! Any tips for writing secure asm code?
Post 13 Sep 2018, 00:29
View user's profile Send private message Reply with quote
Melissa



Joined: 12 Apr 2012
Posts: 125
Melissa 13 Sep 2018, 02:33
Secure code means checks. Check for values, that's it.

edit:
yes, assembly is more secure then C. Instructions are clearly defined
and what they do. There is no undefined behavior in assembly.
Post 13 Sep 2018, 02:33
View user's profile Send private message Reply with quote
revolution
When all else fails, read the source


Joined: 24 Aug 2004
Posts: 20486
Location: In your JS exploiting you and your system
revolution 13 Sep 2018, 02:56
I don't think the language used is related to secure or insecure code. It is equally possible to write secure code in C and assembly. And it is just as equally possible to write insecure code in C and assembly.

The more complex the system become the harder it is to make secure. So I think the real answer is simply a measure of complexity, not a measure of the underlying language(s) used.

It can happen that each and every individual part can be secure on its own, but when those parts are combined into a larger system the interaction between them creates vulnerabilities.
Post 13 Sep 2018, 02:56
View user's profile Send private message Visit poster's website Reply with quote
wean_irdeh



Joined: 12 Sep 2018
Posts: 12
wean_irdeh 13 Sep 2018, 04:44
revolution wrote:
...

Melissa wrote:
....

Thank you! How can I avoid something like buffer overflow and integer overflow?
Post 13 Sep 2018, 04:44
View user's profile Send private message Reply with quote
revolution
When all else fails, read the source


Joined: 24 Aug 2004
Posts: 20486
Location: In your JS exploiting you and your system
revolution 13 Sep 2018, 06:02
wean_irdeh wrote:
Thank you! How can I avoid something like buffer overflow and integer overflow?
Buffer overflows: Make sure all your buffers have a known length and check all operations to make sure things fit correctly.

Integer overflows: The CPU has the O and C flags, check those to see of something went wayward.

Those are very simple types of security problems. Always be vigilant to other sorts of potential vulnerabilities. But most of all, where possible, keep your code simple. Complexity is the enemy of security.
Post 13 Sep 2018, 06:02
View user's profile Send private message Visit poster's website Reply with quote
wean_irdeh



Joined: 12 Sep 2018
Posts: 12
wean_irdeh 13 Sep 2018, 06:12
revolution wrote:
...


Thank you! I appreciate your answer
Post 13 Sep 2018, 06:12
View user's profile Send private message Reply with quote
Tomasz Grysztar



Joined: 16 Jun 2003
Posts: 8363
Location: Kraków, Poland
Tomasz Grysztar 13 Sep 2018, 06:19
The basic rule could be: whenever you copy something from one place to another, or convert from one type of data to another, ensure that the destination is correctly prepared to fit what you try to put in there. If it does not, not only abort the operation, but have a clear error route - do not let the error be ignored by the higher layers of your program unless you are absolutely sure that it does not matter to them.

Be careful around boundaries. For example, a buffer that is exactly the right size to fit your string is going to be too small if you need to add a terminating zero. When you add or increment sizes, always check for overflow (for example use JC/JO after ADD, JZ/JO after INC). Again, have a clear route for any kind of "out of range" error that may occur.
Post 13 Sep 2018, 06:19
View user's profile Send private message Visit poster's website Reply with quote
wean_irdeh



Joined: 12 Sep 2018
Posts: 12
wean_irdeh 13 Sep 2018, 10:43
Tomasz Grysztar wrote:
...


Thank you! That is clear enough!
Post 13 Sep 2018, 10:43
View user's profile Send private message Reply with quote
Furs



Joined: 04 Mar 2016
Posts: 2582
Furs 13 Sep 2018, 12:05
wean_irdeh wrote:
Hi guys, I was having discussion with Reddit users on vulnerability which might arise when writing asm, and their answer was the C code vulnerability also applies to asm, but worse since there are no compiler warning and mitigation

Link to the discussion:
https://www.reddit.com/r/AskNetsec/comments/9f5exx/what_vulnerability_might_arise_when_writing/
https://www.reddit.com/r/hacking/comments/9f5d5x/what_vulnerability_might_be_arise_when_writing/

Only one thing I know asm does better than C is there are no undefined behavior.

If so what are you guys gonna do to secure your handwritten code, I'm also curious on how MenuetOS handles things,
thanks in advance
Everytime someone brings up how a language is bad at security because it's "easy" to do something bad, ask him to stop looking for a scapegoat for his real problems. The problem is between the chair and the keyboard.

Of course the language can be at fault, if it's designed such that you cannot write secure code no matter what. But that is not the case here.
Post 13 Sep 2018, 12:05
View user's profile Send private message Reply with quote
DimonSoft



Joined: 03 Mar 2010
Posts: 1228
Location: Belarus
DimonSoft 13 Sep 2018, 13:25
Furs wrote:
Everytime someone brings up how a language is bad at security because it's "easy" to do something bad, ask him to stop looking for a scapegoat for his real problems. The problem is between the chair and the keyboard.

Of course the language can be at fault, if it's designed such that you cannot write secure code no matter what. But that is not the case here.

I’d say it’s not about black and white (can or cannot write secure code). Programming is 50 shades of gray: there are absolutely terrible languages which make it impossible to avoid vulnerabilities (and they mostly die unknown and unused), there are ideal languages (and they do not exist), and there’re lots of levels between them. Some languages just make shooting one’s leg an easy task, while others prevent that as much as they can but introduce certain difficulties in case what you want is to REALLY shoot your leg.
Post 13 Sep 2018, 13:25
View user's profile Send private message Visit poster's website Reply with quote
ACP



Joined: 23 Sep 2006
Posts: 204
ACP 21 Sep 2018, 21:23
There are so many misconception presented both here and on the reddit discussions that I've decided to write my own answer.

First of all I've been waiting for such a topic for many years. There are basically very few resources on the net dealing with secure coding in assembly language. The reason is very few people use it nowadays and with secure coding in asm deal mostly people doing compilers nowadays.

Some myths and misconception:
1. assembly language is safer than C since you don't call functions from external libraries like those operating on strings with buffers hence leading to potential buffer overflows. Untrue: in fact you can (and in many examples I've seen) call external libraries (be it DLL or SO) including system and C ones, hence using dangerous API.

2. some HLL compilers add safeguard to release code (like canary/stack guard for example). None of known to me assembler/linker set does the same. You can implement the same behavior using macros , but you have to do it on your own. This also leads to another important remark: when writing in assembly language your compile code in most cases looks the same as source code. When doing the same in HLL you never know how it will look like at the end or what compiler/linker will add.

3. there are many types of vulnerabilities/software defects like race conditions or weak permissions that has nothing to do with language used, instead those are architecture/security model related issues.

As for security tips in writing secure code in assembly language there are none I am aware of available publicly. The closes you can get is Secure Coding in C, C++ https://www.pearson.com/us/higher-education/program/Seacord-Secure-Coding-in-C-and-C-2nd-Edition/PGM142190.html. It even has some assembly code snippets inside Wink Most if not all tips given in this book can be applied to assembly language.

As for some quick tips:

1. never trust any input
2. always validate and sanitize input and output
3. always lock resources before using them
4. always handle errors and check for errors
5. always free resources after using them
6. do not pass NULL for security parameters
7. always use complete path
8. use all operating system safeguard available (wisely)


Just my 2 cents
Post 21 Sep 2018, 21:23
View user's profile Send private message Reply with quote
Melissa



Joined: 12 Apr 2012
Posts: 125
Melissa 22 Sep 2018, 21:51
Quote:
1. assembly language is safer than C since you don't call functions from external libraries like those operating on strings with buffers hence leading to potential buffer overflows.


Not because of that, rather because you don't have undefined behavior in assembly.
undefined behavior means compiler is free to generate anything, and that is what assembly
makes safer then C.
Post 22 Sep 2018, 21:51
View user's profile Send private message Reply with quote
ACP



Joined: 23 Sep 2006
Posts: 204
ACP 23 Sep 2018, 20:25
Melissa wrote:
Quote:
1. assembly language is safer than C since you don't call functions from external libraries like those operating on strings with buffers hence leading to potential buffer overflows.


Not because of that, rather because you don't have undefined behavior in assembly.
undefined behavior means compiler is free to generate anything, and that is what assembly
makes safer then C.


Again, both statements are false, at least in this particular context.

In fact most C/C++ compilers today issue a warning when using string functions considered dangerous. In some compiler you even have to disable security checks for code to compile with such calls. In assembly language nothing will stop you from passing to small buffer or missing format string for sprintf line function. And I haven't seen any assembler/linker that would issue such a warning like VisualStudio for example.
Post 23 Sep 2018, 20:25
View user's profile Send private message Reply with quote
Tomasz Grysztar



Joined: 16 Jun 2003
Posts: 8363
Location: Kraków, Poland
Tomasz Grysztar 23 Sep 2018, 20:35
ACP wrote:
In assembly language nothing will stop you from passing to small buffer or missing format string for sprintf line function.
I would even say that assembly can be at least as insecure as all other languages combined, because for any unsafe code you could create in another language, you can also do the same in assembly. Wink
Post 23 Sep 2018, 20:35
View user's profile Send private message Visit poster's website Reply with quote
DimonSoft



Joined: 03 Mar 2010
Posts: 1228
Location: Belarus
DimonSoft 24 Sep 2018, 11:09
ACP wrote:
Melissa wrote:
Not because of that, rather because you don't have undefined behavior in assembly.

<…>
In fact most C/C++ compilers today issue a warning when using string functions considered dangerous. In some compiler you even have to disable security checks for code to compile with such calls. In assembly language nothing will stop you from passing to small buffer or missing format string for sprintf line function. And I haven't seen any assembler/linker that would issue such a warning like VisualStudio for example.

It is completely wrong to consider safety of code equal to preventing buffer overflows. You can have buffer overflows without using unsafe versions of C standard string handling functions. They may occur due to arithmetic overflows, logical errors in your code (e.g. not validating size fields in data structures for being within a reasonable range), etc. And buffer overflow is not the only way to compromise a program.

In assembly the definitions of instruction behaviour is much more complete than that of C/C++ operators. And having undefined behaviour in your code in C/C++ gives the compiler unlimited choice of what to generate. Up to crazy stuff like this: https://blog.djmnet.org/2008/08/05/a-pragmatic-decision/. Note that such compiler behaviour is compliant to the C standard. Which is completely different from assembly.
Post 24 Sep 2018, 11:09
View user's profile Send private message Visit poster's website Reply with quote
ACP



Joined: 23 Sep 2006
Posts: 204
ACP 24 Sep 2018, 11:49
Tomasz Grysztar wrote:
ACP wrote:
In assembly language nothing will stop you from passing to small buffer or missing format string for sprintf line function.
I would even say that assembly can be at least as insecure as all other languages combined, because for any unsafe code you could create in another language, you can also do the same in assembly. Wink


Spot on Very Happy
Post 24 Sep 2018, 11:49
View user's profile Send private message Reply with quote
ACP



Joined: 23 Sep 2006
Posts: 204
ACP 24 Sep 2018, 12:07
DimonSoft wrote:
ACP wrote:
Melissa wrote:
Not because of that, rather because you don't have undefined behavior in assembly.

<…>
In fact most C/C++ compilers today issue a warning when using string functions considered dangerous. In some compiler you even have to disable security checks for code to compile with such calls. In assembly language nothing will stop you from passing to small buffer or missing format string for sprintf line function. And I haven't seen any assembler/linker that would issue such a warning like VisualStudio for example.

It is completely wrong to consider safety of code equal to preventing buffer overflows. You can have buffer overflows without using unsafe versions of C standard string handling functions. They may occur due to arithmetic overflows, logical errors in your code (e.g. not validating size fields in data structures for being within a reasonable range), etc. And buffer overflow is not the only way to compromise a program.

In assembly the definitions of instruction behaviour is much more complete than that of C/C++ operators. And having undefined behaviour in your code in C/C++ gives the compiler unlimited choice of what to generate. Up to crazy stuff like this: https://blog.djmnet.org/2008/08/05/a-pragmatic-decision/. Note that such compiler behaviour is compliant to the C standard. Which is completely different from assembly.


Be so kind and reread all my above posts please - you will find exactly the same statement except not a single example taken out of context. Honestly speaking I fail to see how:
Code:
int i;
i++;    

differs from
Code:
inc eax    

in terms of integer overflow case for example. Could you please explain it? I also afraid that I do not follow your idea of undefined behavior of C/C++ compiler. Could you show me an example of the same secure code written in C/C++ and in assembly language where undefined compiler behavior introduced software defect in binary object please? Also I would appreciate if you could point me at any assembler that in fact has some built-in safeguards against buffer overflows? Own macro(s) does not count Wink
Post 24 Sep 2018, 12:07
View user's profile Send private message Reply with quote
DimonSoft



Joined: 03 Mar 2010
Posts: 1228
Location: Belarus
DimonSoft 24 Sep 2018, 12:44
ACP wrote:
Honestly speaking I fail to see how:
Code:
int i;
i++;    

differs from
Code:
inc eax    

in terms of integer overflow case for example. Could you please explain it?

Let’s then talk about semicolon instead, and how it is different from a newline in assembly. But if we switch to a more constructive discussion and take a bigger perspective then maybe we should talk about the size of the i variable in your example as compared to the size of eax and the consequences of this difference for integer overflows? We can move on by discussing whether one’s or two’s complement representation is used in both cases, and again the consequences for integer overflow conditions. Just to begin with.

ACP wrote:
I also afraid that I do not follow your idea of undefined behavior of C/C++ compiler. Could you show me an example of the same secure code written in C/C++ and in assembly language where undefined compiler behavior introduced software defect in binary object please?

The idea is not mine, it’s in the languages’ standards. And your demand for secure C/C++ code with unwanted software defect is either a trick to later say “Ha-ha! It’s not a valid/secure C/C++ code since it has undefined behaviour!” or a real question due to the lack of knowledge about UB in these languages. Nevertheless, I’ll give it a try.

Both true and false: a Zen moment in C
markshroyer.com wrote:
While I cannot reproduce the actual source code here, the effect was that code like
Code:
bool p;

/* ... */

if ( p )
    puts("p is true");

if ( ! p )
    puts("p is false");    
would produce the output:
Code:
p is true
p is false    

Note that this kind of stuff is impossible in assembly, unless you explicitly try to reproduce the C-compiled code behaviour. The logical equivalents to
Code:
if (p)    
and
Code:
if (!p)    
are checks for p being equal/not equal to zero. And if you check the same value you’ll get either one case or another but not both in assembly.

Not even mentioning inter-procedural optimizations that become available when a programmer accidentally strikes the UB land: Undefined behavior can result in time travel (among other things, but time travel is the funkiest). This kind of stuff is impossible when you split your code into procedures on your own.

Next time we may talk about NULL being equal to 0 and (void *)0 but not equal to (void *)x where x = 0, which is not the case of undefined behaviour but the case of “amazing” design of the C language.

ACP wrote:
Also I would appreciate if you could point me at any assembler that in fact has some built-in safeguards against buffer overflows? Own macro(s) does not count Wink

You’re asking for nonsense. Assembler should not insert any additional code by its nature and definition. Asking for an assembler that inserts safeguard code is basically the same as asking for manual transmission capable of selecting gears automatically.

Besides, even in languages with automatic memory management there’re cases when the safeguards are just not enough. Logical errors should be fixed by changing the source code, not by inserting even more code. Safeguards are just for detection of the errors at runtime and shutting down ASAP. It’s like finding terrorists on your plane when you’re already 10 km above the earth and deciding to explode the plane with all the passengers (even if later it turns out the suspicious passengers weren’t terrorists).
Post 24 Sep 2018, 12:44
View user's profile Send private message Visit poster's website Reply with quote
Display posts from previous:
Post new topic Reply to topic

Jump to:  
Goto page 1, 2, 3  Next

< Last Thread | Next Thread >
Forum Rules:
You cannot post new topics in this forum
You cannot reply to topics in this forum
You cannot edit your posts in this forum
You cannot delete your posts in this forum
You cannot vote in polls in this forum
You cannot attach files in this forum
You can download files in this forum


Copyright © 1999-2025, Tomasz Grysztar. Also on GitHub, YouTube.

Website powered by rwasa.