Level09
Obfuscated token
when we login as level08 user we are given 2 files :
level09@SnowCrash:~$ ls -l
total 12
-rwsr-sr-x 1 flag09 level09 7640 Mar 5 2016 level09
----r--r-- 1 flag09 level09 26 Mar 5 2016 token
Here we can read the file token and we can see :
level09@SnowCrash:~$ cat token
f4kmm6p|=�p�n��DB�Du{��
We alse have a binary file called level09 when we execute it we get :
level09@SnowCrash:~$ ./level09
You need to provied only one arg.
It expect an argument, so when we provide an argument where is what we get :
level09@SnowCrash:~$ ./level09 token
tpmhr
level09@SnowCrash:~$ ./level09 ""
level09@SnowCrash:~$ ./level09 "123456789"
13579;=?A
level09@SnowCrash:~$ ./level09 "abcdefgh"
acegikmo
level09@SnowCrash:~$ ./level09 "1234567890abcdefghijklmnopqrstuvwxyz"
13579;=?A9kmoqsuwy{}���������������
when we provided the argument 123456789
we got 13579;=?A and when we provided abcdefgh
we got acegikmo Just by looking at it we can see that each character is the result of the character code + the position.
So for abcdefgh
we will have :
Position | 0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 |
---------------------------------
Char | a | b | c | d | e | f | g | h |
---------------------------------
Char code |97 |98 |99 |100|101|102|103|104|
Befor | After
---------------------
( 97) a + 0 : a ( 97)
( 98) b + 1 : c ( 99)
( 99) c + 2 : e (101)
(100) d + 3 : g (103)
(101) e + 4 : i (105)
(102) f + 5 : k (107)
(103) g + 6 : m (109)
(104) h + 7 : o (111)
From here we can guess that it is possible that the data in the file token might have been encoded using this technique.
To decode the data all we have to do is just remove the value of position from the value in question.
So if we have have the following Ascii code (in the following order) 97
99
101
(which is a
c
e)
all we have to do to get it's original valie is 97 - 0
99 - 1
101 - 2
and we will get the decoded value (which is a
b
c
)
Here is a simple program that can decode any value encoded using the above technique :
int main(int argc, char **argv)
{
char *arg;
int i = 0;
if(argc != 2)
{
fprintf(stderr, "[-] Only one argument is accepted\n");
return 1;
}
arg = argv[1];
while(*arg)
{
printf("%c", *arg - i);
i++;
arg++;
}
printf("\n");
return 0;
}
If we can use the above progran as following :
level09@SnowCrash:~$ ls
level09 token
level09@SnowCrash:~$ cat token | xargs /tmp/decode
f3iji1ju5yuevaus41q1afiuq
For me the following command did not work to compile the file decode.c located in /tmp/
directory :
level09@SnowCrash:~$ gcc /tmp/decode.c -o /tmp/decode
Cannot create temporary file in ./: Permission denied
Aborted (core dumped)
To solve the problem i changed the current directory to /tmp/
and then compiled :
level09@SnowCrash:~$ cd /tmp
level09@SnowCrash:/tmp$ gcc decode.c -o decode
Password for next level
So the Password to connect to the account level10 is s5cAJpM8ev6XHw998pRWG728z
Command summery
## Befor doing the folloing create the decode program and compile it
## then use that file to decode it
level09@SnowCrash:~$ cat token | xargs /tmp/decode
f3iji1ju5yuevaus41q1afiuq
## Log into the user flag09 to get the password for level09
level09@SnowCrash:~$ su flag09
Password: quif5eloekouj29ke0vouxean
## Get the password for level10
flag09@SnowCrash:~$ getflag
Check flag.Here is your token : s5cAJpM8ev6XHw998pRWG728z
Alternative method
If you do decide to decompile the level09 binary here is what you will get. I have cleaned the data to make it more readable :
char * __arg = argv[1];
char * v9 = (char *)-1;
while (true)
{
uint32_t i = (int32_t)v9 + 1; // at first it's 0
int32_t arg = *__arg;
int32_t dec = -1;
int32_t v13;
/* if argv[1] is : [ABCD] */
while (true)
{
negative_lenth = 0;
/* We are counting the number of characters */
if (dec != 0)
{
/* If we have reached the end of string */
if (*arg == 0)
{
negative_lenth = dec - 1;
break;
}
arg++;
dec--;
continue;
}
/* If the argument string is empty print '\n' */
if (i >= -2 - negative_lenth)
{
int32_t fputc_rc = fputc('\n', stdout);
if (__readgsdword(20) == v1)
return (fputc_rc);
return (int32_t)&v2;
}
lab_0x8048975:
/* Here is where the encoding is happening */
putchar(__arg[i] + i);
v9 = (char *)i;
break;
}
if (i < -2 - negative_lenth)
goto lab_0x8048975;
fputc('\n', stdout);
}
//
// This file was generated by the Retargetable Decompiler
// Website: https://retdec.com
// Copyright (c) 2020 Retargetable Decompiler <info@retdec.com>
//
#include <fcntl.h>
#include <stdbool.h>
#include <stdint.h>
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
// ------------------------ Structures ------------------------
struct _IO_FILE {
int32_t e0;
};
// ------------------- Function Prototypes --------------------
int32_t afterSubstr(char * a1, int32_t a2);
int32_t function_80484a0(char * file, int32_t oflag, ...);
int32_t isLib(int32_t a1, int32_t a2);
int32_t syscall_gets(char * a1, int32_t a2, int32_t fd);
int32_t syscall_open(int32_t a1, int32_t a2);
// --------------------- Global Variables ---------------------
int g1 = 0; // ebx
int g2 = 0; // esi
char (*g3)[5] = ".so\n";
struct _IO_FILE * g4 = stderr;
int32_t g5 = stdout;
// ------------------------ Functions -------------------------
// Address range: 0x80484a0 - 0x80484a6
int32_t function_80484a0(char * file, int32_t oflag, ...)
{
// 0x80484a0
int32_t * path;
return open((int32_t )&path, (int32_t )&path, (int32_t )&path);
}
// Address range: 0x80485a4 - 0x80485d4
int32_t syscall_open(char *file, int32_t a2)
{
int32_t oflag = g1; // 0x80485a8
int32_t fd = open(-1, oflag, g2); // 0x80485c3
g1 = oflag;
return fd;
}
// Address range: 0x80485d4 - 0x8048646
int32_t syscall_gets(char * __buffer, int32_t len, int32_t fd)
{
char *buffer = __buffer;
int32_t i = 0;
while (i < len)
{
/* If read didn't stop */
if (read(fd, &(buffer[i]), 1) == 1)
{
/* If user pressed '\n' (newline) */
if (buffer[i] == '\n')
break;
i += 1;
continue;
}
buffer[i] = '\0';
return i;
}
buffer[i] = '\0';
return i;
}
// Address range: 0x8048646 - 0x80486cb
int32_t afterSubstr(char * a1, int32_t a2)
{
int32_t result = 0;
if (*a1 != 0)
{
char *v1 = a1; // 0x80486a929
int32_t v2;
int32_t v3; // 0x8048688
int32_t v4; // 0x80486a5
while (true)
{
int32_t v5 = 0;
int32_t v6 = 1;
while (true)
{
char * v7 = (char *)(v5 + a2);
int32_t v8 = v1;
int32_t v9 = v6;
int32_t v10 = v5;
if (*v7 != 0)
{
char v11 = *(char *)(v5 + v1);
v2 = *v7 == v11 ? v6 : 0;
v3 = v5 + 1;
if (v2 != 1)
break;
v5 = v3;
v6 = v2;
continue;
}
if (v9 != 0)
return v10 + v8;
}
v4 = v1 + 1;
if (*(char *)v4 == 0)
break;
v1 = v4;
}
if (v2 != 0)
result = v3 + v4;
else
result = 0;
}
// 0x80486c9
return result;
}
// Address range: 0x80486cb - 0x80487ce
int32_t isLib(char *a1, int32_t a2)
{
int32_t v1 = afterSubstr((char *)a1, a2); // 0x80486de
if (v1 == 0)
return 0;
int32_t result;
if (*(char *)v1 == 45)
{
int32_t v2 = 0;
while (true)
{
int32_t v3 = v1 + 1;
char * v4 = (char *)v3;
if (*v4 > 47)
{
if (*v4 > 57)
break;
v1 = v3;
v2 = 1;
continue;
}
if (v2 != 0)
{
if (*v4 == 46)
{
int32_t v5 = 0;
while (true)
{
int32_t v6 = v3 + 1;
char * v7 = (char *)v6;
if (*v7 > 47)
{
if (*v7 > 57)
break;
v3 = v6;
v5 = 1;
continue;
}
if (v5 == 0)
return 0;
int32_t v8 = *(int32_t *)&g3;
char * v9 = (char *)v8;
if (*v9 == 0)
return (1);
int32_t v10 = 0;
while (true)
{
if (*v9 != *(char *)(v10 + v6))
return 0;
int32_t v11 = v10 + 1; // 0x80487b1
char * v12 = (char *)(v11 + v8); // 0x80487c0
if (*v12 == 0)
break;
v9 = v12;
v10 = v11;
}
return (1);
}
}
}
return (0);
}
}
else
result = 0;
return (result);
}
int main(int argc, char ** argv)
{
int32_t v1 = __readgsdword(20); // 0x80487e3
int result; // 0x8048a92
int32_t * v2;
/* Open the file and get the file fd */
int32_t map_fd = syscall_open("/proc/self/maps", 0);
/* If no error */
if (map_fd != -1)
{
char *__buffer;
char __buffer_ptr = __buffer;
bool v6 = true;
while (true)
{
while (true)
{
if (syscall_gets(__buffer, 256, map_fd) != 0)
{
int32_t v7 = isLib(__buffer_ptr, "libc"); // 0x8048930
if (v6 == true || v7 != 0)
{
v6 = v7 == 0;
break;
}
else
{
if (isLib(__buffer_ptr, (int32_t)"ld") != 0)
{
int32_t items_written;
if (argc != 2)
items_written = fwrite("You need to provied only one arg.\n", sizeof(char), 34, stderr);
else
{
/* Main program */
char * __arg = argv[1];
char * v9 = (char *)-1;
while (true)
{
uint32_t i = (int32_t)v9 + 1; // at first it's 0
int32_t arg = *__arg;
int32_t dec = -1;
int32_t v13;
/* if argv[1] is : [ABCD] */
while (true)
{
negative_lenth = 0;
/* We are counting the number of characters */
if (dec != 0)
{
/* If we have reached the end of string */
if (*arg == 0)
{
negative_lenth = dec - 1;
break;
}
arg++;
dec--;
continue;
}
/* If the argument string is empty print '\n' */
if (i >= -2 - negative_lenth)
{
int32_t fputc_rc = fputc('\n', stdout);
if (__readgsdword(20) == v1)
return (fputc_rc);
return (int32_t)&v2;
}
lab_0x8048975:
/* Here is where the encoding is happening */
putchar(__arg[i] + i);
v9 = (char *)i;
break;
}
if (i < -2 - negative_lenth)
goto lab_0x8048975;
fputc('\n', stdout);
}
/* End of main program here */
}
if (__readgsdword(20) == v1)
return items_written;
return (int32_t)&v2;
}
if (afterSubstr((char *)&__buffer, (int32_t)"00000000 00:00 0") == 0)
break;
continue;
}
}
}
}
}
else
fwrite((int32_t *)"/proc/self/maps is unaccessible, probably a LD_PRELOAD attempt exit..\n", sizeof(char), 70, stderr);
// 0x8048a77
if (__readgsdword(20) == v1)
result = 1;
else
{
__stack_chk_fail();
result = (int32_t)&v2;
}
return result;
}
// --------------- Dynamically Linked Functions ---------------
// void __stack_chk_fail(void);
// int fputc(int c, FILE * stream);
// size_t fwrite(const void * restrict ptr, size_t size, size_t n, FILE * restrict s);
// char * getenv(const char * name);
// long int ptrace(enum __ptracerequest __request, ...);
// int putchar(int c);
// int puts(const char * s);
// ------------------ System-Call Functions -------------------
// int32_t open(int32_t a1, int32_t a2, int32_t a3);
// ssize_t read(int fd, void * buf, size_t nbytes);
// --------------------- Meta-Information ---------------------
// Detected compiler/packer: gcc (4.5.x)
// Detected functions: 6
// Decompilation date: 2020-01-22 10:54:15
//
// This file was generated by the Retargetable Decompiler
// Website: https://retdec.com
// Copyright (c) 2020 Retargetable Decompiler <info@retdec.com>
//
#include <fcntl.h>
#include <stdbool.h>
#include <stdint.h>
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
// ------------------------ Structures ------------------------
struct _IO_FILE {
int32_t e0;
};
// ------------------- Function Prototypes --------------------
int32_t afterSubstr(char * a1, int32_t a2);
int32_t function_80484a0(char * file, int32_t oflag, ...);
int32_t isLib(int32_t a1, int32_t a2);
int32_t syscall_gets(char * a1, int32_t a2, int32_t fd);
int32_t syscall_open(int32_t a1, int32_t a2);
// --------------------- Global Variables ---------------------
int32_t g1 = 0; // ebx
int32_t g2 = 0; // esi
char (*g3)[5] = ".so\n";
struct _IO_FILE * g4 = NULL;
int32_t g5 = 0;
// ------------------------ Functions -------------------------
// Address range: 0x80484a0 - 0x80484a6
int32_t function_80484a0(char * file, int32_t oflag, ...) {
// 0x80484a0
int32_t * path;
return open((int32_t)&path, (int32_t)&path, (int32_t)&path);
}
// Address range: 0x80485a4 - 0x80485d4
int32_t syscall_open(int32_t a1, int32_t a2) {
int32_t oflag = g1; // 0x80485a8
int32_t fd = open(-1, oflag, g2); // 0x80485c3
g1 = oflag;
return fd;
}
// Address range: 0x80485d4 - 0x8048646
int32_t syscall_gets(char * a1, int32_t a2, int32_t fd) {
int32_t v1 = g1; // 0x80485d8
int32_t v2 = (int32_t)a1; // 0x80485e8
int32_t v3 = 0;
// branch -> 0x8048623
int32_t result;
while (true) {
// 0x8048623
result = v3;
if (a2 - 1 <= v3) {
// 0x8048631
*(char *)(result + v2) = 0;
g1 = v1;
return result;
}
int32_t buf = v3 + v2; // 0x80485eb
if (read(fd, (int32_t *)buf, 1) == 1) {
int32_t v4 = v3 + 1; // 0x804861f
if (*(char *)buf == 10) {
result = v4;
// break -> 0x8048631
break;
}
v3 = v4;
// continue -> 0x8048623
continue;
} else {
result = v3;
}
// 0x8048631
*(char *)(result + v2) = 0;
g1 = v1;
return result;
}
// 0x8048631
*(char *)(result + v2) = 0;
g1 = v1;
return result;
}
// Address range: 0x8048646 - 0x80486cb
int32_t afterSubstr(char * a1, int32_t a2) {
int32_t result = 0;
if (*a1 != 0) {
int32_t v1 = (int32_t)a1; // 0x80486a929
int32_t v2;
int32_t v3; // 0x8048688
int32_t v4; // 0x80486a5
while (true) {
int32_t v5 = 0;
int32_t v6 = 1;
// branch -> 0x8048692
while (true) {
char * v7 = (char *)(v5 + a2); // 0x8048698
int32_t v8 = v1; // 0x80486a913
int32_t v9 = v6;
int32_t v10 = v5;
if (*v7 != 0) {
char v11 = *(char *)(v5 + v1); // 0x804867a
v2 = *v7 == v11 ? v6 : 0;
v3 = v5 + 1;
if (v2 != 1) {
// break -> 0x80486a5
break;
}
v5 = v3;
v6 = v2;
// continue -> 0x8048692
continue;
}
// 0x80486b6
if (v9 != 0) {
// 0x80486c3
// branch -> 0x80486c9
// 0x80486c9
return v10 + v8;
}
}
// 0x80486a5
v4 = v1 + 1;
if (*(char *)v4 == 0) {
// break -> 0x80486b6
break;
}
v1 = v4;
// continue -> 0x804868c
}
// 0x80486b6
if (v2 != 0) {
// 0x80486c3
result = v3 + v4;
// branch -> 0x80486c9
} else {
result = 0;
}
}
// 0x80486c9
return result;
}
// Address range: 0x80486cb - 0x80487ce
int32_t isLib(int32_t a1, int32_t a2) {
int32_t v1 = afterSubstr((char *)a1, a2); // 0x80486de
if (v1 == 0) {
// 0x80486ec
// branch -> 0x80487cc
// 0x80487cc
return 0;
}
// 0x80486f6
int32_t result; // 0x80487cd
if (*(char *)v1 == 45) {
int32_t v2 = 0;
while (true) {
int32_t v3 = v1 + 1;
char * v4 = (char *)v3;
if (*v4 > 47) {
// 0x804872c
if (*v4 > 57) {
// break -> 0x8048736
break;
}
v1 = v3;
v2 = 1;
// continue -> 0x8048722
continue;
}
// 0x8048736
if (v2 != 0) {
// 0x804873c
if (*v4 == 46) {
int32_t v5 = 0;
while (true) {
int32_t v6 = v3 + 1;
char * v7 = (char *)v6;
if (*v7 > 47) {
// 0x804876f
if (*v7 > 57) {
// break -> 0x8048779
break;
}
v3 = v6;
v5 = 1;
// continue -> 0x8048765
continue;
}
// 0x8048779
if (v5 == 0) {
// 0x804877f
// branch -> 0x80487cc
// 0x80487cc
return 0;
}
int32_t v8 = *(int32_t *)&g3;
char * v9 = (char *)v8; // 0x80487c051
if (*v9 == 0) {
// 0x80487c7
// branch -> 0x80487cc
// 0x80487cc
return 1;
}
int32_t v10 = 0; // 0x80487bb56
while (true) {
// 0x804878f
if (*v9 != *(char *)(v10 + v6)) {
// 0x80487aa
// branch -> 0x80487cc
// 0x80487cc
return 0;
}
int32_t v11 = v10 + 1; // 0x80487b1
char * v12 = (char *)(v11 + v8); // 0x80487c0
if (*v12 == 0) {
// break -> 0x80487c7
break;
}
v9 = v12;
v10 = v11;
// continue -> 0x804878f
}
// 0x80487c7
// branch -> 0x80487cc
// 0x80487cc
return 1;
}
}
}
// 0x8048746
// branch -> 0x80487cc
// 0x80487cc
return 0;
}
} else {
// 0x8048700
result = 0;
// branch -> 0x80487cc
}
// 0x80487cc
return result;
}
// Address range: 0x80487ce - 0x8048a93
int main(int argc, char ** argv) {
int32_t v1 = __readgsdword(20); // 0x80487e3
int32_t result; // 0x8048a92
int32_t * v2;
if (ptrace(0) < 0) {
// 0x804882a
puts("You should not reverse this");
// branch -> 0x8048a77
// 0x8048a77
if (__readgsdword(20) == v1) {
// 0x8048a77
result = 1;
// branch -> 0x8048a8c
} else {
// 0x8048a87
__stack_chk_fail();
result = (int32_t)&v2;
// branch -> 0x8048a8c
}
// 0x8048a8c
return result;
}
// 0x8048840
if (getenv("LD_PRELOAD") != NULL || function_80484a0("/etc/ld.so.preload", 0) >= 1) {
// 0x8048850
fwrite((int32_t *)"Injection Linked lib detected exit..\n", 1, 37, g4);
// branch -> 0x8048a77
// 0x8048a77
if (__readgsdword(20) == v1) {
// 0x8048a77
result = 1;
// branch -> 0x8048a8c
} else {
// 0x8048a87
__stack_chk_fail();
result = (int32_t)&v2;
// branch -> 0x8048a8c
}
// 0x8048a8c
return result;
}
int32_t v3 = syscall_open((int32_t)"/proc/self/maps", 0); // 0x80488db
if (v3 != -1) {
// 0x8048a51
int32_t v4; // bp-276
int32_t v5 = &v4; // 0x8048a61
bool v6 = true;
// branch -> 0x8048a51
while (true) {
// 0x8048a51
// branch -> 0x8048a51
while (true) {
// 0x8048a51
if (syscall_gets((char *)&v4, 256, v3) != 0) {
int32_t v7 = isLib(v5, (int32_t)"libc"); // 0x8048930
if (v6 || v7 != 0) {
// 0x8048a51
v6 = v7 == 0;
// branch -> 0x8048a51
break;
} else {
// 0x8048951
if (isLib(v5, (int32_t)"ld") != 0) {
// 0x804896d
int32_t items_written; // eax
if (argc != 2) {
// 0x80489e4
items_written = fwrite((int32_t *)"You need to provied only one arg.\n", 1, 34, g4);
// branch -> 0x8048a77
} else {
int32_t * v8 = (int32_t *)((int32_t)argv + 4); // 0x80489a6
char * v9 = (char *)-1;
// branch -> 0x8048996
while (true) {
uint32_t v10 = (int32_t)v9 + 1; // 0x8048996
int32_t v11 = *v8; // 0x80489bd
int32_t v12 = -1; // 0x80489bd
// branch -> bb
int32_t v13; // 0x80489bf
while (true) {
// bb
v13 = 0;
if (v12 != 0) {
int32_t v14 = 1 + v11; // 0x80489bd
int32_t v15 = v12 - 1; // 0x80489bd
if (*(char *)v11 == 0) {
v13 = v15;
// break -> bb273
break;
}
v11 = v14;
v12 = v15;
// continue -> bb
continue;
}
// bb273
if (v10 >= -2 - v13) {
int32_t fputc_rc = fputc(10, (struct _IO_FILE *)g5); // 0x80489da
// branch -> 0x8048a77
// 0x8048a77
if (__readgsdword(20) == v1) {
// 0x8048a77
// branch -> 0x8048a8c
// 0x8048a8c
return fputc_rc;
}
// 0x8048a87
__stack_chk_fail();
// branch -> 0x8048a8c
// 0x8048a8c
return (int32_t)&v2;
}
lab_0x8048975:
// 0x8048975
putchar((int32_t)*(char *)(*v8 + v10) + v10);
v9 = (char *)v10;
// branch -> 0x8048996
break;
}
// bb273
if (v10 < -2 - v13) {
goto lab_0x8048975;
}
// 0x80489ca
fputc(10, (struct _IO_FILE *)g5);
// branch -> 0x8048a77
}
}
// 0x8048a77
if (__readgsdword(20) == v1) {
// 0x8048a77
// branch -> 0x8048a8c
// 0x8048a8c
return items_written;
}
// 0x8048a87
__stack_chk_fail();
// branch -> 0x8048a8c
// 0x8048a8c
return (int32_t)&v2;
}
// 0x8048a0e
if (afterSubstr((char *)&v4, (int32_t)"00000000 00:00 0") == 0) {
// break -> 0x8048a26
break;
}
// continue -> 0x8048a51
continue;
}
}
}
}
} else {
// 0x80488ef
fwrite((int32_t *)"/proc/self/maps is unaccessible, probably a LD_PRELOAD attempt exit..\n", 1, 70, g4);
// branch -> 0x8048a77
}
// 0x8048a77
if (__readgsdword(20) == v1) {
// 0x8048a77
result = 1;
// branch -> 0x8048a8c
} else {
// 0x8048a87
__stack_chk_fail();
result = (int32_t)&v2;
// branch -> 0x8048a8c
}
// 0x8048a8c
return result;
}
// --------------- Dynamically Linked Functions ---------------
// void __stack_chk_fail(void);
// int fputc(int c, FILE * stream);
// size_t fwrite(const void * restrict ptr, size_t size, size_t n, FILE * restrict s);
// char * getenv(const char * name);
// long int ptrace(enum __ptracerequest __request, ...);
// int putchar(int c);
// int puts(const char * s);
// ------------------ System-Call Functions -------------------
// int32_t open(int32_t a1, int32_t a2, int32_t a3);
// ssize_t read(int fd, void * buf, size_t nbytes);
// --------------------- Meta-Information ---------------------
// Detected compiler/packer: gcc (4.5.x)
// Detected functions: 6
// Decompilation date: 2020-01-23 04:00:46
Last updated
Was this helpful?