c++ BOF vulnerability in this code please some one explain - c++

what is the vulnerabilty in this code please some one explain me
#include <stdio.h>
#include <string.h>
int main(int arc, char* argv[])
{
char buff[50];
strcpy(buffer, argv[1]);
printf("You are string: %s", buff);
return 0;
}

argv[1] may not exist, or it could be longer than 50 chars => problem.
Solution: Check if argc >=2 and strlen(argv[1])<50
Otherwise, your program has undefined behaviour,
means it can do something strange and unexpected.
Additionally, malicious humans maybe can inject own code

Related

Float variable to hex C++ arduino

I encountered an issue while having fun with Arduino. I am currently using the first version of Arduino IDE (v 1.18.49.0).
Problem is that I can't figure out how to convert float value to hex. I am trying to use various solutions that occurred earlier on StackOverflow, but none of them seemed to work for me. My best attempt is:
char data[9];
float a = 3.141592654;
sprintf(data, "%x", *(unsigned int*)&a);
Serial.println(data);
Expected Result: 40490fdb
Actual Result: fdb
What's surprising using the same code, yet slightly modified, compiled by g++ gives the expected result.
#include <stdio.h>
int main(int argc, char** argv)
{
char data[9];
float a = 3.141592654;
sprintf(data, "%x", *(unsigned int*)&a);
printf(data);
return 0;
}
Why do the results differ? Maybe there is a better way to do that?
Thanks in advance!
If you are sure you want to see the bit pattern of a 4 byte variable, you should prefer a conversion like this:
sprintf(data, "%08lx", *(uint32_t*)&a);
(Here it's irrelevant, but in general, leading zeros help readability)
[edited to include #timemage's hint]

fopen returning NULL in gdb

Im trying to solve a binary exploitation problem from picoCTF, but I'm having trouble with gdb.
Here is the source code of the problem (I've commented some stuff to help me).
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <sys/types.h>
#include <wchar.h>
#include <locale.h>
#define BUF_SIZE 32
#define FLAG_LEN 64
#define KEY_LEN 4
void display_flag() {
char buf[FLAG_LEN];
FILE *f = fopen("flag.txt","r");
if (f == NULL) {
printf("'flag.txt' missing in the current directory!\n");
exit(0);
}
fgets(buf,FLAG_LEN,f);
puts(buf);
fflush(stdout);
}
// loads value into key, global variables ie not on stack
char key[KEY_LEN];
void read_canary() {
FILE *f = fopen("/problems/canary_3_257a2a2061c96a7fb8326dbbc04d0328/canary.txt","r");
if (f == NULL) {
printf("[ERROR]: Trying to Read Canary\n");
exit(0);
}
fread(key,sizeof(char),KEY_LEN,f);
fclose(f);
}
void vuln(){
char canary[KEY_LEN];
char buf[BUF_SIZE];
char user_len[BUF_SIZE];
int count;
int x = 0;
memcpy(canary,key,KEY_LEN); // copies "key" to canary, an array on the stack
printf("Please enter the length of the entry:\n> ");
while (x<BUF_SIZE) {
read(0,user_len+x,1);
if (user_len[x]=='\n') break;
x++;
}
sscanf(user_len,"%d",&count); // gives count the value of the len of user_len
printf("Input> ");
read(0,buf,count); // reads count bytes to buf from stdin
// compares canary (variable on stack) to key
// if overwriting need to get the value of key and maintain it, i assume its constant
if (memcmp(canary,key,KEY_LEN)) {
printf("*** Stack Smashing Detected *** : Canary Value Corrupt!\n");
exit(-1);
}
printf("Ok... Now Where's the Flag?\n");
fflush(stdout);
}
int main(int argc, char **argv){
setvbuf(stdout, NULL, _IONBF, 0);
int i;
gid_t gid = getegid();
setresgid(gid, gid, gid);
read_canary();
vuln();
return 0;
}
When I run this normally, with ./vuln, I get normal execution. But when I open it in gdb with gdb ./vuln and then run it with run, I get the [ERROR]: Trying to Read Canary message. Is this something that is intended to make the problem challenging? I don't want the solution, I just don't know if this is intended behaviour or a bug. Thanks
I don't want the solution, I just don't know if this is intended behaviour or a bug.
I am not sure whether you'll consider it intended behavior, but it's definitely not a bug.
Your ./vuln is a set-gid program. As such, it runs as group canary_3 when run outside of GDB, but as your group when run under GDB (for obvious security reason).
We can assume that the canary_3 group has read permissions on the canary.txt, but you don't.
P.S. If you printed strerror(errno) (as comments suggested), the resulting Permission denied. should have made the failure obvious.

I can not overflow buffer

I have seen a buffer overflow code but I can not over flow it. Is there any gcc option to compile that? Or any wrong with that code.
The code is:
#include <stdlib.h>
#include <unistd.h>
#include <stdio.h>
#include <string.h>
int main(int argc, char **argv)
{
volatile int modified;
char buffer[64];
if(argc == 1) {
errx(1, "please specify an argument\n");
}
modified = 0;
strcpy(buffer, argv[1]);
if(modified == 0x61626364) {
printf("you have correctly got the variable to the right value\n");
} else {
printf("Try again, you got 0x%08x\n", modified);
}
}
and I am trying to run it this way:
perl -e 'print "A"x64 . "dcba"' | xargs ./main
You need to know
Know the stack memory layout and the address difference between the variable modified and buffer
You can solve it by finding the offset between modified and buffer as (char *)&modified - (char *)buffer
Your machine endianess. I have used the stack overflow answer for this purpose
The linked demonstrates how to run the modified code that serves the purpose of determining the correct argument as well as stack smashing. The first Demo provides you with the argument that you can feed to your second Demo

Invalid conversion from char to const char*

Sorry in advance for what I feel is going to be a really simple problem, but I've been stuck on it for hours and I haven't been able to work out how to fix it based on the stuff I've found here or on google.
I've got an arduino hooked up to a GPS and a radio and am trying to broadcast the GPS signal to my radio. What I am trying to do now is get the NMEA sentence from the GPS into the variable 'text', but am getting confused by this error, which I think is due to arrays.
My error is occurring on this line:
sprintf(text, char(c));
I've tried a few different things but this is where I'm stuck at the moment. Any help would be really appreciated.
#define RADIOPIN 13
#include <string.h>
#include <util/crc16.h>
#include <Adafruit_GPS.h>
#include <SoftwareSerial.h>
SoftwareSerial mySerial(3, 2);
#define GPSECHO true
Adafruit_GPS GPS(&mySerial);
char datastring[80];
char text[80];
void setup() {
Serial.begin(115200);
GPS.begin(9600);
GPS.sendCommand(PMTK_SET_NMEA_OUTPUT_RMCGGA);
GPS.sendCommand(PMTK_SET_NMEA_UPDATE_5HZ);
delay(3000);
pinMode(RADIOPIN,OUTPUT);
}
void loop(){
gpscheck();
}
void gpscheck(){
char c = GPS.read();
if (c) {
// Serial.print(c);
sprintf(text, char*(c));
Serial.print(text);
}
}
You might want to read a reference of sprintf. Then you will see that the second argument is a string.
So the following would be fine:
sprintf(text, "%c", c);
To be on the safe side, you might want to use snprintf instead, to lessesn the risk of buffer overflows.
Of course, for a single character, you might as well do e.g.
text[0] = c;
text[1] = '\0'; /* Terminate string */
sprintf(text, char*(c));
If you want to print character
simply use printf("%c",c);
if you want to copy that into text
sprintf(text,"%c", c);

How to get unsigned int as console argument?

I'm trying to pass an unsigned int value via console argument to my program.
what have I tried yet:
first: check if argc is 2, otherwise error
if there is a second value I tried to convert this value with:
strtoul(argv[1], NULL, 0)
So when I pass "100", i get "1"
What am I doing wrong?
br
Sagi
€: passed a wrong argument to my function, found the mistake, thanks guys
It's a little hard to tell without seeing the actual code but you can use this as a baseline:
#include <stdio.h>
#include <stdlib.h>
int main (int argc, char *argv[]) {
char *pCh;
unsigned long unlong = 42;
// Check enough arguments.
if (argc != 2) {
puts ("Not enough arguments");
return 1;
}
// Convert to ulong WITH CHECKING!
unlong = strtoul (argv[1], &pCh, 10);
// Ensure argument was okay.
if ((pCh == argv[1]) || (*pCh != '\0')) {
puts ("Invalid number");
return 1;
}
// Output converted argument and exit.
printf ("Argument was %ld\n", unlong);
return 0;
}
Transcript follows:
pax> ./testprog 314159
Argument was 314159
If that's not enough to help out, I suggest you post the shortest complete program that exhibits the problem, then we can tell you in excruciating detail what's wrong with it :-)
Your method should work. Alternatively, you can use stringstream:
std::string str(argv[1]);
unsigned long ul;
std::stringstream(str)>>ul;