I'm working on a ctf challenge. This is the relevant code section,
void details(){
char name[100];
printf("Please enter your name: ");
scanf("%100s", name);
printf("Hello %s!\n", name);
}
If I EOF scanf/stdin, printf will output arbitrary data, which I
hope to put to some use but it's indiscernable hex data in bash.
I tried piping the output to hexdump or od -t x1, redirect to a
file but whatever I'm trying the shell output doesn't match what
I'm seeing in gdb, e.g. 0xf7facce0 0xf7e7b6e3 etc etc.
output/bash
Any pointers?
Thanks.
Ok, I'll eloborate, bear with me the interface here is still somewhat of a challenge all by itself.
I was trying to keep my question generic to avoid running into any spoilers.
There's are other attack vectors I'm looking at, this is just one of the them.
And I know I can overflow the buffer but that will only get halfway where I
need to go.
void welcome(){
char name[100];
printf("enter you name : ");
scanf("%100s", name);
printf("Welcome %s!\n", name);
}
int main(){
printf("Toddler's Secure Login System 1.0 beta.\n");
welcome();
login();
// something after login...
printf("Now I can safely trust you that you have credential :)\n");
return 0;
}
In gdb it looks something like this,
gdb
At the top you can see the printf output when I quit scanf with Ctrl-D, "Welcome &%%/%/&", obviously it's non readable in this format. In the disassembly the buffer is at $ebp-0x70, 0xffffd068 and following. As you can see there's a few words before the first 0 byte and I was hoping to be able to make these available
in bash. Now, if I pipe the program's output to od to convert to hex, all I get to see is printable ASCII codes in hex, where did the non-printable characters go?
pipe to od -t x1
The real function of interest in this challenge is login(). To give you a hint on this challenge without spoiling it for you: remember that even when the welcome() function ends and the stack is cleared, those values can still remain in those memory locations. Look at the scanf() function in login() instead.
Related
I want to get date of birth in one line:
#include <stdio.h>
int main()
{
int BirthYear,BirthMonth,BirthDay;
printf("Please enter your birth date: ");
scanf("%d",&BirthYear);
printf("/");
scanf("%d",&BirthMonth);
printf("/");
scanf("%d",&BirthDay);
return 0;
}
This is my output:
Please enter your birth date: YYYY
/MM
/DD
But I want to get something like this:
Please enter your birth date: YYYY/MM/DD
In output, it goes to next line after each scanf() without using \n.
I use VS Code for IDM.
Here is a workaround using ansi control characters. I would not do like this, but just to show that it is possible:
#define PREVLINE "\033[F"
#define MSG "Please enter your birth date: "
int main(void) {
int BirthYear,BirthMonth,BirthDay;
printf(MSG);
scanf("%d",&BirthYear);
printf(PREVLINE MSG "%d/", BirthYear);
scanf("%d",&BirthMonth);
printf(PREVLINE MSG "%d/%d/", BirthYear, BirthMonth);
scanf("%d",&BirthDay);
printf("You entered: %d/%d/%d\n", BirthYear, BirthMonth, BirthDay);
}
Please note that this is not portable. The terminal needs to support this in order to work. AFAIK there's no 100% portable way to achieve this.
If you want to do this stuff for real, then I recommend taking a look at the ncurses library
Note:
Always check the return value for scanf to detect errors.
Note2:
It may be a good idea to add fflush(stdout); after each printf statement.
I actually wrote another answer today about ascii control characters. It might be interesting: https://stackoverflow.com/a/64549313/6699433
You can explicitly specify that the three input numbers should be separated by a '/' character by adding that character in the format specifier for the scanf function.
Then, you can ensure that the user gave valid input by checking the value returned by scanf (which will be the number of items successfully scanned and assigned); if that value is not 3, then you will (probably) need to clear any 'leftover' characters in the input buffer, using a getchar() loop until a newline (or end-of-file) is found:
#include <stdio.h>
int main()
{
int BirthYear, BirthMonth, BirthDay;
int nIns = 0, ch;
while (nIns != 3) {
printf("Enter D.O.B. (as YYYY/MM/DD): ");
nIns = scanf("%d/%d/%d", &BirthYear, &BirthMonth, &BirthDay);
while ((ch = getchar() != '\n') && (ch != EOF))
; // Clear remaining in-buffer on error
}
printf("Entered data were: %d %d %d!\n", BirthYear, BirthMonth, BirthDay);
return 0;
}
Expanding on my comment...
The problem you're running into is that you have to hit Enter for each input, which writes a newline to the terminal screen. You can't avoid that.
And unfortunately, you can't overwrite the newline on the screen with a '\b'; you can only backspace up to the beginning of the current line, not to a previous line.
You basically can't do what you want with vanilla C - the language only sees byte streams, it has no concept of a "screen".
There are some terminal control sequences you can play with to reposition the cursor after sending the newline; I don't know how well those will work for you.
Beyond that, you'll need to use a library like ncurses.
#include <stdio.h>
int main()
{
int BirthYear,BirthMonth,BirthDay;
printf("Please enter your birth date: ");
scanf("%d/%d/%d",&BirthYear,&BirthMonth,&BirthDay);
return 0;
}
You can take multiple values from scanf which are then separated by any text you like (in this case /s).
You could use fflush(3) (in particular before all calls to scanf(3)) like in
printf("Please enter your birth date: ");
fflush(NULL);
but you should read this C reference website, a good book about C programming such as Modern C, and the documentation of your C compiler (perhaps GCC) and debugger (perhaps GDB).
Consider enabling all warnings and debug info in your compiler. With gcc that means compiling with gcc -Wall -Wextra -g
Be aware that scanf(3) can fail.
Your code and problem is surely operating system specific.
On Linux consider using ncurses (for a terminal interface) or GTK (for a graphical interface). Read also the tty demystified, then Advanced Linux Programming and syscalls(2) and termios(3).
You might also consider using ANSI escape codes, but be aware that in 2020 UTF-8 should be used everywhere.
For some reason, scanf isn't working properly after using c redirection to pass input to stdin.
I've tested the same code with no c redirection and it works perfectly fine.
Also, I've tried flushing stdin before doing scanf operations with fflush(stdin) and that also did not work.
Running my executable like
./3240Assignment0 < test-input.txt
The code for running the scanf operation looks as follows
int main(int argc, char** argv){
fflush(stdin);
char input[100];
char *output = "Thank you for your message!";
puts("Tell me something nice:");
scanf("%s", input);
printf("%s\n\n", output);
}
The problem is the terminal doesn't give me the opportunity to enter
any information or input.
Script of my terminal
Joes-MacBook-Pro:a0 joemanto$ make test
./3240Assignment0 < test-input.txt
Tell me something nice:
Thank you for your message!
Joes-MacBook-Pro:a0 joemanto$
It accepts input, it just accepts input from the file you've told it to accept input from.
You have three options with STDIN:
assignment: Interactive input
assignment < input.txt: Take input from file
command | assignment: Take input from the result of command command (pipe)
Since you're using the second form you can't take interactive input as well. It's one input source and one only.
My program is supposed to let the user edit a line of a file. The user edits the line and sends it back by pressing enter. Therefore I would like to print the current line which is about to be edited, but kind of print it on stdin instead of stdout.
The only problem I don't know how to solve is how I can prefill the stdin. I've already tried this:
char cprefill[] = {"You may edit this line"};
char cbuffer[100];
fprintf(stdin, cprefill);
fgets(cbuffer, 100, stdin);
This seems to be the simplest solution, but is probably too simple to work. The fprintf doesn't print anything to stdin. What is the correct way?
Edit:
This is how it is supposed to look like. Please mind the cursor which can be moved.
The C language has no notion of terminal nor of line edition, so it cannot be done in a portable way. You can either rely on a library like [n]curses to get an almost portable solution, or if you only need that on one single OS use low level OS primitives.
For exemple on Windows, you could feed the input buffer by simulating key strokes into the appropriate window (for example by sending WM_CHAR messages) just before reading, but that would be highly non portable - and in the end is no longer a C but a Windows solution...
First you need the libreadline developer package. (You might also need the libreadline if it's not already available on your system)
On Debian / Ubuntu that's apt install libreadline-dev (plus libreadline6 if you need the binaries also - 6 might be different on your platform)
Then you can add an history to readline, like this
#include <stdio.h>
#include <readline/readline.h>
#include <readline/history.h>
...
char cprefill[] = {"You may edit this line"};
add_history(cprefill);
char *buf = readline("Line: ");
printf("Edited line is %s\n", buf);
// free the line allocated by readline
free(buf);
User is prompted "Line: ", and has to do UP ARROW to get and edit the history, i.e. the cprefill line.
Note that you have to compile/link with -lreadline
readline prints the prompt given as argument, then waits for user interaction, allowing line edition, and arrows to load lines stored in the history.
The char * returned by readline has then to be freed (since that function allocates a buffer with malloc()).
You could use GNU Readline. It calls the function that rl_startup_hook points to when starting, where we use rl_insert_text to put our text in the line buffer.
#include <stdio.h>
#include <stdlib.h>
#include <readline/readline.h>
int prefill(void)
{
rl_insert_text("You may edit this line");
return 0;
}
int main(void)
{
char *cbuffer;
puts("Please edit the following line");
rl_startup_hook = prefill;
if ((cbuffer = readline(NULL)) == NULL) /* if the user sends EOF, readline will return NULL */
return 1;
printf("You entered: %s\n", cbuffer);
free(cbuffer);
return 0;
}
For more information, see the GNU Readline manual.
I have the following C program:
#include<stdio.h>
main()
{
char buf[64];
gets(buf);
printf("Your input: %s\n", buf);
gets(buf);
printf("Your input: %s\n", buf);
}
I want to send data to the program using pipes or redirection. The problem is that the program don't wait for the second gets to enter new data.
e.g
$ echo "a" | ./test
Output:
Your input: a
Your input: a
How can I send let the program wait for the user input at each gets using pipes or redirection.
P.S I don't have persmission to write to /proc/$pid/fd/0 and I don't have to change the code.
Any help would be appreciated.
If you use pipes | to input data to a command, it is disconnected from the (input portion) of your terminal. gets reads the first line "a\n" and writes this to the buf as "a\0". Then it hits the end of the pipe, or EOF (end of file).
Your second gets then does nothing (as there is nothing to read after EOF) and lets buf alone; buf still contains "a\0", which is duly printed.
Further hints:
When doing I/O, which can inherently fail at any time, you have to check for errors after each and every call, or bad things will happen. Train yourself to do this and save lots of debugging time.
Never do an I/O like gets(buf) because it will lead to buffer overflows, the bane of computing security. If you input arbitrary data, you must use a call that lets you limit the number of bytes written. The man page for gets contains the sentence "Never use this function" right at the top. You can find other, better functions, read being a baseline, and if you are in C++ there will be plenty of other standard solutions for that.
Hi I'm trying some C coding on Eclipse, and I had a problem:
I am trying to print some text, however, while awaiting input from the user, the text actually fails to appear until AFTER the user has input.
Here is an example of what I mean:
TEST
#include <stdio.h>
#include <stdlib.h>
int main(void){
char c[5];
printf("test\n"); //PRINTING 'test' BEFORE i have to enter code
fgets(c, 5, stdin);
printf("You entered: %s\n", c);
return 0;
}
OUTPUT:
dog (this is what i typed)
test
You entered: dog
Rather than appearing BEFORE I am prompted to enter code, the "test" printf only appears AFTER I have entered the code.
Probably this text to print is still waiting in the buffer (that's an optimization, to group data to write to make it more efficient). To make sure everything from buffer gets out to the console you should flush it like this
fflush(stdout);
or you can use a function that does not use buffering like (on linux)
write()