Virtulization

OS Design, Theory, and Programming

Moderator: Moderators

Virtulization

Postby michael » Mon Jan 07, 2008 3:55 am

Okay well I have an idea.. I know its phesable in terms of making it work, but I want to know how feasable it is in terms of making it not go really REALLY slow..

Basically what im thinking is if no code could execute apart from the kernal (and maybe/maybe not drivers), without well being interpreted by the kernal.. I know interpreted laugauges normally work very slow but if the interpreter is down that low level..

My reason for this is not to be lazy with all the security and stuff I'd have to write without this.. Its basically my idea to make something completely unhackable.

If this is pheasable and am I going about it the right way?

At the moment im planning (this is simplified to fit here :) ) to iterate through all running threads, read an virtual opcode and use a lookup table to find a pointer to the call to interpret it.
Then repeat that a certain number of times depending on the priority of the thread or until it decides to take itself of the running threads list.
michael
 
Posts: 29
Joined: Thu Nov 15, 2007 12:06 am

Postby Andyhhp » Wed Jan 09, 2008 12:46 pm

Good Question - That is certainly an interesting idea.

However, I am not sure how feasible it is.

It is certainly possible to make an interpreter although to make a good one is very hard. As for speed, most programs can be made faster by improving algorithms, and using trickery (bit operations, loop unrolling etc).

What I am not sure about is what you are trying to protect against. If you are trying to protect a stand alone computer from any attempt to rewrite the operating system, sadly there is nothing you can do to stop someone who is determined enough
If you are trying to prevent attack via internet, your interpreter would need to know every possible way for the computer to be cracked and prevent it. While this is theoretically possible, sodds law dictates that there is always someone out there who knows more about computers that you do, so can find a way round your protection.

Wishing to move on from the negative side, I do think that this idea has the potential to protect against all but the most determined attacks against your computer.

I hope to hear how you get on with it,

Andrew.
Last edited by Andyhhp on Sat Jan 12, 2008 3:15 pm, edited 1 time in total.
Image
Andyhhp
Moderator
 
Posts: 387
Joined: Tue Oct 23, 2007 10:05 am
Location: 127.0.0.1

Postby michael » Wed Jan 09, 2008 11:27 pm

Hey Thanks :D

Well what im trying to protect against is anyone/anything apart from the actull owner of the physical computer.. Because yeah I know protecting further then that is technically impossible (and pretty much useless).

Going into a bit more detail I want to:

Stop any proccess from blocking everything else from executing by limiting the number of threads etc.

Make a pointer data type that CANNOT be used as a variable other than a pointer (so no memory leaking and strict type saftey etc).

Have a base class library that has "permission" to interact with drivers etc (nothing else does) and for every call made to it that some programs may not be aloud to use require a "permission" object to be passed with it.

These objects can be obtained by asking the user at the time with a dialog box etc. They expire and are very specific to what it can do.

Instances of classes cannot be accessed from another proccess without explicit consent.


Once ive done all this. Well I know there will be people that know more about computers than me (for sure).. But how per say could they "hack" that system without the consent of the user?
Espically if it was very clear on what permissions this "virus", "trojan", etc was trying to obtain
michael
 
Posts: 29
Joined: Thu Nov 15, 2007 12:06 am

Postby Andyhhp » Thu Jan 10, 2008 12:40 pm

From what you want about pointers and base class permissions, it would make sense to write a custom programming language that has that attributes. You might even be able to vastly reduce the workload that your interpreter has to do if it knows that the program was written in your language.

But how per say could they "hack" that system without the consent of the user?


Purely on a point of correctness :P , 'crack' is the word you are looking for. A 'hack' is 'a piece of code written to solve a specific corner case of a specific problem as opposed to code written to solve a problem in a general case.' (Game Coding Complete, 2nd edition by Mike McShaffry <-- brilliant book for any sort of programming at all)

As for the way a virus or trojan gains access to a computer, here is the example of viruses such as blaster and sasser worked.

Take for example the following program:
Code: Select all
#include <iostream>
using namespace std;

char * GetName()
{
  char buffer[20];
  cout << "Enter your name: ";
  cin >> buffer;
  char * name = new char[20];
  strcpy(name,buffer);
  return name;
}

int main(char ** arg,int count)
{
  char * name = GetName();
  cout << "Hello " << name << endl;
}

This is a stupid little example but it proves a point.
The program is expecting someone to enter a name such as 'Andrew' or 'Micheal'. It is not expecting any name longer than 20 characters.

Notice that buffer is declared as a local variable. As such, it is allocated on the stack, below the return address, when the function is called. However, the pointer points to the bottom of the array and copies data upward.

From this, if you enter 24 bytes worth of data, there is no bound checking and these 24 bytes will be written to to the array, past the end, and overwrite the return address.

Now, imagine you entered something stupid like 3000bytes worth of opcode on the end of the 20 character. If you change the return address to the next byte up the stack, you can execute the program you have written onto the stack as soon as the function returns.

Now imagine that this is a ring 0 program, as it was on Windows XP. You can do anything and not be stopped . This particular exploit was addressed in XP SP2.

But from this example, you can see how malicious programs can gain access. Its mainly by lazy coding on the programmers behalf.

Hope this makes sense,

Andrew
Last edited by Andyhhp on Sat Jan 12, 2008 3:15 pm, edited 1 time in total.
Image
Andyhhp
Moderator
 
Posts: 387
Joined: Tue Oct 23, 2007 10:05 am
Location: 127.0.0.1

Postby michael » Thu Jan 10, 2008 8:45 pm

Oh thats actully a very good idea :o :D I was considering that but it would mean making my own compiler :( alot of work ah well..

And oh yuep I knew the difference between crack and hack, well you know how you know things but you kinda forget until you get reminded? :P

Wow thats scary when you think about it.. I had know idea it was that simple. :shock: ...If I had a seperate stack for each thread running (which I am 99% sure I have to do anyway) would that solve all these type of attacks do you think?

Oh and another idea I had was when calling a class library etc, halt the calling thread, use a messanging system to send the data to a seperate thread which then proccesses the request of whatever, sends a message back to the previous thread somehow (Im very abstract when I design things I know lol but its worked for me so far) and resume execution on that thread..
I dont know if this is possible though..
michael
 
Posts: 29
Joined: Thu Nov 15, 2007 12:06 am

Postby Andyhhp » Fri Jan 11, 2008 12:08 am

^_^ - don't worry, i sometimes slip into common habits (I got frustrated after a convo I had with someone went along the lines of:
"OMG - I think someone is hacking my computer!
You sure?
Defiantly - there must be a hacker at another computer trying to hack me over the internet!
Even though your not plugged into the internet?
Oh"
but thats a different story :D )

As for cracking,

It scared me the first time I heard that method. It was explained to me by someone who was employed to assess security risks 20 years ago, when things like the x86 architecture was being designed. It annoyed him because he, and others, were employed to make risks like this and others aware to the designers, who completely ignored the research, and went ahead and designed it how they wanted, not in the most security tight way.

As for having separate stacks: I believe that XP has individual stacks. Either way, any ring 0 program that can be exploited in that way will have the same effect, be it with a small local stack or part of a single stack for the entire computer.

Even if it is only a small stack that can only hold a bit of opcode until it runs into a descriptor boundary (then gets caught by a boundary error or protection fault etc.), it doesn't take much ring 0 opcode to alter the GDT to give itself all the space it needs.

In truth, there are 2 very simple ways to completely prevent this exploit.
1)Have the stack in a separate descriptor and make it non-executable or,
2)Better yet, bound check all inputs which will also prevent both buffer overruns present in my example.
3)Or best yet, do both of the above

As for other malicious access, there are many ways that programs can gain unauthorized access to a computer. This is just the only example that I know. There are people who make their living preventing such ways for a computer to be attacked and there are people who get much enjoyment in writing programs that find a way round the latest security.

I am fairly sure there is not a chance any single person can make a computer completely malware proof. What you need, on top of doing your best to protect your OS from such attack, is to have a part of it that can recognize when it has been compromised and do something about it.

If you end up doing everything by interpretation, they it would not be hard to make a detailed log of everything that happened leading up to the attack, which you can use to plug that hole and prevent it in the future.

As for your idea of communication between threads - that is the basis of a micro-kernal. e.g.
1)Process asks hard disk driver to load a file from the hard disk into memory.
2)Driver says 'Yes ok - wait a bit because the hard disk is very slow' (You get the idea)
3)Process tells the process manager that it is waiting for the hard disk driver before it can continue.
4)Process manager puts process to one side and allows a different process to run.
5)Driver tells both the process and the process manager that the data is ready to collect.
5)Process manager schedules process as the next to run after the current has finished.
6)Process runs and find that its data in now available and continues with whatever it was doing.

The End 8)
(wow - the first ever use I have found for paying attention in OS lectures at uni rather than sleeping ^_^
most of OS lectures is about the fetch-execute cycle on a theoretical 'simple' processor - i.e. completely invented for people who don't know ASM or how to write operating systems)

I hope I'm not sending people to sleep reading my ramblings,

Andrew
Last edited by Andyhhp on Sat Jan 12, 2008 3:16 pm, edited 1 time in total.
Image
Andyhhp
Moderator
 
Posts: 387
Joined: Tue Oct 23, 2007 10:05 am
Location: 127.0.0.1

Postby Warsome » Fri Jan 11, 2008 3:00 am

That example applys to web programming as well, PHPBB had a major security issue not long ago.

It seems that most programmers seem to forget to check all input and output, in programming nothing should be seen as safe untill you check the data it holds.

Im still learning computer programming so here is an example using php.

Code: Select all

    if (!empty ($_GET["somevar"]))
    {
        // we want this to be a number only
        if (ctype_digit ($_GET["somevar"]))
        {
            // we want the number to be between 1 and 1000
            if (($_GET["somevar"] <1001> 0))
            {
                define ("thisNumber", $_GET["somevar"]);
            }
        }

        if (!defined ("thisNumber"))
        {
            print "Error: somevar must be any number between 1 and 1000";
        }

        else
        {
            if (isset ($query))
            {
                unset ($query);
            }

            if (isset ($doQuery))
            {
                unset ($doQuery);
            }

            $query = sprintf ("SELECT * FROM `table` WHERE b='%d'", thisNumber);

            $doQuery = @mysql ($query);

            if ($doQuery)
            {
                if (mysql_num_rows($doQuery) > 0)
                {
                    print "Success!";
                }

                else
                {
                    print "Failed!";
                }
            }

            else
            {
                print "MySQL error!";
            }
        }
    }

    else
    {
        // print html data here
    }



This is very simple easy steps in implementing checks on data, it does not matter if it's PHP, C++, or V.Basic, never trust data from anybody.
User avatar
Warsome
 
Posts: 21
Joined: Sun Nov 18, 2007 3:13 am

Postby Andyhhp » Fri Jan 11, 2008 12:16 pm

One way that bugs like this can occur by accident is when a programmer writes a small utility for his/her own use.

As its for personal use, the programmer doesn't bother to check all inputs because they know that only they are going to use it, and know how to use it correctly.

However, months later when the programmer is working on a different project, they realize that the utility they wrote ages ago is exactly what they need here, so they just add it into the project, with the knowledge that it works, and continue with the project.



Another way that a bug can creep in is of a programmer has a tight deadline and makes sure the project is completed on time, rather than putting in all the validation code needed for the project to be error free.

Andrew
Last edited by Andyhhp on Sat Jan 12, 2008 3:16 pm, edited 1 time in total.
Image
Andyhhp
Moderator
 
Posts: 387
Joined: Tue Oct 23, 2007 10:05 am
Location: 127.0.0.1

Postby Warsome » Fri Jan 11, 2008 5:09 pm

I always place the validation code in at the beginning while im writing a function, class.

Even for personal use. For example, I created a utility that automatically can compute a build number based on the date, it takes input such as a past date and a future date and time.

I validate all input even tho I will probably be the only person ever to use it, to speed up my programming for any project I work by a strict set of pre built classes and functions that I know work and are proven to be safe.

If I come across a new function that is needed, I create that functon in the lib so it can be used in other projects too, but before I add it to the main lib trunk, I fully test it for any and all exploits and errors.

Yes I try to crack my own code :lol:
User avatar
Warsome
 
Posts: 21
Joined: Sun Nov 18, 2007 3:13 am

Postby Andyhhp » Fri Jan 11, 2008 5:49 pm

Honestly, I'm not quite that diligent about validation for personal projects.

However, I probably go OTT on any project that i am not making specifically for myself. I spose this is good in a way because it makes it less likely that exploits exist but it can sometimes lead to very messy code.

There is nothing wrong with trying to crack your own code. Just get someone else to try cracking it as well to cover all the possibilities that you missed when trying to crack it :lol:

Andrew
Last edited by Andyhhp on Sat Jan 12, 2008 3:17 pm, edited 1 time in total.
Image
Andyhhp
Moderator
 
Posts: 387
Joined: Tue Oct 23, 2007 10:05 am
Location: 127.0.0.1

Postby Warsome » Fri Jan 11, 2008 8:10 pm

I do that too, I release it for people to do anything they want to it while it's in dev, if it is to be a project that I will sell, if they manage to crack it and provide full info of where my errors are, I let them have a free copy :lol:

I get great feedback from it and it's not everyday a cracker gets rewarded by a dev.

Im kind of a bit brassed off the last few days, I beta tested vista since longhorn was a baby, and there reward was an email I got the other day.

Beta Tester Reward Offer:
Buy a full copy of Windows Vista Ultimate costing 326 GBP and get an upgrade edition of Windows Home Premium free.

Wow that is so exciting. I give away free software and they give away free bugs.
User avatar
Warsome
 
Posts: 21
Joined: Sun Nov 18, 2007 3:13 am

Postby michael » Sat Jan 12, 2008 2:01 am

Adding input validators and stuff is nice but not always neccasary even for proper projects..

Only for methods, properties etc that are exposed as public should really be checked otherwise your cutting a (possibilly big) performance loss. :cry:

As for sticking all your functions and stuff into one library.. If you distribute that people will get hold of your library and could use it for themselves :shock: *shudders* I always put all my code in one assembly if possible.. Copy and paste it from snippets and stuff from in OneNote :D .. but thats just me..

an' hey.. beta testing is fun :) Think of poor people like me with no broadband that would love to :cry: lol.. Ah well so typical of microsoft :roll: ..
michael
 
Posts: 29
Joined: Thu Nov 15, 2007 12:06 am

Postby Andyhhp » Sat Jan 12, 2008 12:49 pm

Buy a full copy of Windows Vista Ultimate costing 326 GBP and get an upgrade edition of Windows Home Premium free.

:shock: Lol - how stupid do they think we are??

Only for methods, properties etc that are exposed as public should really be checked otherwise your cutting a (possibilly big) performance loss.

Not totally. Whilst data that is being moved around inside your program should be fine, as it knows what it needs and is expecting, this is not always the case. If one part of your program is compromised, it could send unvalidated data to other parts and compromise the entire program.

Still - I agree that the amount of checking that goes on is a compromise between security and speed/size.

Andrew
Image
Andyhhp
Moderator
 
Posts: 387
Joined: Tue Oct 23, 2007 10:05 am
Location: 127.0.0.1

Postby michael » Sat Jan 12, 2008 11:38 pm

Just a note on your sign Andrew :P thats not my service provider :P...

Hmm program size doesn't really matter though.. When you look how big office is they're probally all in cahoots with the hard disk manafactures :roll:

Yea I suppose.. Checking should be avoided where possible though.. Like there's no point checking something only to send the data through to be checked again. What I would often do is create a method without checking and create a wrapper for it with checking :) though thats another story with the call stack and blah blah.. hmmm.. I suppose there's no perfect way to do anything then.
michael
 
Posts: 29
Joined: Thu Nov 15, 2007 12:06 am

Postby Andyhhp » Sat Jan 12, 2008 11:50 pm

Hmm - If it isn't your ISP then its your ISP's ISP.

The perfect un-exploitable bit of code would be something that required no input at all - but there are limited applications of this sort of program.

I guess there is no perfect way.
Image
Andyhhp
Moderator
 
Posts: 387
Joined: Tue Oct 23, 2007 10:05 am
Location: 127.0.0.1

Next

Return to Advanced OS Development

Who is online

Users browsing this forum: No registered users and 1 guest

cron