WelcomeWelcome | FAQFAQ | DownloadsDownloads | WikiWiki

Author Topic: SH loading, BASH configuraiton (during logging) and SUID not working for C files  (Read 2855 times)

Offline core-fuel

  • Newbie
  • *
  • Posts: 7
Good evening everyone.  :D

Recently I have started a project to design an intentionally vulnerable linux distro for pedagogic purposes. I know this already exists, but I wanted to create my own. Since one of the requirements of my project was for the distro to have no x (or desktop manager) and to be extremely light-weight, I decided to go with Tinycore.

I am extremely happy with how things are turning out, as Tinycore seems to be a solid piece of software, and I am learning quite a lot about a lot of Linux's functionality I always took for granted. Things like "persistance" are a treat to learn. However, I am having a few issues trying to set a secure enviroment with the proper permissions and configure certain files/applications.

For context, I want my users to have a different user than 'tc' (I call this user 'attacker_1') and a few vulnerable users (which I call 'victim_x'). Also, I have downloaded BASH, UNIX-UTILS and CORE-UTIL to give 'attacker_1' access to tools without giving them access to busybox. I know busybox.suid exists, but certain exploits depend on a traditional Linux configuration and I wanted to work in a framework I knew.

I have found myself with two BIG roadblocks:

.ROADBLOCK 1: SUID does not seem to work properly.

I read online that BASH drops SUID when it executes scripts, so I programmed and compiled my utilities in c. BASH is still dropping them from some reason. MKSH and Busybox's ASH do the exact same thing.

My program first prints the "REAL UID" and the "EFFECTIVE UID", and both of them are different. (As a matter of facts, "EFFECTIVE UID" has the UID of the program OWNER) However, when the program tries to read or modify a file under the OWNER's UID (Program: RWSR-XR-X victim_1 victim_1 <> File: RWX------ victim_1 victim_1), the computer tells that "I can not access" and "Permission denied".

Can anybody explain to me why the SUID could be failing?


.ROADBLOCK 2: I can't find a way to consistently configurate BASH.

BASH starts differently for tc than it does for attacker_1, victim_1 or root.

I have placed .ashrc and .bashrc inside every "home folder" (/root/, /home/tc, /home/attacker_1, etc) and placed a line at the end of the script to "echo <name of file>". It seems that attacker_1 and root NEVER use any of those files. On the other hand, for some weird reason, user tc seems to call the .ashrc definitions TWICE. (despite the fact I am using BASH as /bin/SH)

* My question is, which lines are responsable for "loading" the shells after loging?
* Why does tc work different than the other users?
* And is there some way I can modify this behavoiur?


I trully appreciate any help I can get. And thank you for your time. :)

class(): def __Core-fuel__(): sign_post().pretty()
« Last Edit: October 08, 2018, 08:53:04 PM by core-fuel »

Offline curaga

  • Administrator
  • Hero Member
  • *****
  • Posts: 10957
How did you make bash /bin/sh?
The only barriers that can stop you are the ones you create yourself.

Offline core-fuel

  • Newbie
  • *
  • Posts: 7
How did you make bash /bin/sh?

All 3 installations (BASH, UTIL-LINUX, COREUTILS) were made through tce-load.
With the exception of my scripts, I used everything out-of-the box.

Offline core-fuel

  • Newbie
  • *
  • Posts: 7
(I apologize for double posting, but the forum does not allow me to edit my previous post)

This is a shot in the dark but I started to wonder if maybe (maybe?) the booting+mounting processes has something to do with the blocking of SUID?

I can't find it anywhere on my instalation of Tinycore, but I am aware that a flag called NOSUID does exists. Could that be the problem?

....

Also, just to provide further context, these are the parameters of my running c function:

File location: /home/victim_1/program

Permisions:
  • /home/victim_1                                       (rwx rwx rwx victim_1 victim_1)
  • /home/victim_1/program                       (rws r-x  r-x   victim_1 victim_1)
  • /home/victim_1/secrets                         (rwx rwx ---   victim_1 victim_1)
  • /home/victim_1/secrets/password.txt (rwx rwx rwx victim_1 victim_1)

Source code:
Code: [Select]
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>

int main (void)
{
  int real = getuid();
  int euid = geteuid();
  system("ls /home/victim_1/secrets/password.txt");
  return 0;
}


Output (when run as victim_1):
Code: [Select]
The REAL UID =: 1002
The EFFECTIVE UID =: 1002
/home/victim_1/secrets/password.txt

Output (when run as attacker_1):
Code: [Select]
The REAL UID =: 1001
The EFFECTIVE UID =: 1002
ls: cannot acces '/home/victim_1/secrets/password.txt' : Permission denied

Once again, thanks for any help.  ;D

class(): def __Core-fuel__(): sign_post().pretty()

Offline polikuo

  • Hero Member
  • *****
  • Posts: 714
How did you add the other users ?

The user "tc" is added like this
Code: [Select]
addUser(){
   echo "${GREEN}Adding user ${YELLOW}$USER ${NORMAL}"
   /bin/adduser -s /bin/sh -G staff -D "$USER"
   echo "$USER":tcuser | /usr/sbin/chpasswd -m
   echo -e "$USER\tALL=NOPASSWD: ALL" >> /etc/sudoers
}

If you wanna use bash as the default shell, you should replace /bin/sh with something like /usr/local/bin/bash.

See https://github.com/tinycorelinux/Core-scripts/blob/master/etc/init.d/tc-config

Permisions:
  • /home/victim_1                                       (rwx rwx rwx victim_1 victim_1)
  • /home/victim_1/program                       (rws r-x  r-x   victim_1 victim_1)
  • /home/victim_1/secrets                         (rwx rwx ---   victim_1 victim_1)
  • /home/victim_1/secrets/password.txt (rwx rwx rwx victim_1 victim_1)

Your attacker_1 does not have the permission to access the directory /home/victim_1/secrets.
Permission -> owner: rwx, group member: rwx, anyone: --- (deny anyone)
Ownership -> creater: victim_1, group: victim_1
It can only be accessed by victim_1 itself or users who belongs group "victim_1".

Offline core-fuel

  • Newbie
  • *
  • Posts: 7
How did you add the other users ?

The user "tc" is added like this
Code: [Select]
addUser(){
   echo "${GREEN}Adding user ${YELLOW}$USER ${NORMAL}"
   /bin/adduser -s /bin/sh -G staff -D "$USER"
   echo "$USER":tcuser | /usr/sbin/chpasswd -m
   echo -e "$USER\tALL=NOPASSWD: ALL" >> /etc/sudoers
}

I used the command provided by the os, A.K.A. using sudo adduser. Since I am persisting home/ and some files in etc/ those users are saved and loaded during booting time.

If you wanna use bash as the default shell, you should replace /bin/sh with something like /usr/local/bin/bash.

I know, I Have already done that. :p


Your attacker_1 does not have the permission to access the directory /home/victim_1/secrets.
Permission -> owner: rwx, group member: rwx, anyone: --- (deny anyone)
Ownership -> creater: victim_1, group: victim_1
It can only be accessed by victim_1 itself or users who belongs group "victim_1".

That's 100% intentional. The idea is to exploit a security flaw with a badly configured executable with SUID.

The user attacker_1 should never have access to victim_1/secrets or the files inside it.
However, attacker_1 has access to "program" and "program" (owned by victim_1) runs with SUID.
So "program" should be running with victim_1's priviledges. 

It seems to be doing that (EFFECTIVE ID is victim_1's ID), but for some reason the priviledges are dropped as soon as the shell is called again.

class(): def __Core-fuel__(): sign_post().pretty()

Offline curaga

  • Administrator
  • Hero Member
  • *****
  • Posts: 10957
system() calls /bin/sh, so it sounds like you didn't replace it with bash. tce-loading bash does not make it /bin/sh.
The only barriers that can stop you are the ones you create yourself.

Offline core-fuel

  • Newbie
  • *
  • Posts: 7
First and foremost, I have advanced a little in my SETUID problem. (kind of)

Apparently I was being dumb and forgot to use setuid to make my "effective uid" into my "real uid". 
However, calling setuid() does not change the "real uid". Moreover, it doesn't even give an error. (return is 0)

Here is the code:

Code: [Select]
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>

int main (void)
{
  int real = getuid();
  int euid = geteuid();

 
  printf("real uid: %d\n", getuid());
  printf("effective uid: %d\n", geteuid());
 
  int error = setuid(euid);

  printf("setuid response : %d\n", error);
  printf("real uid: %d\n", getuid());
  printf("effective uid: %d\n", geteuid());
  printf("\n");
  setuid(real);

  return 0;

}

It returns...

Code: [Select]
setuid: 1001
effective uid: 1002
setuid response : 0
setuid: 1001
effective uid: 1002

What could be the problem here? :/

Second of all, I still can not make the log-in work properly. ):

I placed an "echo ash" and an "echo bash" inside every ".ashrc" and ".bashrc", respectively.

When logging in as "tc" it loads the .ashrc file in /home/tc... twice. I get two printings of "ash".
Also, I get all the aliases defined in ".ashrc", so it's pretty clear the file is being executed.

When I log in as "root", "attacker_1" or "victim_1", I do not get any "ash" or "bash" printing.
I don't get any of aliases either, so it's clear no file is actually being loaded.

What's even weirderer is that the user "victim_1" tries to access "/usr/bin/tty" (and returns a permission denied error)
The user "attacker_1" does not try this. ("attacker_1" does not have access to busybox either, so this would give an error)

"victim_2" and beyond load similar to tc (they open the "ashrc" file... twice) and also try to get "/usr/bin/tty".
Could this be a problem of badly configured consistence on my part?

system() calls /bin/sh, so it sounds like you didn't replace it with bash. tce-loading bash does not make it /bin/sh.

When running "ls -l /bin/*sh" I get the following results after booting up:

Code: [Select]
lrwxrwxrwx 1 root root 7 Mar 19 2018 /bin/ash -> busybox
lrwxrwxrwx 1 root root 7 Mar 19 2018 /bin/bash -> /tmp/tcloop/bash/usr/local/bin/bash
lrwxrwxrwx 1 root root 7 Mar 19 2018 /bin/fdflush -> busybox
lrwxrwxrwx 1 root root 7 Mar 19 2018 /bin/sh -> bash

Doesn't that make Bash the default SHELL?

Offline core-fuel

  • Newbie
  • *
  • Posts: 7
UPDATE 1!  ;D

I have solved my SUID problem. Apparently, it had nothing to do with tinycore at all. I tried in other machines with other versions of linux (DSL, alpine,etc.) and found myself with the exact same problem. Turns out it was something related to C's libraries and how they handle setsuid. (which happens to be POSIX complaint).

The solution was to use a different, non-POSIX complain function. (setreuid)

Now I only need to understand why the boot process is different for [attacker_1], [victim_1/root] and [victim_2/victim_3/victim_4]. I will check if removing some of the files I have been saving has anything to do with that.

EDIT:

UPDATE 2!

I am starting to get my stuff together.  :D

Apparently, the different logins are caused because I updated the /etc/skel, so older users had outdated files (in particular $HOME/.profile) while the newer ones didn't. This difference was the reason why the older log-ins to beheaved so weirdly.

Also, when a user logs in, .profile defines "$ENV=.ashrc" and then runs ". $HOME/.ashrc". However, it seems that BASH also executes ". $HOME/$ENV" when it's starting to run. By commenting that line, then .ashrc is only being executed once, which is exactly what I wanted.

Now the only issue I need to iron out is that users with no busybox priviledges have no "weird log errors" related to busybox functions called during startup (such as "which"). I believe that having no access to that call makes the program beheave, a few edits here and there should make everything beheave properly.
« Last Edit: October 09, 2018, 02:54:34 PM by core-fuel »