In this scenario the user will submit his/her C code to my server through a browser.
The code will then be compiled and executed on my server and the output will be sent to the user.
Since the user can submit any code (including Viruses, or other malfunctioning code). I will have to take care of that.
So my question is, how can I secure my server from such code?
I cannot answer you for windows -- I can tell you for linux.
This is an extremly complex problem. You need to think to:
quota limit
process that compiles/executes the code to be runned as an unprivileged user.
do not allow the process to run more than N seconds
do not allow process to allocate too much memory
I can say that this is a long-term project that you can not finish correctly in a few weeks.
Your question is perhaps equivalent to the halting problem, and probably has no bullet proof answer (think of asm in malicious C code, forged function pointers, computed goto, buffer overflow trashing the return address, dlsym & dlopen, etc.).
As mentioned by Shawn in his comment (referring to this question), you could use sand-boxing techniques. Alinsoar's answer shows you the complexity of the issue.
Other problem to think to : what rights to allow the guest process: is he allowed to open a socket ? If so , what traffic do you allow him ?
In the case you open a socket, then the problem becomes even more complex, because he can deliver an attack over that socket...
You might consider using ideone API, some mobile devices software do so (CodeToGo for example)
Related
I have a set of independent programs that I wrote in C. I would like all of them to write their log to the same file. Obviously comes the issue of control access. Two or more of them could end up writing simultaneously.
What is the most pragmatic way to achieve this?
I came across solutions using pthread/mutexes/etc but that sounds overkill implementation for something like that.
I am also looking at syslog but wonder if this is really for the purpose of what I need to do?
I feel that I need a daemon service taking the message and control when they are written. I wonder if that already exists.
I am also looking at syslog but wonder if this is really for the purpose of what I need to do?
Yes
I feel that I need a daemon service taking the message and control when they are written. I wonder if that already exists.
It exists in the Unix derivatives (including Linux) and is called... syslogd
More seriously, the syslog function is intended to pass a message to a syslogd daemon that will route it according to its configuration file. Most common uses include writing it down to a file or to the system console (specially for panic level messages when nobody can be sure whether the file system is still accessible). The syslog system may come with more features than what you are asking for, but it is an extremely robust and extensively tested piece of software. In addition, it is certainly already active on your system, so you should have a strong reason to roll your own instead of using it.
You have two way :
First : Using something that already exist.
For the logging part, syslog (and syslog-ng) are well-know and well-used.
From that point, you can parametre syslog-ng to listen to an ip connection, and scan a dir for new file.
Your program can, when they will want to log, either connect to syslogng directly and send the log, and if the connection fail, write a new file in the directory that syslogng watch.
That allow to not have the loss of the log is syslog-ng are interrupted for a reason or another.
Second : Develop something really similar to syslog-ng.
In that case, it's up to you.
When I execute on solaris 11.0:
pfiles /proc/PROCESSID
The result is process information, a small chunk of output is what interest me:
4: S_IFSOCK mode:0666 dev:543,0 ino:46228 uid:0 gid:0 size:0
O_RDWR|O_NONBLOCK
SOCK_STREAM
SO_REUSEADDR,SO_KEEPALIVE,SO_SNDBUF(49152),SO_RCVBUF(128480)
sockname: AF_INET6 ::ffff:10.10.50.28 port: 22
peername: AF_INET6 ::ffff:10.16.6.150 port: 55504
The process I pfiles /proc/PROCESSID is the sshd session itself.
My question is given a process id, how can i get this (pfiles) information from within a kernel code ?
When looking in struct proc i could not find something that give me this data.
Is there a pointer to struct that hold all open files occupied by the process on the proccess' proc?
I also executed truss pfiles /proc/PROCESSID but could not find the exact call
If you look in /usr/include/sys/user.h you'll see the open file information can be found in the p_user.u_finfo structure of the current process.
Walking that structure is not trivial. Just look at what the proc filesystem code has to do to look up the attributes of just one open file descriptor. There's lots of locking needed - you can't simply walk the data structures while things are running.
And, the following is beyond the scope of the question, but it's important...
For what it's worth, what you're doing can't work. It's fundamentally flawed - technically and legally.
What you're trying to do - track users who share a user account - is worthless anyway. You will never be able to prove that just because a certain login session executed some code that the code was executed because the user logged into that session purposely ran that code. Because any of the users with access to that account can modify the environment of the shared account such that malware is run by someone else. And they can make it look just like a typed-in command.
Shared credentials and accounts violate nonrepudiation. That's your insurmountable legal flaw in using any data your custom kernel tracking may produce - even if you manage to produce a system that's foolproof, which isn't likely.
If I'm logged into a shared account, you can never prove that the code I ran was run intentionally.
Well, that's not entirely true - if you have perfect auditing where you can trace every thing a user does down to the bytes modified on disk, you can. And "perfect" in this case means those users have no access whatsoever to change any part of the auditing system.
But if you already have perfect auditing in place, you don't need to write kernel modules to try and implement it.
Of course, it's impossible to prove you have perfect auditing in place because you can't prove that you don't have holes in it.
See the problem?
We're right back to "You CAN'T prove I did it intentionally."
You'd be much better off just using the OS-provided auditing services. Whatever you come up with isn't going to be useful in proving "who did it" for any intelligent bad actor - like someone who figures out a way to insert malicious code into another user's session. And the OS auditing will be sufficient to catch anyone who has no clue in how to cover their tracks.
But you won't be able to provably catch any bad actor who knows what he's doing when shared accounts are involved. And if you can't prove it, you might not even be able to do anything at all to someone you suspect. Because someone who really knows what they're doing will be able to pin the apparent blame on someone who's innocent - if they can't hide or destroy the evidence of the bad act[s] in the first place.
What are you going to do if you find the shared .profile file has a line in it that after a certain date emails sensitive data to a throwaway email account, but only when the login comes from a certain IP address?
Any one of the users who share that one account could have put it in there.
No auditing system in the world can solve that problem unless it's perfect and tracks every file change.
If the data you're trying to protect is important, whoever is tasking you to solve the problem by writing custom kernel modules needs to grow a brain and solve the real problem - shared user accounts. Get rid of them.
There's a reason why every security guide says not to use shared accounts, and every security audit I've ever seen will fail anyone using shared accounts.
So I started network programming a few days ago, and I created a very simple trojan (Victims execute a client that create a connection to the hackers PC's and then Hackers can execute function of CMD by a simple system() command).
Basically my trojan works but I don't understand why my Anti-Virus doesn't detect it. I mean the only thing that possibly could have stopped my trojan is my firewall which detected an outgoing connection. So I don't understand why other trojans are detected but not this new one.
I can provide source code if needed, and I would like to emphasize that I do this only for educational purposes. I will never use any of this knowledge to attack anyone (Anyway I don't have enough skill), I just want to learn and understand :).
Avira :
AMES is using the Avira engine for virus detection. If the Avira
engine is not able to detect a virus, then the most likely cause could
be that this virus is brand new and cannot be detected yet. We would
greatly appreciate if you submit the suspicious file to us so we can
analyze it immediately. Our virus lab will subsequently send you a
feedback. If we cannot detect the suspicious file as a virus, we will
work on creating an update to make sure we detect the file in the
future.
AVG :
Sometimes a new virus is not detected even if your AVG is fully up to
date. This happens when a threat has just been written or released, or
we’ve discovered it only very short time ago and are now working on an
update that will recognize and contain the virus.
DELL (https://powermore.dell.com/technology/teaching-your-computer-to-detect-new-viruses/) :
Most antivirus programs use signatures — mathematically derived
strings or regular expressions of malware code — to detect viruses.
But that requires a lengthy process of finding malware in the wild,
getting a sample, analyzing it, generating a signature and adding it
to the repository that is pushed to users in anti-virus updates.
So it seems, like mentioned in the comments, that viruses are only detected when their signatures are recorded by the security software.
Here is a link on how you can use ClamAV to create your own signature : http://blog.adamsweet.org/?p=250
It's not detected because most Antivirus are based on signatures (blacklisting) and that approach is basically not effective to stop malware because ir requires:
an Antivirus company to collect a sample, confirm it and write a
signature for it;
Issue a database update;
People in general
to update their virus database definitions.
Until steps 1-3 are taken, a virus is free to spread and attack your devices. Plus, since step 3 involves people cooperation (allow the antivirus to update) the attack window might not be so short.
It is generally accepted that the efficiency of signature-based antivirus is around 40%-45%.
In the last couple of years, antivirus companies are finally admitting that virus signatures are not the way to go, and they must change from that to behaviour analysis:
http://www.pcworld.com/article/2150743/antivirus-is-dead-says-maker-of-norton-antivirus.html
I was recently downvoted (which only bugged me a little :) ) for an answer I gave to this question. The person offered no explanation for the down vote which started me thinking: "Why would you avoid producing intermediate files?" Especially in a language like Python where File IO is laughably easy.
There seemed to be consensus that it was a bad idea, but I know for a fact that intermediate files are used regularly in practice. I worked for a very well respected research firm (let's just say S.O. wouldn't exist without this firm) where it was assumed that your programs would produce files as output. We did this because if your program indeed deserved to be a standalone program then it would need debuggable output and some way of passing its output between processes that could later be examined in case we discovered an error in our output further downstream.
Is it considered bad practice (in cases like the question linked above) to use intermediate files? Why?
One problem with intermediate files happens when multi-threading.
If Clients C1 and C2 are handled simultaneously by server process S (which may or not have forked into seperate processes, used threads, or whatever concurrency system..), you may get weird issues when both try to create the same intermediate file.
I believe one of Unix philosophies is that all programs should act as filters, however this doesn't necessarily mean creating files on the disk, and using intermediate files leads to unwieldly behaviour in my opinion. One should also treat the disk as a last resort and only use it for storing/retrieving data that should be available after powering off the computer, and maybe even take care to allow programs to run on read-only media.
Well, there are some issues when you use files, especially there may be many unexpected failures while accessing or creating the files. The following listed are all the issues that I personally have experienced.
1) The file location is on the remote machine and the network is down. (NFS mounted).
2) There is not enough free space while creating the file.
3) In between the process the user press Ctrl-C to cancel the process the file is not deleted.
4) The file is mounted on the NFS and the network is slow.
5) The folder in which file was created was a soft link and the original link was deleted.
But still we have to use file because there are hardly any options while working in bash. But in C,C++ i think disk access should be considered as the last resort. Program producing files as output is ok, if that is the only way to communicate with the user. But atleast for intermediate savings use of disk files should be minimized.
If you create temporary files properly (with setting platform-specific 'temporary' flag meaning do not flush cache to disk when no urgent need) they are perfectly good if task requires them.
There are almost no things in IT that you can't use while having a good reason to. :-)
I am afraid that several terminologies in my question are wrong. Please bear with me and correct me wherever I am wrong.
I have to write a library/program that will provide set of function to operate a card reader attached at Serial Port. Like to eject card that was inserted in it, user will simply have to call in his code, for example,
cardEject(); // or
track2Data( response); // to read data of track 2 of magnetic stripe.
cardEject() and other functions will themselves take care of opening serial port, writing data to it, checking the acknowledgement, checking error code, resending command in case of failure, etc. I am pretty clear about communicating with devices on serial port.
My question is, after writing all these functions and testing them, how should I provide them to the user.
Should I give him a header file (.h) and an object file (.o)? So that he can link to the object while compiling his actual program.
Should I provide a static library (.a)?
Which one is a better idea?
Is it a good idea that each function open serial port and then close it? Or a initCardReader() opens it, sets its properties and closeCardReader() should close it? All other functions can only be called after initCardReader()?
Now a silly but real question :-) what is the terminology used for such programs? Is it a driver or library or device interface? What is the correct label for such projects?
Thanks for your time.
Edit
Thanks to all of you for guiding me. Really appreciated.
This API has to become part of a larger project. In fact, I will be working on that project too. But there is a strong possibility that this API will be used in other projects with or without me. I think, considering the possible use in other projects, library makes more sense. Kindly correct me if I am wrong.
I'll go with the answer from Anders K. you are writing a API for your card reader.
My two cents about the more general questions:
Your question about open/close connection, there are two aspects that you have to keep in mind. Lets assume you proceed the way in which you leave it up to the user to open and close the connection. What if he forgets to close it after he finished, what when multiple processes access the card-reader? In those scenarios you may want to free the port to the other processes after each write/read. In the end it depends on the operations that will be done, the process using your API will usually always call your read method multiple times you might want to leave it open or you could implement a read multiple records in your API again avoiding the possibility that a connection gets left open.
I would make a library if it is mainly used in other projects. It also puts you into the position of changing the lib at one place for everyone to implement. Again depending on where you will implement it, there are numerous scenarios when adding your code is the better option.
I think you should do it as simple as possible, a static library and a header file should be a good start.
One way is to treat the card reader in the same way any other resource like a file, meaning you open/init the card reader and return some handle that identifies the card reader. Then subsequently use that in all functions when accessing the card reader.
My two cents:
I think how you provide the output depends on the user. Is this person working closely with you in the same company / project, or is this going to an external source?
If its going external definitely make it a library...it may be easier to create a library in the other case as well, since it would mean less things for this other user to worry about.
Is your code going to be integrated into a larger project? If so, you should just build your code into a subfolder in this project and provide him with the required functions that are needed. I think this portion is more subjective than anything.
Regarding opening/closing the ports, again it depends how it will work. If you are simply providing the API for other programmers to use (and don't know how it will work), I would say abstract it into an initCardReader/closeCardReader function call. That way, if the user wants to do multiple transactions he doesn't need to worry about wasting processing time with each call he makes...he can simply open/close at his discretion.
And it sounds to me like you are writing API calls for a card-reader device driver ;)
You can put this set of functions in the shared lib (like: libCardReader.so) and give away with the Header file to the programmer to reference and use it in his/her code. The following link provide very good intro about building the SO file (http://www.network-theory.co.uk/docs/gccintro/)