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) 9799101 (which is ace) all we have to do to get it's original valie is 97 - 099 - 1101 - 2 and we will get the decoded value (which is abc)
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;
}
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