Finding the address of /bin/bash for buffer overflow attack - bash

I am trying out ret-to-libc attacks and use the following piece of code to get the address of environment variable /bin/bash
#include <unistd.h>
int main(void)
{
printf("bash address: 0x%lx\n", getenv("SHELL"));
return 0;
}
when i use gdb's x command to check if the address returned by this code is correct it shows up correctly the first time.But when some other program is executed this address changes automatically.What should i do to keep this environment variable's address constant? I am using this address for buffer overflow, but since it keeps changing with every run, the attack is never successful. Any suggestions?

You have to disable the ASLR for the address to not change.
echo 0 | tee /proc/sys/kernel/randomize_va_space

Related

macOS blocking serial I/O

I'm writing a tool as part of a test suite, which needs to talk over a serial port to some hardware so that the code being tested sees the environment change.
So, I do this:
open("/dev/tty.usbmodem14141", O_RDWR | O_NOCTTY);
only it hangs there. If I replace that call with
open("/dev/tty.usbmodem14141", O_RDWR | O_NOCTTY | O_NONBLOCK);
then it works -- but I would prefer not to have to fiddle with select() and friends, or write a busy-loop poll, just so I can read from the serial port; that's what blocking I/O is for.
Do I need to do anything special for this to work?
When you have opened the serial terminal in nonblocking mode, you can then clear the file status flag to perform I/O in blocking mode.
To clear the nonblocking status flag you can use fcntl(), e.g.:
int flags;
flags = fcntl(fd, F_GETFL);
flags &= ~O_NONBLOCK;
fcntl(fd, F_SETFL, flags);
Since the Linux version of F_SETFL can change only the O_APPEND, O_ASYNC, O_DIRECT, O_NOATIME, and O_NONBLOCK flags, common practice is to simplify the code down to just
fcntl(fd, F_SETFL, 0);
(Yes, the single-liner does not have the same degree of portability as advocated in Setting Terminal Modes Properly.)

NFS mount System Call in linux

I am trying to mount a source directory from nfs server to a destination directory in embedded board having linux. The following command works perfectly as expected in shell prompt in the board.
mount -t nfs -o nolock 10.126.62.45:/vol/home/avinoba/Sky /mnt
What is the equivalent system call to be used in program for the command above?
I tried the below call but the mount failed with "Invalid Argument"
if(mount("10.126.62.45:/vol/home/avinoba/Sky","/mnt","nfs",MS_MGC_VAL,"nolock") == -1)
{
printf("ERROR: mount failed: %s \n",strerror(errno));
}
Please suggest what is the solution for it.
Thanks
I'm quite surprised here knowing that how this is not covered by any man page regarding NFS mounts. Diving into the kernel code, in the function nfs_validate_text_mount_data, the function nfs_parse_mount_options is responsible for parsing the multiple comma separated options passed as the fifth argument in the mount system call.
struct sockaddr *sap = (struct sockaddr *)&args->nfs_server.address;
if (nfs_parse_mount_options((char *)options, args) == 0)
return -EINVAL;
if (!nfs_verify_server_address(sap))
goto out_no_address;
In the above code block, the last if statement checks whether the nfs server address and socket family is defined to valid values. If they are not updated within nfs_parse_mount_options, mount would end up returning invalid parameter.
If the implementation of nfs_parse_mount_options is walked through, it can be seen that, only for the case Opt_addr, the nfs server address and the socket family is updated by parsing the options argument.
case Opt_addr:
string = match_strdup(args);
if (string == NULL)
goto out_nomem;
mnt->nfs_server.addrlen =
rpc_pton(mnt->net, string, strlen(string),
(struct sockaddr *)
&mnt->nfs_server.address,
sizeof(mnt->nfs_server.address));
kfree(string);
if (mnt->nfs_server.addrlen == 0)
goto out_invalid_address;
break;
The case Opt_addr corresponds to the option "addr=nfs server ip". So for the system call to work, defining this option is a must. As far as I have searched, this is completely missing from all the man pages which describes nfs mounts.
So now considering the problem statement, please try by changing to the below code
if(mount(":/vol/home/avinoba/Sky","/mnt","nfs",0,"nolock,addr=10.126.62.45") == -1)
{
printf("ERROR: mount failed: %s \n",strerror(errno));
}
Also note that when the addr option is put in the argument, the ip address in front of the nfs server path becomes optional. However the ':' is must,as this acts as the delimiter to parse the nfs server path.
MS_MGC_VAL should be in the top 16 bits if needed, not the bottom. If your kernel version is > 2.4, you don't need it at all.
It solved by the following call for me now.
if(system("mount -t nfs -o nolock 10.126.62.45:/vol/home/avinoba/Sky /mnt")==-1);
{
printf("ERROR: mount failed \n");
}
But still searching for the answer with mount() call as it accepts 'filesystemtype' argument as "nfs".

bogus first syscall argument reported for 32-bit processes on Linux x86_64?

On Linux x86_64 systems (at least RHEL 6.4 running 2.6.32), the first syscall argument reported by /proc/pid/syscall for 32-bit processes seems to be bogus ... I'd like to determine why.
For example, if a process is blocked doing openat(AT_FDCWD, ...), I see the following in /proc/pid/syscall ...
64-bit:
257 0xffffffffffffff9c ...
32-bit:
295 0xffffffff810495c0 ...
AT_FD_CWD == -100 == 0xffffffffffffff9c, so the 64-bit case looks right, but the value for 32-bit seems to have been clobbered (the other arguments look right).
I know that I can find a struct pt_regs at the top of the stack, and I can find it via ...
#define task_pt_regs(tsk) ((struct pt_regs *)(tsk)->thread.sp0 - 1)
I see the bogus value there.
However ... strace seems to be able to find the correct value of the first argument even in the 32-bit case. It does ptrace(PTRACE_PEEKUSER), which AFAIK just looks at the same struct pt_regs.
I must be missing something ... what magic happens for strace that allows it to see valid register values via PTRACE_PEEKUSER? What happens to clobber the first argument as seen via /proc/pid/syscall?

Limit Memory allocation to a process in Mac-OS X 10.8

I would like to control the maximum memory, a process can use in Mac-OS X 10.8. I feel that setting ulimit -v should achieve the goals but doesn't seem to be the case. I tried following simple commands :
ulimit -m 512
java -Xms1024m -Xmx2048m SomeJavaProgram
I was assuming that 2nd command should fail as Java Process will start by keeping 1024MB of memory for itself but it passes peacefully. Inside my Sample program, I try allocating more than 1024MB using following code snippet:
System.out.println("Allocating 1 GB of Memory");
List<byte[]> list = new LinkedList<byte[]>();
list.add(new byte[1073741824]); //1024 MB
System.out.println("Done....");
Both these programs get executed without any issues. How can we control the max memory allocation for a program in Mac-OS X?
I'm not sure if you still need the question answered, but here is the answer in case anyone else happens to have the same question.
ulimit -m strictly limits resident memory, and not the amount of memory a process can request from the operating system.
ulimit -v will limit the amount of virtual memory a process can request from the operating system.
for example...
#include <stdio.h>
#include <stdlib.h>
int main(int argc, char* argv[]) {
int size = 1 << 20;
void* memory = NULL;
memory = malloc(size);
printf("allocated %i bytes...\n", size);
return 0;
}
ulimit -m 512
./memory
allocated 1048576 bytes...
ulimit -v 512
./memory
Segmentation fault
If you execute ulimit -a it should provide a summary of all the current limits for child processes.
As mentioned in comments below by #bikram990, the java process may not observe soft limits. To enforce java memory restrictions, you can pass arguments to the process (-Xmx, -Xss, etc...).
Warning!
You can also set hard limits via the ulimit -H command, which cannot be modified by sub-processes. However, those limits also cannot be raised again once lowered, without elevated permissions (root).

Profiling the memory used by linux kernel

I have linux kernel 2.6.30 on an ARM based embedded device.
I have to do some kernel memory usage profiling on the device.
I am thinking of monitoring the ps output on various kernel threads and modules while I carry out actions like wifi on/off etc.
Can you suggest me:
Which threads I need to monitor? How to monitor the kernel module memory usage?
sometimes it is useful to get the real info straight from the kernel, I have used this little C program I threw together to get real system info in an output format that is suited for the shell (it compiles down to a pretty small binary if that matters) --
#include <sys/sysinfo.h>
int main(int argc, char **argv){
struct sysinfo info;
sysinfo(&info);
printf( "UPTIME_SECONDS=%d\n"
"LOAD_1MIN=%d\n"
"LOAD_5MIN=%d\n"
"LOAD_15MIN=%d\n"
"RAM_TOT=%d\n"
"RAM_FREE=%d\n"
"MEMUSEDKB=%d\n"
"RAM_SHARED=%d\n"
"RAM_BUFFERS=%d\n"
"SWAP_TOT=%d\n"
"SWAP_FREE=%d\n"
"PROCESSES=%d\n",
info.uptime,
info.loads[0],
info.loads[1],
info.loads[2],
info.totalram,
info.freeram,
(info.totalram-info.freeram)*info.mem_unit/1024,
info.sharedram,
info.bufferram,
info.totalswap,
info.freeswap,
info.procs);
}
I use it in the shell like this:
eval `sysinfo`
BEFORERAM=$MEMUSEDKB
command &
sleep .1 #sleep value may need to be adjusted depending on command's run time
eval `sysinfo`
AFTERRAM=$MEMUSEDKB
echo RAMDELTA is $(($AFTERRAM - BEFORERAM ))

Resources