Hi
I'm trying to make a security feature for my C Project, so that if someone steals it, it becomes useless.
It works as following:
The main function only runs if the comparison of my macbook's Serial to an encrypted one is 1.
The Problem is that I cannot get the system info in the program.
When I do:
int main ()
{ i=0;
if (strcmp(system("system_profiler SPHardwareDataType | grep \"Serial Number\""),
"Serial Number (system): W80314GJATP"));
{
bla
bla
bla
}
else {for(i=0;i<100;i++)
{printf("Unauthorized Computer");
}
return 1;
}
It only prints info to stdout.
Is there a way to do that comparison?
Best Regards
Not an answer to your question, but keep in mind that these tricks are never really secure.
See for example this post at lifehacker (this is about OS X, but it doesn't really matter).
system() does not return a char pointer, it returns the exit code (an int) from command that was run. You could use popen() to run a command. popen() will return a FILE* that you can read from (it is from the program's stdout). You can then read and parse the program output accordingly.
system returns an int not a const char * of what would show up on the command interrupter. If you want the output of the program you will need to get that programs stdout.
Take a look at this question on how to get the output from a pipe.
If you honestly want to make it secure, use (for example) a BIOS serial number (or hard disk serial number) as a key to encrypt the executable. Write a small wrapper that reads the same data, uses it to decrypt the executable, and then runs the result. At least without access to the original hardware, this can be fairly difficult to work around (unlike the comparison you're doing). OTOH, with access to the original hardware, this is pretty easy to break as well.
Related
If you dont want the long sschpeal head the the last paragraph-->
I found a buffer overflow vulnerability in a program that is using gets() to fill a function's local 1024-char* buffer. It's on Sparc Solaris 5.8 (sun4u) 32-bit.
The first obstacle to overcome was the tch was not letting me manually input > 257 chars
(256 if I want to be able to hit enter ;)
To bypass this, I have been executing /bin/sh and stty raw and I can effectively overflow the buffer now with > 1095 chars.
(Note : I have to use Ctrl-J to do line-feeds/enter , though I haven't researched stty raw to examine why this change occurs.
My issue is this: it is now time to not only overflow the buffer but also write new return address / preserve %fp in hex codes. But since I know of no way to manually enter hex codes from inside a terminal program, I figured I could find a way to use C and have it execute/interact with the vulnerable program and eventually send it my custom buffer.
HOWEVER, if I had a way to manually enter / copy paste hex bytes, I could just do something EASY like this!!!
perl -e 'print "n" . "A"x1094 . "\xff\xbe\xf5\x58" . "\xff\xbe\xff\x68" . "\0"'
(if you're wondering why I am printing 'n' it is because the vulnerable program checks for a yes/no # index 0 of the string)
because I know no way to manually paste such hex-information, I have been trying in C.
In C, I craft the special buffer and have been learning to popen() the vulnerable program ("w") and fputs my buffer, but it has been working iffy at best. (popen and IPC is all new to me)
(I also tried piping/dup2ing and i got NO results, no evidence of effective string output/input) not sure what is going wrong, and I experimented much with the code and later abandoned it.
The best to depict the output from my 'popen' program is that there is a segfault in the vulnerable program only by delimiting the buffer at indexes [1096->1099], this is effectively the location of the function's %fp, so it seemed normal # first. However, delimiting the string at indexes HIGHER than this leaves the programing working fine (WTF)!!! And that sort of behavior makes me think WTF!!? That is not the same behavior as manually pasting, as going more chars most definitely changes seg fault -> bus error, because I will be next overwriting the return address followed by whatever possibly important info in that stack frame and beyond!!
Is the whole string not actually getting sent in one bang?!?!? I heard something about buffer fflush() issues from the popen() manpage, but I dont understand that talk!!
It's my first time using popen(), and there is more behavior that I have deemed strange-> if i stop fputs()ing data , the vulnerable program goes into an infinite loop, repeatedly printing the last output string that it NORMALLY would
only print once,
but in this case, whenever i stop fputs'ing, the thing starts infinitely printing out. Now, I expected that if I am not outputting, wouldn't the program just sit and wait for more input like a good duck. ??? apparently not. apparently it has to keep on pissing and moaning that I need to enter the next string!! is this normal behavior with popen?! Perhaps it is due to my popen' program exiting and closing with pclose(), before actually finishing (but i was expecting a buffer overflow and i dont know why I am not getting it like I could when pasting manually)
Note: I am using "\r\n" to signal the vulnerable program to do a 'return' , I am not sure the equivalent of CTRL-J / Enter key (which enter key does not work in raw tty). I am also not sure if raw tty is even necessary when piping a buffer.
then I thought I try to be clever and cat the strings to a file and then do a pipe via command line. I have no idea if u can pipe like this to a program expecting inputs
in this form, I could not even get a single overflow!! i.e.
printf "\r\n" > derp && perl -e 'print "n" . "A"x1025' >> derp && printf "\r\n" >> derp
cat derp | ./vuln
Now, rewind <-> back in tsh, i said I have a 257 char limit, and i needed to do ONE LESS THAN THAT if i wanted to be able to hit enter and have the program continue operation. So, perhaps \r\n is not right here, cause that's 2 chars. either that or you just Cannot cat into a program like this. But I AM using \r\n in my C programs to tell the vulnerable program that I have hit enter, and they are at least mildly more functional (not really), though still not overflowing the buffer in the same fashion as manually pasting my trash buffer.
ARGh!!!
Also, using just one or the other: '\r' or '\n' was most definitely not working! is there another control char out there I am missing out on? And is it possible that this could be one of my issues with my programs???
but basically my whole problem is I cant' seem to understand how to create a program to run and interface with a command-line executable and say hey!!! Take this whole buffer into your gets(), i know you'd really love it!! just as I would if I was running the program from terminal myself.
And i know of no way to manually paste / write hex codes into the terminal, is the whole reason why i am trying to write an interacting program to
craft a string with hext bytes in C and send to that program's gets()!!!!
If you jumped to this paragraph, i want you also to know that I am using specifically /bin/bash and stty raw so that I could manually input more than 257 chars (not sure if I NEED to continue doing this if I can successfully create an interacting program to send the vulnerable program the buffer. maybe sending a buffer in that way bypasses tch' terminal 257 char limit)
Can anyone help me!?!?!?!?!
The popen call is probably the call you want. Make sure to call pclose after the test is finished so that the child process is properly reaped.
Edit Linux man page mentioned adding "b" to the mode was possible for binary mode, but POSIX says anything other than "r" or "w" is undefined. Thanks to Dan Moulding for pointing this out.
FILE *f = popen("./vuln", "w");
fwrite(buf, size, count, f);
pclose(f);
If the shell is reading with gets(), it is reading its standard input.
In your exploit code, therefore, you need to generate an appropriate overlong string. Unless you're playing at being expect, you simply write the overlong buffer to a pipe connected from your exploit program to the victim's standard input. You just need to be sure that your overlong string doesn't contain any newlines (CR or LF). If you pipe, you avoid the vagaries of terminal settings and control-J for control-M etc; the pipe is a transparent 8-bit transport mechanism.
So, your program should:
Create a pipe (pipe()).
Fork.
Child:
connect the read end of the pipe to standard input (dup2()).
close the read and write ends of the pipe.
exec the victim program.
report an error and exit if it fails to exec the victim.
Parent:
close the read end of the pipe.
generates the string to overflow the victim's input buffer.
write the string to the victim down the pipe.
Sit back and watch the fireworks!
You might be able to simplify this with popen() and the "w" option (since the parent process will want to write to the child).
You might need to consider what to do about signal handling. There again, it is simpler not to do so, though if you write to a pipe when the receiver (victim) has exited, you will get a SIGPIPE signal which will terminate the parent.
Nothing is yielding results.
Let me make highlights of what I suspect are issues.
the string that I pipe includes a \n at the beginning to acknowledge the "press enter to continue" of the vulnerable program.
The buffer I proceed to overflow is declared char c[1024]; now I fill this up with over 1100 bytes. I don't get it; sometimes it works, sometimes it doesn't. Wavering factor is if I am in gdb (being in gdb yields better results). but sometimes it doesn't overflow there either. DUE TO THIS, I really believe this to be some sort of issue with the shell / terminal settings on how my buffer is getting transferred. But I have no idea how to fix this :(
I really appreciate the help everybody. But I am not receiving consistent results. I have done a number of things and have learned a lot of rough material, but I think it might be time to abandon this effort. Or, at least wait longer until someone comes through with answers.
p.s.
installed Expect, :) but I could not receive an overflow from within it...
I seemed to necessitate Expect anyways, because after the pipe is done doing its work I need to regain control of the streams. Expect made this very simple, aside from that fact that I can't get the program to overflow.
I swear this has to do something with the terminal shell settings but I don't have a clue.
Another update
It's teh strangest.
I have actually effectively overwritten the return address with the address of a shellcode environment variable.
That was last night, Oddly enough, the program crashed after going to the end of the environment variable, and never gave me a shell. The shellcode is handwritten, and works (in an empty program that alters main's return address to the addr of the shellcode and returns, simply for test purposes to ensure working shellcode). In this test program Main returns into my SPARC shellcode and produces a shell.
...so.... idk why it didn't work in the new context. but thats the least of my problems. because the overflow it's strange.....
I couldn't seem to reproduce the overflow after some time, as I had stated in my prior post. So, i figured hey why not, let's send a bigger,more dangerous 4000 char buffer filled with trash "A"s like #JonathanLeffler recommended, to ensure segfaulting. And ok let's just say STRANGE results.
If I send less than 3960 chars, there will NOT be an overflow (WTF?!?!), although earlier i could get overflow at times when doing only about 1100 chars, which is significantly less, and that smaller buffer would overwrite the exact spot of return address (when it worked .*cough)
NOW THE strangest part!!!
this 'picky' buffer seems to segfault only for specific lengths. But i tried using gdb after sending the big 4000 char buffer, and noticed something strange. Ok yes it segfaulted, but there were 'preserved areas,' including the return address i previously was able to overflow, is somehow unharmed, and u can see from the image (DONT CLICK IT YET) Read the next paragraph to understand everything so u can properly view it. I am sure it looks a mess without proper understanding. parts of my crafted buffer are not affecting certain areas of memory that I have affected in the past with a smaller buffer! How or why this is happening. I do not know yet. I have no idea how regular this behavior is. but i will try to find out .
That image takes place about 1000 bytes in from the buffer's start address. you can see the 'preserved memory segments', embedded between many 0x41's from my buffer ("A" in hex) . In actuality, address 0xffbef4bc holds the return address of 0x0001136c, which needs to be overwritten, it is the return address of the function that called this one, 'this one' = the function that holds the vulnerable buffer. we cannot write (*the function that vulnerable buffer belongs to)*'s return address due to the nature of stack windows in SPARC -- that return address is actually BELOW the address of the buffer, unreachable, so therefore we must overwrite the return address of the function above us. aka our caller ;)
Anyways the point is that I was also able to previously overflow that return address sometimes with a smaller buffer. So WTF is up with these gaps!!?!??! Shouldnt a larger buffer be able to overflow these, esp. if the smaller buffer could (though not consistently).. Whatever, here's the image.
[image] http://s16.postimage.org/4l5u9g3c3/Screen_shot_2012_06_26_at_11_29_38_PM.png
So, this seemed simple at first, but after crawling Google and here, the answer doesn't seem as simple as I first thought.
Basically, I'm editing a MINIX kernel as part of a practical for my Operating Systems course, and I have to add a little function that spits out the number of running processes when you hit a function key in the Information Server. I've figured out how to integrate the functionality so all the other stuff works, but for the life of me, I can not figure out how to get the current number of processes running in the system into my C code and into a variable to print out.
First I thought there'd be a nifty Syscall like SYS_NUMPROCS or something that'd return the value, but no luck.
Then, I tried piping output from a system("ps -ax | wc -l") to a file and the file wouldn't create. I tried using popen() and no luck there either - even with a simple "ls" read into a buffer, it just bombs the code and "hangs" the run of the code, so there's no output.
So now I'm truly stumped, and any help would be super awesome, because at this point I've exhausted all the obvious options.
The only two things I can think of now would be a loop counting all the processes, but first you have to get to the system's process list, and I've heard vague things said about /proc/ as a directory, but I haven't a clue how to access/run through that or how it'd link up to getting the number of processes in the first place.
Thanks a stack (lol pun), guys :)
Also, I haven't included code explicitly because nothing I've written aside from basic printf'ing for cosmetic output, because none of the things I've tried gave me any joy :/
Edit notes: Guys, this is a kernel edit - I'm writing the function to printf the information in a system C file, then recompiling the kernel and rebooting the system to test. It's a UNIX (MINIX) kernel, not a Linux kernel, and it's not a user mode program.
My code for popen(), as some of you requested, is as follows:
public void cos_dmp(){
char buffer[512];
FILE * f;
f = popen("ps -ax | wc -l","r");
fgets(buffer, sizeof(buffer),f);
//buffer should now contain result of popen()
printf(buffer);
}
That's a bit of a hacked together version from what I remember and keeping it ultra simple and showing you guys that's what I was trying to do. Again though, there must be a better way to do this aside from essentially calling the output of a system() call.
Edit again: the above code woks perfectly from a user program but won't work from the kernel function. Anybody have an idea why?:/
struct kinfo kinfo;
int nr_tasks, nr_procs;
getsysinfo(PM_PROC_NR, SI_KINFO, &kinfo);
nr_procs = kinfo.nr_pro;
This will get you the number of processes running
try looking to see what ps does. Look at its source code; it knows how many processes there are
Perhaps you could show us the code your wrote for capturing the result of system("ps -ax | wc -l"), or the code you wrote to use popen and we could help you diagnose the problem with it.
Regardless, the most efficient way I can think of to count the number of existing (not the same as running) processes on the system is to opendir("/proc") and count the number of entries that are strings of decimal digits. Each process in the system will be represented by a subdirectory of /proc, named after the decimal process id number of that process.
So, if you find "/proc/3432", for example, then you know that there exists a process with a pid of "3432". Simply count the number of subdirectories you find whose names are decimal numbers.
Assumptions:
You are asking about Linux, not MINIX.
You are writing a user-mode program, not modifiying the kernel.
So I have been having the same problem and found a solution. (MINIX 3.1) within the method to count the processes use this code:
(This is ANSI C)
It simply runs through the process table and counts the number of processes.
I know this is an old thread but it might help someone in the future.
#include "../pm/mproc.h"
/* inside function */
struct mproc *mp;
int i, n=0;
printf("Number of running processes:\n");
getsysinfo(PM_PROC_NR, SI_PROC_TAB, mproc);
for (i = 0; i<NR_PROCS; i++) {
mp = &mprocs[i];
if (mp->mp_pid == 0 && i != PM_PROCS_NR) continue;
n++;
}
printf("%d", n);
/* function end */
I had the same assignment at my university so i will post my solution if someone needs it in future. I am using Minix 3.3 and VMware player for virtual machines.
In pm server at location /usr/src/minix/servers/pm there is glo.h file which contains various global variables used by pm server. In that file, there is fortunately one variable called procs_in_use defined as EXTERN int procs_in_use;
So simple printf("%d\n",procs_in_use); from a system call will show the number of current processes running. You can test this by adding fork() function in your user space program in the middle of a loop.
One more mention : first answer that says
struct kinfo kinfo;
int nr_tasks, nr_procs;
getsysinfo(PM_PROC_NR, SI_KINFO, &kinfo);
nr_procs = kinfo.nr_procs;
didn't work out for me. SI_KINFO no more exists so you should use SI_PROC_TABLE. Also there can be problems with permissions, so you will not be able to call this function from your regular system call. There is alternative function sys_getkinfo(&kinfo) that can be called from your fresh system call and that will do the same as the above. The problem is kinfo.nr_procs will not return number of current processes but number of maximum user processes that can be in operative system which is 256 by default, and can be changed manually in file where NR_PROCS is defined. On the other hand kinfo.nr_taskswill return maximum number of kernel processes that can be held by operative system, which is 5 by default.
Check this out: http://procps.sourceforge.net/
It's got source to a number of small utilities that do these kinds of things. It'll be a good learning experience :) and I think PS is i n there as pm100 noted.
If you're editing the kernel, the most efficient way to solve this problem is to maintain a count every time a process (i.e., a task_struct entry) is created (and make sure you decrement the count every where a process terminates).
You could always loop through the list of processes in the kernel using the built-in macro (but its expensive, so you should try to avoid it):
struct task_struct *p;
unsigned int count = 0;
for_each_process(task) {
count++;
}
Check this out: http://sourceforge.net/p/readproc/code/ci/master/tree/
#include"read_proc.h"
int main(void)
{
struct Root * root=read_proc();
printf("%lu\n",root->len);
return 0;
}
Well this is regarding a program for a competition.
I was submitting a program & finding my metrics to be relatively way slower than the top scorers in terms of total execution speed. All others (page faults, memory...) were similar. I found that when I ran through my program without the printf (or write) my total execution speed (as measured in my own pc) seemed to be similar.
The competition evaluates the output by redirecting the output (with a pipe, i suppose) into a file & matching its MD5 with theirs....
My question is, Is there by any means something in C, that doesn't write to the output stream but still the pipe gets its input. Or perhaps I am even framing the question wrong. But either way, I am in a fix.
I have been beating my head off with optimizing the algorithm. BTW they accept makefile where many have tried to optimize. For me neither of the optimization flags have worked. I don't know what else can be done about that too...
If you need to make a program that writes its output to a file, you just need to:
open the file with int fd = fopen("/file/path", O_WRONLY); (you may need to check the parameters, it's been a long time since I've done C programming) and then write(fd, ...); or fprintf(fd, ...);
open the file with fopen, close the standard output and use dup2() to duplicate the file descriptor to the file descriptor number 1 (i.e. standard output).
You may try fprintf on the pipe fd.
I need to write a very basic command interpreter on a micro controller that will communicate over a virtual serial port. Before I go ahead and write my own version of this, I was wondering if anyone knew of any libraries for very simple, shell-like text processing. I'd like the features that are standard in a shell, such as text received only being available after the user types in a new line, pressing backspace removes the last character in the queue rather than adding another char in the queue, stuff like that.
Any ideas?
Thanks
to achieve a truly simple "shell" with line buffering (line buffering means processing only after an "enter" or '\n') in a microcontroller, i would do something like this (in the middle of the main loop:
char * p = my_read_buffer; //this is in the initialization, rather than the main loop
if (byte_from_my_uart_avaliable()) {
*p = read_uart_byte();
if (*p == '\n') {
process_input(my_read_buffer);
p = my_read_buffer; //reset the linebuffer
}
else
p++;
}
The secret then, would be the process_input() function, where you would parse the commands and its parameters, so you could call the appropriate functions to handle them.
This is just an idea far from finished, you would need to put a limit to the number of chars received before a '\n' to prevent overflow.
Try looking for a Forth interpreter. This is a large ecosystem, and you'll find many implementations that are intended to be used in firmware, such as Open Firmware¹ implementations OpenBIOS. For example Open Firmware² is BSD-licensed and includes code for terminal access, which you may be able to reuse. I don't know how portable the Open Firmware code is, but if it doesn't suit you, I suggest searching for other Forth systems meeting your portability and licensing requirements and having a terminal access component.
¹ the specification
² the program
Check out ECMD, which is a part of the Ethersex platform.
ECMD Reference.
For a programming assignment, we have the following requirements:
It needs to be a command-line program written in C.
It needs to read text from a text document. However, we are to do this by using the Unix redirection operator < when running the program rather than having the program load the file itself. (So the program reads the text by pretending it's reading from stdin.)
After reading the data from the file, the program is to poll the user for some extra information before doing its job.
After much research, I can't find a way to retrieve the "old" stdin in order to accomplish part (3). Does anybody know how or if this is even possible?
Technically part (3) is part of a bonus section, which the instructor probably didn't implement himself (it's very lengthy), so it's possible that this is not possible and it's an oversight on his part. However, I certainly don't want to jump to this conclusion.
On linux, i would open the controlling terminal /dev/tty.
Which OS? On Linux the usual trick to accomplish this is to check if stderr is still connected to a tty:
if (isatty(2))
and if so, open a new reading file descriptor to that terminal:
new_stdin = open("/proc/self/fd/2", O_RDONLY);
then duplicate the new file descriptor to stdin (which closes the old stdin):
dup2(new_stdin, 0);
(If stderr has also been redirected, then isatty(2) will return false and you'll have to give up.)
If you run the program like this:
myprog 3<&0 < filename
then you get file descriptor 3 set up for you as a duplicate of stdin. I don't know if this meets the requirements of your assignment, but it might be worth an experiment.