Exploiting strcpy() in C with Buffer overflow, [closed] - c

Closed. This question needs details or clarity. It is not currently accepting answers.
Want to improve this question? Add details and clarify the problem by editing this post.
Closed 5 years ago.
Improve this question
I'm new to the subject of computer security, and I came across this table
char *
isdn_net_newslave(char *parm)
{
char *p = strchr(parm, ',');
isdn_net_dev *n;
char newname[10];
if (p) {
/* Slave-Name MUST not be empty */
if (!strlen(p + 1))
return NULL;
strcpy(newname, p + 1);
*p = 0;
/* Master must already exist */
if (!(n = isdn_net_findif(parm)))
return NULL;
/* Master must be a real interface, not a slave */
if (n->local->master)
return NULL;
/* Master must not be started yet */
if (isdn_net_device_started(n))
return NULL;
return (isdn_net_new(newname, n->dev));
}
return NULL;
}
I want to get a root shell by exploiting strcpy() or strchr().
I have some troubles exploiting this with C, though it's got a strcpy() and strchr() inside it, because this is my first buffer overflow exploitation.
My Questions:
I don't know about ASLR well. How does it disturb the buffer overflow with a C script? I don't want to disable it, I'm looking at practical exploitation.
How to manipulate the variable newname?
And how to target this exact piece of code? Actually this code starts at Line 2639 in original code.
Please help me with this! Thank you!
Original Code:
https://kernel.googlesource.com/pub/scm/linux/kernel/git/ralf/linux/+/linux-3.18.19/drivers/isdn/i4l/isdn_net.c

any overflow ( buffer, stack, heap, ... ) requires shell code to lead to an exploit.
ASLR and DEP randomize the location of specific modules ( like i.e. stack, heap, libc ) in memory by a random offset cf https://security.stackexchange.com/questions/18556/how-do-aslr-and-dep-work
on linux you can see how ASLR works with cat /proc/self/maps ( With ASLR turned on, are all sections of an image get loaded at the same offsets relative to the image base address every time? )
if this would not be done and the modules were at static positions in memory ( like it was back in the old days ) one would have a static address where specific functions are located and these addresses could be used as entry point for the shellcode execution, because any overflow exploit has the goal to place shellcode in memory and execute this shellcode by a pointer to the specific position in memory
i will not tell you more about grey techniques here but maybe have a look at return-oriented programming what is a variant of overflow technique that is still efficient
( Exploiting a string-based overflow on x86-64 with NX (DEP) and ASLR enabled )

Related

Meltdown PoC Detailed Code Review [closed]

Closed. This question needs to be more focused. It is not currently accepting answers.
Want to improve this question? Update the question so it focuses on one problem only by editing this post.
Closed 5 years ago.
Improve this question
I read all the week-end about Meltdown and Spectre
I also have already read the .pdfs for Spectre and Meltdown
which are Must Read for anyone seeking more knowledge about these exploits but unfortunately don't provide detailed explanations on the code.
I found various PoC on github, which were very interesting but I lack the knowledge to fully understand it. I would be thanksful about more explanation on specific parts:
From this link https://github.com/dendisuhubdy/meltdown/blob/master/src/poc.c , and other git repositories as well, there are many interesting parts in the conception of this exploit.
Time reads
/* Time reads. Order is lightly mixed up to prevent stride prediction */
for (i = 0; i < 256; i++) {
mix_i = ((i * 167) + 13) & 255;
addr = &array2[mix_i * 512];
time1 = __rdtscp(&junk); /* READ TIMER */
junk = *addr; /* MEMORY ACCESS TO TIME */
time2 = __rdtscp(&junk) - time1; /* READ TIMER & COMPUTE ELAPSED TIME */
if (time2 <= CACHE_HIT_THRESHOLD && mix_i != array1[tries % array1_size])
results[mix_i]++; /* cache hit - add +1 to score for this value */
}
why do we use prime numbers 167 and 13 ?
/* Locate highest & second-highest results results tallies in j/k */
Why do we care about getting the max value ?
Other parts explanations are very welcome as well !!

how many recursive function calls causes stack overflow?

I am working on a simulation problem written in c, the main part of my program is a recursive function.
when the recursive depth reaches approximately 500000 it seems stack overflow occurs.
Q1 : I want to know that is this normal?
Q2 : in general how many recursive function calls causes stack overflow?
Q3 : in the code below, removing local variable neighbor can prevent from stack overflow?
my code:
/*
* recursive function to form Wolff Cluster(= WC)
*/
void grow_Wolff_cluster(lattic* l, Wolff* wolff, site *seed){
/*a neighbor of site seed*/
site* neighbor;
/*go through all neighbors of seed*/
for (int i = 0 ; i < neighbors ; ++i) {
neighbor = seed->neighbors[i];
/*add to WC according to the Wolff Algorithm*/
if(neighbor->spin == seed->spin && neighbor->WC == -1 && ((double)rand() / RAND_MAX) < add_probability)
{
wolff->Wolff_cluster[wolff->WC_pos] = neighbor;
wolff->WC_pos++; // the number of sites that is added to WC
neighbor->WC = 1; // for avoiding of multiple addition of site
neighbor->X = 0;
///controller_site_added_to_WC();
/*continue growing Wolff cluster(recursion)*/
grow_Wolff_cluster(l, wolff, neighbor);
}
}
}
I want to know that is this normal?
Yes. There's only so much stack size.
In the code below, removing local variable neighbor can prevent from stack overflow?
No. Even with no variables and no return values the function calls themselves must be stored in the stack so the stack can eventually be unwound.
For example...
void recurse() {
recurse();
}
int main (void)
{
recurse();
}
This still overflows the stack.
$ ./test
ASAN:DEADLYSIGNAL
=================================================================
==94371==ERROR: AddressSanitizer: stack-overflow on address 0x7ffee7f80ff8 (pc 0x00010747ff14 bp 0x7ffee7f81000 sp 0x7ffee7f81000 T0)
#0 0x10747ff13 in recurse (/Users/schwern/tmp/./test+0x100000f13)
SUMMARY: AddressSanitizer: stack-overflow (/Users/schwern/tmp/./test+0x100000f13) in recurse
==94371==ABORTING
Abort trap: 6
In general how many recursive function calls causes stack overflow?
That depends on your environment and function calls. Here on OS X 10.13 I'm limited to 8192K by default.
$ ulimit -s
8192
This simple example with clang -g can recurse 261976 times. With -O3 I can't get it to overflow, I suspect compiler optimizations have eliminated my simple recursion.
#include <stdio.h>
void recurse() {
puts("Recurse");
recurse();
}
int main (void)
{
recurse();
}
Add an integer argument and it's 261933 times.
#include <stdio.h>
void recurse(int cnt) {
printf("Recurse %d\n", cnt);
recurse(++cnt);
}
int main (void)
{
recurse(1);
}
Add a double argument, now it's 174622 times.
#include <stdio.h>
void recurse(int cnt, double foo) {
printf("Recurse %d %f\n", cnt, foo);
recurse(++cnt, foo);
}
int main (void)
{
recurse(1, 2.3);
}
Add some stack variables and it's 104773 times.
#include <stdio.h>
void recurse(int cnt, double foo) {
double this = 42.0;
double that = 41.0;
double other = 40.0;
double thing = 39.0;
printf("Recurse %d %f %f %f %f %f\n", cnt, foo, this, that, other, thing);
recurse(++cnt, foo);
}
int main (void)
{
recurse(1, 2.3);
}
And so on. But I can increase my stack size in this shell and get twice the calls.
$ ./test 2> /dev/null | wc -l
174622
$ ulimit -s 16384
$ ./test 2> /dev/null | wc -l
349385
I have a hard upper limit to how big I can make the stack of 65,532K or 64M.
$ ulimit -Hs
65532
A stack overflow isn’t defined by the C standard, but by the implementation. The C standard defines a language with unlimited stack space (among other resources) but does have a section about how implementations are allowed to impose limits.
Usually it’s the operating system that actually first creates the error. The OS doesn’t care about how many calls you make, but about the total size of the stack. The stack is composed of stack frames, one for each function call. Usually a stack frame consists of some combination of the following five things (as an approximation; details can vary a lot between systems):
The parameters to the function call (probably not actually here, in this case; they’re probably in registers, although this doesn’t actually buy anything with recursion).
The return address of the function call (in this case, the address of the ++i instruction in the for loop).
The base pointer where the previous stack frame starts
Local variables (at least those that don’t go in registers)
Any registers the caller wants to save when it makes a new function call, so the called function doesn’t overwrite them (some registers may be saved by the caller instead, but it doesn’t particularly matter for stack size analysis). This is why passing parameters in registers doesn’t help much in this case; they’ll end up on the stack sooner or later.
Because some of these (specifically, 1., 4., and 5.) can vary in size by a lot, it can be difficult to estimate how big an average stack frame is, although it’s easier in this case because of the recursion. Different systems also have different stack sizes; it currently looks like by default I can have 8 MiB for a stack, but an embedded system would probably have a lot less.
This also explains why removing a local variable gives you more available function calls; you reduced the size of each of the 500,000 stack frames.
If you want to increase the amount of stack space available, look into the setrlimit(2) function (on Linux like the OP; it may be different on other systems). First, though, you might want to try debugging and refactoring to make sure you need all that stack space.
Yes and no - if you come across a stack overflow in your code, it could mean a few things
Your algorithm is not implemented in a way that respects the amount of memory on the stack you have been given. You may adjust this amount to suit the needs of the algorithm.
If this is the case, it's more common to change the algorithm to more efficiently utilize the stack, rather than add more memory. Converting a recursive function to an iterative one, for example, saves a lot of precious memory.
It's a bug trying to eat all your RAM. You forgot a base case in the recursion or mistakenly called the same function. We've all done it at least 2 times.
It's not necessarily how many calls cause an overflow - it's dependent upon how much memory each individual call takes up on a stack frame. Each function call uses up stack memory until the call returns. Stack memory is statically allocated -- you can't change it at runtime (in a sane world). It's a last-in-first-out (LIFO) data structure behind the scenes.
It's not preventing it, it's just changing how many calls to grow_Wolff_cluster it takes to overflow the stack memory. On a 32-bit system, removing neighbor from the function costs a call to grow_Wolff_cluster 4 bytes less. It adds up quickly when you multiply that in the hundreds of thousands.
I suggest you learn more about how stacks work for you. Here's a good resource over on the software engineering stack exchange. And another here on stack overflow (zing!)
For each time a function recurs, your program takes more memory on the stack, the memory it takes for each function depends upon the function and variables within it. The number of recursions that can be done of a function is entirely dependant upon your system.
There is no general number of recursions that will cause stack overflow.
Removing the variable 'neighbour' will allow for the function to recur further as each recursion takes less memory, but it will still eventually cause stack overflow.
This is a simple c# function that will show you how many iteration your computer can take before stack overflow (as a reference, I have run up to 10478):
private void button3_Click(object sender, EventArgs e)
{
Int32 lngMax = 0;
StackIt(ref lngMax);
}
private void StackIt(ref Int32 plngMax, Int32 plngStack = 0)
{
if (plngStack > plngMax)
{
plngMax = plngStack;
Console.WriteLine(plngMax.ToString());
}
plngStack++;
StackIt(ref plngMax, plngStack);
}
in this simple case, the condition check: "if (plngStack > plngMax)" could be removed,
but if you got a real recursive function, this check will help you localize the problem.

What is the C way to report progress of computation? [closed]

Closed. This question needs to be more focused. It is not currently accepting answers.
Want to improve this question? Update the question so it focuses on one problem only by editing this post.
Closed 6 years ago.
Improve this question
This is a follow-up question to Using a thread in C++ to report progress of computations.
Suppose that I have a for loop which executes run_difficult_task() many times, and I would like to infer how far the loop has advanced. I used to write:
int i;
for (i=0; i < 10000; ++i) {
run_difficult_task(i);
if (i % 100 == 0) {
printf("i = %d\n", i);
}
}
but the main problem with such approach is that executing run_difficult_task() might literally take forever (by being stuck in an infinite loop, etc.), so I would like to get a progress report in every k seconds by means of printing out the value of the loop variable i.
I found quite a rich literature on this site regarding object-oriented multithreading (of which I am not really familiar with) in various programming languages, but the questions I found doing this in C-style seem quite outdated. Is there a platform-independent, C11 way to do what I want? If there is not any, then I would be interested in methods working in unix and with gcc.
Note: I do not wish to run various instances of run_difficult_task in parallel (with, for example, OpenMP), but I want to run the for loop and the reporting mechanism in parallel.
Related: How to "multithread" C code and How do I start threads in plain C?
Linux (and also POSIX systems) provide the alarm library call. This allows you to do something after an interval of seconds without interrupting your main thread, and without bothering with multi-threading when you don't really need it. It was very much created for use cases like yours.
You can try using one thread (the worker thread) or possibly two (one that does computations and one that displays output while main is doing something else or just waiting) and some global variables (ugh).
The first thread will be your workhorse doing computations and updating some global variable. The second one (maybe simply the main thread) will then check whether this variable has changed or not and then print the stats (perhaps, that variable will hold the stats, for example, percentage).
What you can try:
int ping = 0, working = 0, data;
// in main thread
for (/* something */){
// spawn worker thread
while (working) {
if (ping) printf("%d\n", data), ping = 0;
}
}
// in worker thread
working = 1;
while (/* something */) {
// do a lot of computations
if (/* some condition */) {
if (! ping) {
data = /* data */
ping = 1;
}
}
}
working = 0;
Here's a simple time based progress indicator that I've often used:
void
progress(int i)
{
time_t tvnow;
static time_t tvlast;
static time_t tvbeg;
if (tvbeg == 0) {
tvbeg = time(NULL);
tvlast = tvbeg - 2;
}
tvnow = time(NULL);
if ((tvnow - tvlast) >= 1) {
printf("\r%ld: i = %d",tvnow - tvbeg,i);
fflush(stdoout);
tvlast = tvnow;
}
}
int i;
for (i=0; i < 10000; ++i) {
run_difficult_task(i);
progress(i);
}
UPDATE:
Does this update if run_difficult_task(i) runs for longer than 2seconds?
No, but I've updated the example to put the progress code in a separate function, which is what I normally do in my own code.
You'll have to add calls to the progress function within run_difficult_task to get finer grain progress--this is something I also do in my own code.
But, notice that I added an elapsed time [in seconds] to the progress.
If you didn't care about that, if run_difficult_task takes longer than 2 seconds to run, there is no progress until it returns as you define it because progress is defined by incrementing i which is done by the outer loop.
For my own stuff, the progress function can handle an arbitrary number of progress indicators from an arbitrary number of worker threads.
So, if that would be of interest to you, and [say] run_difficult_task has some inner loop variables like j, k, l, these could be added to the progress. Or, whatever you wish to report on.

libopcodes: get the size of a instruction

I have to find out the size of a instruction which I have in memory (actually, I have a small code segment in memory and want to get the size of the first instruction).
It took me some time to find libopcodes and libbfd. I red the headers and tried to come up with a simple solution but it seems like I missunderstood something since the program always crashes:
int main(int argc, char **argv) {
disassemble_info *dis = malloc(sizeof(*dis));
assert(dis != NULL);
dis->arch = bfd_arch_i386;
dis->read_memory_func = buffer_read_memory;
dis->buffer_length = 64;
dis->buffer = malloc(dis->buffer_length);
memset(dis->buffer, 0x90, dis->buffer_length);
disassemble_init_for_target(dis);
int instr_size = print_insn_i386(0, dis);
printf("instruction size is %d\n", instr_size);
return 0;
}
The expected result would be an instruction size of 1 (nop).
EDIT:
sorry guys, I'm a stupid person.
memset(dis, 0, sizeof(*dis));
There is some code in the Linux kernel you can steal. It should work well if copied into a user mode program.
Take a look at arch/x86/lib and arch/x86/tools
There's an opcode map file there, and an awk script that reads it to produce a table in a file named innat.c. There are some other files there that use the table to implement a decoder.
It is sufficient to determine instruction sizes.
This assumes you are ok with GPL, of course.
It looks like the disassemble_info data structure requires more initialization than you have provided. From examples I have been studying, the correct way to initialize is to call init_disassemble_info().
See if that helps. Failing that, compile your program with debug info ('-g') and run gdb to diagnose where the crash occurs.

Changing a variable's value through the stack

Okay we are given the following code:
#include <stdio.h>
#include <ctype.h>
#include <stdlib.h>
#include <string.h>
#include "callstack.h"
#include "tweetIt.h"
#include "badguy2.c"
static char *correctPassword = "ceriaslyserious";
char *message = NULL;
int validateSanity(char *password) {
for(int i=0;i<strlen(password);i++)
if(!isalpha(password[i]))
return 0;
unsigned int magic = 0x12345678;
return badguy(password);
}
int validate(char *password) {
printf("--Validating something\n", password);
if (strlen(password) > 128) return 0;
char *passwordCopy = malloc(strlen(password) + 1);
strcpy(passwordCopy, password);
return validateSanity(passwordCopy);
}
int check(char *password, char *expectedPassword) {
return (strcmp(password, expectedPassword) == 0);
}
int main() {
char *password = "wrongpassword";
unsigned int magic = 0xABCDE;
char *expectedPassword = correctPassword;
if (!validate(password)) {
printf("--Invalid password!\n");
return 1;
}
if (check(password, expectedPassword)) {
if (message == NULL) {
printf("--No message!\n");
return 1;
} else {
tweetIt(message, strlen(message));
printf("--Message sent.\n");
}
} else {
printf("--Incorrect password!\n");
}
return 0;
}
We are supposed to trick main into sending a tweet using the function badguy. In badguy we have an offset from a previous problem which is the difference between the declaration of password in main and the argument passed to badguy. We have been instructed to use this offset to find the addresses of the correctPassword and password in main and manipulate the value in password to correctPassword so when the password check occurs, it is believed to be legitimate. I am having some trouble figuring out how to use this offset to find the addresses and continuing from there.
First of all, make sure you have good control over your compiler behavior. That is: make sure you know the calling conventions and that they're being respected (not optimized away or altered in any manner). This usually boils down to turn off optimization settings, at least for testing under more controlled conditions until a robust method is devised. Pay special attention to variables such as expectedPassword, since it is highly likely they'll be optimized away (expectedPassword might never be created in the stack, being substituted with the equivalent of correctPassword, rendering you with no stack reference to the correct password at all).
Secondly, note that "wrongpassword" is shorter than "ceriaslyserious"; in other words, if I got it straight, attempting to crack into the buffer pointed to by passwordCopy (whose size is the length of "wrongpassword" plus one) in order to copy "ceriaslyserious" into there could result in a segmentation violation. Nonetheless, it should be relatively simple to track the address of expectedPassword in the call stack, if it exists (see above), specially if you do have already an offset from main()'s stack frame.
Considering an x86 32-bit target under controlled circumstances, expectedPassword will reside 8 bytes below password (4 for password, 4 for magic if it is not optimized away). Having an offset from password to a parameter as you said, it should suffice to subtract the offset from the address of that parameter, and then add 8. The resulting pointer should be expectedPassword, which then points to the static area containing the password. Again, double check your environment. Check this for an explanation on the stack layout in x64 (the layout in the 32-bit case is similar).
Lastly, if expectedPassword does not exist in the call stack, then, since correctPassword is a global static, it will reside in a data segment, rendering the method useless. To achieve the goal in this situation, you would need to carefully scan the data segment with a more intelligent algorithm. It would probably be easier, though, to simply attempt to find the test for check()'s return value in the program text and replace with nops (after properly manipulating the page permissions to allow writing to the text segment).
If you're having problems, inspecting the resulting assembly code is the way to go. If you're using GCC, gcc -S halts the compilation just before assembling (that is, producing an assembly source code file as output). objdump -d could also help. gdb can step between instructions, show the disassembly of a frame and display register contents; check the documentation.
These exercises are specially useful to understand how security breaches occur in common programs, and to provide some basic notions on defensive programming.

Resources