I am currently working on the common return to stack project and I have seen many of example online and on youtube that are very common. Yet when I try to recreate the project with the int2hexstr() function my results are not the same.
Example of test string arugment
As you can see 76 A's print to the screen along with 100 I's and 4 B's along with the shellcode.
However when I replace the BBBB with int2hextr(), My argument is simply exactly what I typed in the single quotation marks.
Example of test string argument with address
I am aware that my results do not print in hexadecimal like most examples in either picture but will that make a difference, as well.
Is there an alternative to use instead of int2hexstr or is there something else I need to type. Also I using a virtual machine, Debian 7.xxx
copy of code i am trying to use return 2 stack
char* dovuln(coonst char*s)
{ char buf[64];
strcpy(buf, s);
puts(buf);
fflush(stdout);
return strdup(buf);
}
int main(int argc, char **argv)
{
if (argc < 2)
{
puts("missing argument");
exit(1);
}
dovuln(argv[1]);
return 0;
}
Related
I have a CTF challenge in which i've got a simple code vulnerable to buffer over flow (via strcpy) which looks like:
#include <stdio.h>
#include <string.h>
int display(char *text)
{
char buffer[20];
strcpy(buffer, texte);
printf("%s\n",buffer);
}
int main(int argc, char ** argv)
{
char forbidden[]={0x00, 0x80, 0x89, 0xe1, 0x89};
int i,j;
if (argc!=2)
{
printf("Usage: %s <text>\n", argv[0]);
return 1;
}
for(i=0;argv[1][i];i++)
{
for(j=0;forbidden[j];j++)
{
if(argv[1][i] == forbidden[j])
{
printf("Shellcode detected!\n");
return 1;
}
}
}
display(argv[1]);
return 0;
}
I managed to debug via GDB and see the addresses and instructions, I took full control of the memory, so I managed to corrupt the memory and inject my own shellcode, and change the return address to that block which runs my code.
But what bothers me, is the code check forbidden characters that I need to use to execute a \bin\cat, which really relies on 0x80 (OpCode of system call), i used shellcode generator such as masterccc.github. But it nevers provide me a shellcode without those forbidden characters, i tried as well an encoder (change shellcode instructions but have the same semantic) but no way.
I just want to know if i am in right path, and i have to execute shellcode and bypass this verification, or it's wrong path ? give me some Hint please.
I'm working on x86 32-bit.
There are other ways to get a shell ;)
You should probably check what is a ROP chain
If you still want to use a shellcode (and this is probably the easiest way), you could also inject it in an env variable instead of the argv[1] and use
jmp ADDRESS_OF_THE_SHELLCODE_IN_ENV
in argv[1]. It won't trigger the forbidden characters.
Have fun with the CTF!
I am writing an interactive REPL program in c.
Some examples of commands (lines starting with >) I would like to handle are:
$ ./my_program // run the program
> add user
id: 123 // this is the output of above command
> update user 123 name "somename"
> remove user 123
> quit
So basically the command is a line with multiple strings.
This is how I am trying to handle the commands.
scan the whole line
parse the command and get a corresponding int value unique to command
do whatever needs to be done for the command
#include <stdio.h>
int parse_cmd(const char *buffer)
{
// parse command
}
int main(int argc, const char **argv)
{
// init code
char buffer[100];
int cmd;
while (1) {
printf("> ");
scanf("%[^\n]%*c", buffer);
cmd = parse_cmd(buffer);
if (cmd < 0) {
printf("error: invalid command\n");
continue;
}
switch (cmd) {
// handle commands
}
}
// deinit code
}
There are a lot of cli programs I have seen that take command inputs in similar way.
I wonder if there is a general way of writing cli programs?
I can write code to parse the commands, just wanted to know the standard approach for such situations?
While there's no real standard way, quite a lot of opensource console tools with an interactive mode use the GNU readline library (https://tiswww.case.edu/php/chet/readline/rltop.html).
It's actually quite easy to use, even simpler than implementing everything 100% correctly by yourself.
Your example rebased on readline:
int main(int argc, const char **argv)
{
// init code
int cmd;
char* line;
while (1) {
line = readline("> ");
if (line) {
cmd = parse_cmd(line);
switch (cmd) {
// handle commands
default:
printf("error: invalid command\n");
}
free(line);
} else {
break;
}
}
// deinit code
}
This isn't any more complex than your example, but you immediately gain:
command line editing at the interactive prompt, with correct handling of each and every possible terminal
correct handling of EOF (important if stdin is redirected)
unlimited input line size
And it's not very hard to add a command history, with arrow-up and down to repeat previous lines, incremental search, optionally persisted to a file, et et.
There's not really a standard way to do it. This is not a 100% fair comparison, but your question is kind of like if there is a standard way to construct a compiler, because you are in fact constructing a language, although a very simple one.
But one reasonably common way that works fairly well for simple programs is this approach. Let's assume that we have two commands add and del. Create a function for both these commands. First we search for one of the strings "add " or "del ". Notice the spaces. Put a pointer on the next character and call the corresponding function with the rest of the line as argument and allow them to determine things.
Here is some pseudo:
parse(bufferptr)
word = getFirstWord(bufferptr)
ptr = bufferptr + strlen(word)
if word == "add"
return add(ptr)
else if word == "del"
return del(ptr)
return -1
add(bufferptr)
word = getFirstWord(bufferptr)
if userExist(word)
return -1
else
return addUser(word)
del(bufferptr)
word = getFirstWord(bufferptr)
if not userExist(word)
return -1
else
return delUser(word)
buffer = input()
int res = parse(buffer)
Okay so overall im trying to complete a basic CLI C program which will complete functions such as clear, quit, cd, ls, help (bring up the unix man) etc.. i altered my code and so far i have this, im getting segmination error when trying to execute the cd command part of the program, (im very new to c btw);
#include<stdio.h>
#include<stdlib.h>
#include<string.h>
#include<unistd.h>
int main (int argc, char *argv[])
{
char input[] = " ";
char *argument;
while(strcmp(input, "quit")!= 0)
{
printf("$");
scanf ("%s", input);
if(strcmp(input,"clear") == 0)
{
printf("\e[1;1H\e[2J");
}
else if(strcmp(argv[1],"cd") == 0)
{
if(chdir(argv[2]) == -1)
{
printf("\n directory does not exists");
}
}
else if(strcmp(input, "echo") == 0)
{
char str[50];
scanf("%[^\n]+", str);
printf(" %s", str);
}
}
}
input is declared as a ' ' (space) character. It will never match 'cd'.
This is probably more along the lines of what you want to achieve, where the first parameter is the command (cd), and the second will be the directory:
int main (int argc, char *argv[])
{
char *argument;
if(strcmp(argv[1],"cd") == 0)
{
if(chdir(argv[2]) == -1)
{
printf("\n directory does not exists");
}
}
Edit Also please note that there is no need for the else satement. If chdir does not return an error, it will change the directory, thus no need to call it again in an else.
Additionally, another tip for using system calls in general, it would be of great help if you print the error number returned by the system upon a failure in system call. This will make things easier when things start going wrong. To do this simply include <errno.h>' and modify the printf to printerrno` which gives specific details about the error:
printf("Chdir error: %d", errno);
For instance chdir() does not only return an error when the directory does not exist, but also for example if you do not have permissions to view the contents of the directory. See the man page for a list of possible errors.
To implement your own shell, you need to take input directly from stdin, not from command-line arguments (argv) from another shell. The basic pattern is like this:
Read input
Execute command
Print results
Loop back to step 1
I am building a Linux Shell, and my current headache is passing command line arguments to forked/exec'ed programs and system functions.
Currently all input is tokenized on spaces and new lines, in a global variable char * parsed_arguments. For example, the input dir /usa/folderb would be tokenized as:
parsed_arguments[0] = dir
parsed_arguments[1] = /usa/folderb
parsed_arguments tokenizes everything perfectly; My issue now is that i wish to only take a subset of parsed_arguments, which excludes the command/ first argument/path to executable to run in the shell, and store them in a new array, called passed_arguments.
so in the previous example dir /usa/folderb
parsed_arguments[0] = dir
parsed_arguments[1] = /usa/folderb
passed_arguments[0] = /usa/folderb
passed_arguments[1] = etc....
Currently I am not having any luck with this so I'm hoping someone could help me with this. Here is some code of what I have working so far:
How I'm trying to copy arguments:
void command_Line()
{
int i = 1;
for(i;parsed_arguments[i]!=NULL;i++)
printf("%s",parsed_arguments[i]);
}
Function to read commands:
void readCommand(char newcommand[]){
printf("readCommand: %s\n", newcommand);
//parsed_arguments = (char* malloc(MAX_ARGS));
// strcpy(newcommand,inputstring);
parsed = parsed_arguments;
*parsed++ = strtok(newcommand,SEPARATORS); // tokenize input
while ((*parsed++ = strtok(NULL,SEPARATORS)))
//printf("test1\n"); // last entry will be NULL
//passed_arguments=parsed_arguments[1];
if(parsed[0]){
char *initial_command =parsed[0];
parsed= parsed_arguments;
while (*parsed) fprintf(stdout,"%s\n ",*parsed++);
// free (parsed);
// free(parsed_arguments);
}//end of if
command_Line();
}//end of ReadCommand
Forking function:
else if(strstr(parsed_arguments[0],"./")!=NULL)
{
int pid;
switch(pid=fork()){
case -1:
printf("Fork error, aborting\n");
abort();
case 0:
execv(parsed_arguments[0],passed_arguments);
}
}
This is what my shell currently outputs. The first time I run it, it outputs something close to what I want, but every subsequent call breaks the program. In addition, each additional call appends the parsed arguments to the output.
This is what the original shell produces. Again it's close to what I want, but not quite. I want to omit the command (i.e. "./testline").
Your testline program is a sensible one to have in your toolbox; I have a similar program that I call al (for Argument List) that prints its arguments, one per line. It doesn't print argv[0] though (I know it is called al). You can easily arrange for your testline to skip argv[0] too. Note that Unix convention is that argv[0] is the name of the program; you should not try to change that (you'll be fighting against the entire system).
#include <stdio.h>
int main(int argc, char **argv)
{
while (*++argv != 0)
puts(*argv);
return 0;
}
Your function command_line() is also reasonable except that it relies unnecessarily on global variables. Think of global variables as a nasty smell (H2S, for example); avoid them when you can. It should be more like:
void command_Line(char *argv[])
{
for (int i = 1; argv[i] != NULL; i++)
printf("<<%s>>\n", argv[i]);
}
If you're stuck with C89, you'll need to declare int i; outside the loop and use just for (i = 1; ...) in the loop control. Note that the printing here separates each argument on a line on its own, and encloses it in marker characters (<< and >> — change to suit your whims and prejudices). It would be fine to skip the newline in the loop (maybe use a space instead), and then add a newline after the loop (putchar('\n');). This makes a better, more nearly general purpose debug routine. (When I write a 'dump' function, I usually use void dump_argv(FILE *fp, const char *tag, char *argv[]) so that I can print to standard error or standard output, and include a tag string to identify where the dump is written.)
Unfortunately, given the fragmentary nature of your readCommand() function, it is not possible to coherently critique it. The commented out lines are enough to elicit concern, but without the actual code you're running, we can't guess what problems or mistakes you're making. As shown, it is equivalent to:
void readCommand(char newcommand[])
{
printf("readCommand: %s\n", newcommand);
parsed = parsed_arguments;
*parsed++ = strtok(newcommand, SEPARATORS);
while ((*parsed++ = strtok(NULL, SEPARATORS)) != 0)
{
if (parsed[0])
{
char *initial_command = parsed[0];
parsed = parsed_arguments;
while (*parsed)
fprintf(stdout, "%s\n ", *parsed++);
}
}
command_Line();
}
The variables parsed and parsed_arguments are both globals and the variable initial_command is set but not used (aka 'pointless'). The if (parsed[0]) test is not safe; you incremented the pointer in the previous line, so it is pointing at indeterminate memory.
Superficially, judging from the screen shots, you are not resetting the parsed_arguments[] and/or passed_arguments[] arrays correctly on the second use; it might be an index that is not being set to zero. Without knowing how the data is allocated, it is hard to know what you might be doing wrong.
I recommend closing this question, going back to your system and producing a minimal SSCCE. It should be under about 100 lines; it need not do the execv() (or fork()), but should print the commands to be executed using a variant of the command_Line() function above. If this answer prevents you deleting (closing) this question, then edit it with your SSCCE code, and notify me with a comment to this answer so I get to see you've done that.
When I compile this using GCC on linux, as I am waiting for input, the "hi" shows up. I do not want to use scanf, and want to know why the hi is showing while I am asking the user to input the name. Also when I want to printout the name of the file that was just passed, I get garbage characters. In netbeans, i get what I want. but on linux, it decides to act weirdly. please help
Code:
int main(int argc, char** argv)
{
char val[70];
if(write(1, "Please input your name", 36)!=36)
{
return -1;
}
if(read(0, val, 36) < 0)
{}
if(write(1, val, 36)!=36)
{}
printf("Yo");//THIS IS PRINTING OUT WAY BEFORE IT IS CALLED, ANY VARIABLE WITH A STRING GETS PRINTED OUT, EVEN WITHOUT PRINTF BEING INVOKED
}
output:
Please input the file nameYo: hi
hi
???Om?0?a?Sm? <<WHAT IS THIS? I DONT GET THIS ON NETBEANS
The third argument to write is the byte length of the string you're trying to print. You have 36, but the string you provide is only 22 bytes long. Changing the code to look like the following will behave as you expected it to:
int main(int argc, char** argv)
{
char val[70];
if(write(1, "Please input your name", 22)!=22)
{
return -1;
}
if(read(0, val, 36) < 0)
{}
if(write(1, val, 36)!=36)
{}
printf("Yo");//THIS IS PRINTING OUT WAY BEFORE IT IS CALLED, ANY VARIABLE WITH A STRING GETS PRINTED OUT, EVEN WITHOUT PRINTF BEING INVOKED
}
Note that you should probably look into using printf and scanf so that you wont have to worry about byte lengths so much.
That might look like this:
#include <stdio.h>
int main(int argc, char** argv)
{
char val[70];
printf("Please input your name");
if(scanf("%69s", &val) == 1)
printf(val);
printf("Yo");
}