Integer overflow not overflowing? - c

I'm doing the ctf challenge from 247CTF "impossible numbers".
The challenge is about integer overflow, and consists of the following file:
#include <stdio.h>
int main() {
int impossible_number;
FILE *flag;
char c;
if (scanf("%d", &impossible_number)) {
if (impossible_number > 0 && impossible_number > (impossible_number + 1)) {
flag = fopen("flag.txt","r");
while((c = getc(flag)) != EOF) {
printf("%c",c);
}
}
}
return 0;
}
You can try the challenge at:
$ nc 1765a1cbe1629dfc.247ctf.com 50458
It's pretty simple, you need to trigger this case:
if (impossible_number > 0 && impossible_number > (impossible_number + 1))
Which you do by inputting 2147483647, which then overflows in the line impossible_number + 1.
This works for me, but I have also tried running it locally in vs code, and here the if statement is not triggered.
After doing some debugging, I have concluded that this is the proporsition that fails:
impossible_number > (impossible_number + 1)
This is really weird to me, I have even tried adding some prints of the values:
#include <stdio.h>
int main() {
int impossible_number;
FILE *flag;
char c;
if (scanf("%d", &impossible_number)) {
printf("impossible nr: %d \n", impossible_number);
printf("plus one nr: %d \n",impossible_number + 1 );
if (impossible_number > 0 && impossible_number > (impossible_number + 1)) {
flag = fopen("flag.txt","r");
while((c = getc(flag)) != EOF) {
printf("%c",c);
}
}
}
return 0;
}
which prints this:
impossible nr: 2147483647
plus one nr: -2147483648
This makes no sense to me, why does this work on the 247CTF server, but not when I run it?

As has been noted in the comments, signed integer overflow is undefined behavior in C.
The game's version of the program was apparently built with a compiler that handles it naively: by actually adding 1 to impossible_number (using ordinary two's-complement addition), then comparing the result with impossible_number and executing the fopen if it's less. In that case inputting 2147483647 works, as you saw. In my tests, clang without optimizations behaves like this.
But there are other possibilities. For instance, recent versions of GCC, even with -O0, notice that the test can't be true in any case when overflow doesn't occur. And if overflow does occur, the behavior is undefined, and so the compiler is at perfect liberty to do whatever it likes in that case. So it is allowed to assume that the test can't ever be true, and that's what it does: it optimizes away the entire if block, including the test itself which is now redundant. Try on godbolt; note that the generated assembly contains no call to fopen at all. So this program compiled with GCC is not vulnerable. The same is true for clang if optimizations are enabled (-O1 or higher).
(You can force the "naive" behavior in either compiler by compiling with -fwrapv. There is also -ftrapv which forces the program to abort if signed integer overflow ever occurs; it has a substantial runtime performance cost, but might be desirable when security is critical.)
Thus for an attack like this, you have to not only read the source code of the vulnerable program, but also be able to discover or guess what is in the compiled code that the victim is actually using.

Related

Im having problems using stdin and NULL in eclipse

Here is my code that I am having issues with. The goal of the program is to scan in a bunch of doubles and perform some simple statistical operations on them. The line I am having the issue with is the fgets(). I have included the stdio.h, it's just not showing up in the code. My actual question is where are the stdin and NULL giving me issues when I though they were part of the language? The exact error I am getting is that both Symbol stdin and NULL could not be resolved.
/*
* simpleStats.c
*
* Created on: Sep 17, 2018
* Author: David Liotta
*/
#include <stdio.h>
#define BUFSIZE 256
int main(){
double n, max, min, sum, mean;
char line[BUFSIZE];
int numsRead = 0;
int numOfItems = 1;
n = -1;
max = n;
min = n;
sum = n;
while(n != 0 && fgets(line, BUFSIZE, stdin ) != NULL){
numsRead = sscanf(line, "%f", &n);
if(numsRead == 1 && n != 0){
numOfItems++;
if(n > max)
max = n;
if(n < min)
min = n;
sum = sum + n;
}
if(numsRead == 0)
printf("Bad input\n");
}
mean = sum / numOfItems;
printf("# of items: %i", numOfItems);
printf("\nSum: %f.3", sum);
printf("\nMax: %f.3", max);
printf("\nMin: %f.3", min);
printf("\nMean: %f.3", mean);
}
This code should compile. I suspect something might be wrong with your development environment.
Since you're running Eclipse, I'm assuming that your compiler is GCC. I may be wrong though.
Try to locate your compiler executable, and run the compilation by hand:
gcc -Wall -o simpleStats simpleStats.c
or, if you're on Windows:
gcc.exe -Wall -o simpleStats.exe simpleStats.c
You may have to specify the full path to gcc.exe, (depending on your environment, it might even be called something else; you may be able to retrieve the full path from the console window in Eclipse).
Pay close attention to the output. Copy/paste the full output verbatim in your original post if you can (do not rephrase the warnings / error messages).
I seldom use Eclipse, but with most IDEs you get to chose what kind of project you want to create. Make sure you selected something like "console application", the error you're referring to (stdin not being resolved) may suggest a linker error. Again, it's hard to tell without the exact GCC output.
A couple more things to check:
make sure your compiler and its dependencies are properly installed,
make sure that this compiler is targeted at Windows (or whatever OS you use), not at some exotic embedded platform,
most development environments come with a bunch of sample projects, see if you can build one.
The problem I was having ended up being the compiler not correctly reading the code. I used a different compiler, and with some minor syntax changes, the code worked fine.

Do not understand message received after running temperature convert program

I am new to C and trying to write a program using Xcode that takes the temperature in Fahrenheit and converts it to Celsius, and vise versa. My code so far is below.
#include <stdio.h>
#include "hw2.h"
void convert_temp(int degree1, char scale1, int* degree2, char* scale2){
if (scale1 == 'F') {
*degree2 = ((degree1 - 32) * 5) / 9;
*scale2 = 'C';
}
else {
*degree2 = ((degree1 * 9) / 5) + 32;
*scale2 = 'F';
}
}
int main() {
int degree1, degree2;
char scale1, scale2;
printf("Enter a temperature and a scale\n");
scanf("%d %c", &degree1, &scale1);
convert_temp(degree1, scale1, &degree2, &scale2);
printf("%d %c = %d %c\n", degree1, scale1, degree2, scale2);
return 0;
}
Here is an example of correct i/o:
Enter a temperature and a scale
32 F
32 F = 0 C
However, when I run the code, this is what I get:
Enter a temperature and a scale
32 F
hw2 was compiled with optimization - stepping may behave oddly; variables may not be available.
(lldb)
I cannot understand the output I am getting. Can anybody tell me why I do not get 32 F = 0 C on my output? Everything in my code seems fine to me.
Assuming hw2 is the name of your program, then the debugger is complaining that it was compiled with optimisations turned on, which isn't normal during development, as the optimizer does all sorts of clever things to get the program running faster.
You need to do the following in Xcode:
Ensure you are debugging using the Debug build configuration (Check your Schemes).
Ensure you haven't turned on Optimizations for the Debug build configuration (Check your Build Settings).

gcc:error in input

i am enthusiast and new in programming trying this simple c language code and compile it with gnu compiler. here is my code:
/*simple program:trying to printf string and get a letter*/
#include "stdio.h"
int main()
{
int i=0;
char c;
while(i++<100){
if(i % 2)
printf("%C this is even number",i);
if(i==50){
c=getchar();
printf("you enter %c letter",c);
}
}
return 0;
}
however when i compile it with gcc and run in terminal, it doesnt show anything,no error and no warning. i tried to figure it out by changing the way my code behave but still not work. is it the code that wrong or gcc have bug or may be i miss about something?
Try to put a newline at the end of printf text:
printf("%C this is even number\n",i);
Also i is an int so use the %d format:
printf("%d this is even number\n",i);
Edit: I just tested this with the changes and it works for me.
You should call fflush(stdout) after your display.
It ran for me using cygwin under Windows Vista.
I pasted your code into a file called test.c and ran gcc test.c that output a file called a.exe which I then ran.
johnma#johnma-PC ~
$ ./a.exe
this is even number♥ this is even number♣ this is even number this is even numb
this is even numbern this is even number◄ this is even number this is even numb
er this is even number this is even number↓ this is even numberthis is even numb
er this is even number this is even number! this is even number# this is even nu
mber% this is even number' this is even number) this is even number+ this is eve
n number- this is even number/ this is even number1 this is even number
you enter
letter3 this is even number5 this is even number7 this is even number9 this is
even number; this is even number= this is even number? this is even numberA this
is even numberC this is even numberE this is even numberG this is even numberI
this is even numberK this is even numberM this is even numberO this is even numb
erQ this is even numberS this is even numberU this is even numberW this is even
numberY this is even number[ this is even number] this is even number_ this is e
ven numbera this is even numberc this is even number
johnma#johnma-PC ~

C: simple code not working as expected (PIC micro)

This line isn't working as expected:
uartPushPos = (uartPushPos + 1) % UART_TX_BUFF_LENGTH;
However this below, which in theory does the same, does work:
//if (uartPushPos == UART_TX_BUFF_LENGTH - 1){
if (uartPushPos >= UART_TX_BUFF_LENGTH - 1){
uartPushPos = 0;
} else {
uartPushPos++;
}
UartPopPos is type char, and UART_TX_BUFF_LENGTH is a preprocessor variable set to 16.
Why does the second code segment work, but not the first?
If it makes much of a difference, I'm using the SourceBoost BoostC compiler for the PIC microcontroller 16f.
Thanks
They are different if uartPushPos is less than 0, or if it is more than or equal to UART_TX_BUFF_LENGTH.
See also Mod of negative number is melting my brain

need help with conditional gdb debugging (of C code)

I have a C code similar to:
int f() {
for (int i = 0; i < 100; i++) {
scanf flag;
if(flag)
scanf data1;
scanf data2;
}
}
I want to break the execution only when flag == 0. How should I set the breakpoint (using gdb)?
In the gdb console type
b (some_line) if flag == 0
EDIT:
If you can't print flag while stopped at some-line, then either:
- (A) your code is compiled with optimization (likely), or
- (B) you have a buggy compiler
If it's (A), add -O0 in addition to -g3.
If you can print flag, then you have a buggy version of GDB. Try upgrading to current 7.0.1 release.

Resources