Register for your free account! | Forgot your password?

Go Back   elitepvpers > Coders Den > C/C++
You last visited: Today at 11:49

  • Please register to post and access all features, it's quick, easy and FREE!

Advertisement



Calculating the Average of Numbers

Discussion on Calculating the Average of Numbers within the C/C++ forum part of the Coders Den category.

Reply
 
Old 11/02/2019, 17:46   #16
 
elite*gold: 0
Join Date: Feb 2009
Posts: 1,137
Received Thanks: 572
As already stated I don't have much time at hand, so I can't really get into this challange (honestly, currently I should be doing sth else, but some procrastination is fine), but here are my thoughts from looking at it for about 2 hours (taken all the few times i looked at it together):
Code:
data = calloc(cnt + 1, sizeof(*data));
calloc takes an size_t type, which is in the glibc unsigned, while cnt is signed. This means giving a negative number for cnt will result in a huge memory area being allocated (as it is converted to unsigned), but i < cnt would surely be false, so we have a huge memory area we can't access.
Also calloc checks for overflow for the multiplication of numElements * sizeElements, meaning you can't simply trick it to allocate a small area but access on large indices (and thereby write out of memory)
I already mentioned:
Code:
for(int i=1; i < cnt + 1; i++){
Which could have been exploited 20 years ago or so, but is off the table on modern systems
Code:
if(!(0 <= idx < ARR_LEN) || data[idx] == NULL){exit(0);}
Is interesting, because 0 <= idx < ARR_LEN is equal to (0 <= idx) < ARR_LEN. (0 <= idx) is either 0 or 1, ARR_LEN is equal to 10, making this a tautology. So using this line of code, one can basically check any memory location if it is NULL, and with the rest of the function you can get at least some information off the state of the memory (basically by timing how long the operation takes you could guess the value written in a position, referenced by data + idx), which is a huge security flaw, but I don't think it's directly exploitable for the challange.
The more interesting occurance of this tautology is here:
Code:
if(0 <= idx < ARR_LEN && numbers[idx] != NULL){
		free(numbers[idx]);	
		numbers[idx] = NULL;
Which basically let's you call free on any arbitrary memory location, which isn't NULL, and write NULL to it.

So yeah, maybe some if this is exploitable (), but everything further than this simple analysis would take me looking deeper than just the man pages for malloc/calloc/free, and I simply have no time for that.
warfley is offline  
Thanks
1 User
Old 11/02/2019, 17:57   #17
 
Beni's Avatar
 
elite*gold: 0
The Black Market: 171/0/0
Join Date: Jul 2009
Posts: 3,268
Received Thanks: 784
Quote:
Originally Posted by warfley View Post
As already stated I don't have much time at hand, so I can't really get into this challange (honestly, currently I should be doing sth else, but some procrastination is fine), but here are my thoughts from looking at it for about 2 hours (taken all the few times i looked at it together):
Code:
data = calloc(cnt + 1, sizeof(*data));
calloc takes an size_t type, which is in the glibc unsigned, while cnt is signed. This means giving a negative number for cnt will result in a huge memory area being allocated (as it is converted to unsigned), but i < cnt would surely be false, so we have a huge memory area we can't access.
Also calloc checks for overflow for the multiplication of numElements * sizeElements, meaning you can't simply trick it to allocate a small area but access on large indices (and thereby write out of memory)
I already mentioned:
Code:
for(int i=1; i < cnt + 1; i++){
Which could have been exploited 20 years ago or so, but is off the table on modern systems
Code:
if(!(0 <= idx < ARR_LEN) || data[idx] == NULL){exit(0);}
Is interesting, because 0 <= idx < ARR_LEN is equal to (0 <= idx) < ARR_LEN. (0 <= idx) is either 0 or 1, ARR_LEN is equal to 10, making this a tautology. So using this line of code, one can basically check any memory location if it is NULL, and with the rest of the function you can get at least some information off the state of the memory (basically by timing how long the operation takes you could guess the value written in a position, referenced by data + idx), which is a huge security flaw, but I don't think it's directly exploitable for the challange.
The more interesting occurance of this tautology is here:
Code:
if(0 <= idx < ARR_LEN && numbers[idx] != NULL){
		free(numbers[idx]);	
		numbers[idx] = NULL;
Which basically let's you call free on any arbitrary memory location, which isn't NULL, and write NULL to it.

So yeah, maybe some if this is exploitable (), but everything further than this simple analysis would take me looking deeper than just the man pages for malloc/calloc/free, and I simply have no time for that.
(the calloc thing should be safe, as cnt can only be -1 on an input scanf() cannot process, and all other values are parsed with "%ld".)


Bravo! This tautology is the intended bug. Sharp eyes and solid understanding of C. Most people tend to fly over such kind of constructs, as it is common in python, etc.

In the first occasion, in print_average, this can be used to print contents relative to the heap, thus leading to a information leak, which can be used to get the heap and libc base.
In the second occasion, as you mentioned, this leads to an arbitrary free. Double-free's are mostly detected nowadays within the glibc, either in the bins or in the t-caches. However an arbitrary free (together with an info leak) is mighty enough to exploit this programm. (or anything, in general.)

soo,.. who will take this and turn it into a shell? I can assist people here, if someone decides to take this chall.
expect a lot of man-hours effort if you never wrote some heap-based exploit.
Beni is offline  
Old 11/02/2019, 18:44   #18
 
elite*gold: 100
Join Date: Apr 2008
Posts: 860
Received Thanks: 1,464
Quote:
Originally Posted by Beni View Post
Anyone else with bug-suggestions? :P
I guess we're in a kinda "open-mode" right now. There's this:

Code:
if(!(0 <= idx < ARR_LEN) || data[idx] == NULL){
    //
}
The first check is garbage. It's not doing what it looks like it does. 0 <= idx is turned into a boolean which is then compared to < ARR_LEN. The result of 0 <= idx is either 0 or 1, which is always < ARR_LEN, so we always return true on this one. It all depends on data[idx].
This leads to either oob read (in print_average) or arbitrary free (in delete_numbers). We can possibly make this a use-after-free, by releasing more or less random memory.

Since I haven't found any oob write to the stack to change the control flow, my current idea is to try and get an arbitrary write to the PLT and execute some code I entered into the array eariler. No idea if that works. Just a theory xD.

Edit: Ah man. Did i really take over one hour to submit this post :rofl:
Edit 2: Oh wow. I didn't think about the information leak in print_numbers.
florian0 is offline  
Thanks
1 User
Old 11/02/2019, 20:50   #19
 
Beni's Avatar
 
elite*gold: 0
The Black Market: 171/0/0
Join Date: Jul 2009
Posts: 3,268
Received Thanks: 784
Quote:
Originally Posted by florian0 View Post
I guess we're in a kinda "open-mode" right now. There's this:

Code:
if(!(0 <= idx < ARR_LEN) || data[idx] == NULL){
    //
}
The first check is garbage. It's not doing what it looks like it does. 0 <= idx is turned into a boolean which is then compared to < ARR_LEN. The result of 0 <= idx is either 0 or 1, which is always < ARR_LEN, so we always return true on this one. It all depends on data[idx].
This leads to either oob read (in print_average) or arbitrary free (in delete_numbers). We can possibly make this a use-after-free, by releasing more or less random memory.

Since I haven't found any oob write to the stack to change the control flow, my current idea is to try and get an arbitrary write to the PLT and execute some code I entered into the array eariler. No idea if that works. Just a theory xD.

Edit: Ah man. Did i really take over one hour to submit this post :rofl:
Edit 2: Oh wow. I didn't think about the information leak in print_numbers.
Bravo, too!

You mentioned "trying to get an arbitrary write". How would you try to get an write? This is basicly the challenge, which is, given this mighty primitive, not too hard.

If you could write arbitrarily, I suggest other targets. In heap based exploits, often times something known as __malloc_hook, __free_hook (or other hooks ) are chosen as target to write to. Just check the implementation of __libc_malloc (the thing which is being called first, when you call malloc()) to get an understanding of the hooks.
Beni is offline  
Old 01/03/2020, 21:46   #20
 
Beni's Avatar
 
elite*gold: 0
The Black Market: 171/0/0
Join Date: Jul 2009
Posts: 3,268
Received Thanks: 784
Bumping with some more info :P.

so i wrote this chall in some lazy night, intended to share it here. however there was some other CTF approaching, so i just submitted it there as challenge. since this ctf is now over since quite some time, there are also detailed writeups about the exploitation path.

If you still want to solve the chall on your own or with some little help by me, dont read the following. Spoilers ahead.







one might use this as learning / or as starting point. do whatever.

however - im disappointed :P y'all can do better than this
Beni is offline  
Reply


Similar Threads Similar Threads
[Selling] account lvl 30 / average 25000 pi / average 140 rp
01/23/2015 - League of Legends Trading - 0 Replies
Hi everybody i got regularly some fresh lvl 30 account to sell , 20 euros per account . Have a nice day .
charname numbers or guild numbers will take block?
02/21/2010 - Silkroad Online - 6 Replies
charname numbers or guild numbers will take block? some friends said that to me is it right?
Calculating Eudemon checksum
04/04/2008 - EO PServer Hosting - 1 Replies
Hi all, i was wondering if anyone knew what the function is that EO uses to calculate the chksum field in the cq_eudemon table? I tried to find it in the source code, but came up blank. Any help is appreciated :)
Calculating Atack or MAtack
05/04/2007 - CO2 Guides & Templates - 4 Replies
Sometimes you wanted know the atack of an trojan and him dont told you? with thats easy guide, you just need open him equipaments window! "JUST 1 percent error" TROJAN ATACK: The follow instructions is both used to lower and higher atack:
Calculating Hours of Pkp
11/23/2006 - CO2 Guides & Templates - 15 Replies
Ever have a black name or more than 30 pk points? This is how to calculate The total time u will have to wait for those 'awful' pk points to get off. 1. Multiply # of pk points by 6. (EX- 100pkp X 6 =600) 2. Divide that number by 60. (EX- 600 / 60) 3. The end number will be the # of hours it will take to get your pkp off.



All times are GMT +2. The time now is 11:49.


Powered by vBulletin®
Copyright ©2000 - 2024, Jelsoft Enterprises Ltd.
SEO by vBSEO ©2011, Crawlability, Inc.
This site is protected by reCAPTCHA and the Google Privacy Policy and Terms of Service apply.

Support | Contact Us | FAQ | Advertising | Privacy Policy | Terms of Service | Abuse
Copyright ©2024 elitepvpers All Rights Reserved.