Tag Archive: linux


openSSH chaos

The other day I was asked about the best way to configure the permissions/ownership of the SSH auth_keys file.

There’s a lot of controversy around this topic and the usual method “I’ll look what Google says” doesn’t help very much in this case. There are a lot of references of technical blogs which recommend opposite solutions… Well, we all know how reliable are personal techie blogs, don’t we? ;)

When dealing with opensource and having a very specific question is better to check the source code

Having an error message, like it was the case, helps by allowing us to grep.

carlos@ubuntu-server-1:~/code/openssh-5.1p1$ grep -in “bad ownership or modes for directory” *
auth.c:454:                         “bad ownership or modes for directory %s”, buf);

From openssh-5.1p1′s auth.c:

/*
* Check a given file for security. This is defined as all components
* of the path to the file must be owned by either the owner of
* of the file or root and no directories must be group or world writable.

*
* XXX Should any specific check be done for sym links ?
*
* Takes an open file descriptor, the file name, a uid and and
* error buffer plus max size as arguments.
*
* Returns 0 on success and -1 on failure
*/
static int
secure_filename(FILE *f, const char *file, struct passwd *pw,
char *err, size_t errlen)
{
uid_t uid = pw->pw_uid;
char buf[MAXPATHLEN], homedir[MAXPATHLEN];
char *cp;
int comparehome = 0;
struct stat st;

if (realpath(file, buf) == NULL) {
snprintf(err, errlen, “realpath %s failed: %s”, file,
strerror(errno));
return -1;
}
if (realpath(pw->pw_dir, homedir) != NULL)
comparehome = 1;

/* check the open file to avoid races */
if (fstat(fileno(f), &st) < 0 ||
(st.st_uid != 0 && st.st_uid != uid) ||
(st.st_mode & 022) != 0) {
snprintf(err, errlen, “bad ownership or modes for file %s”,
buf);
return -1;
}

/* for each component of the canonical path, walking upwards */
for (;;) {                                                                         // An infite loop :-S
if ((cp = dirname(buf)) == NULL) {                                     // strips the non-directory parts
snprintf(err, errlen, “dirname() failed”);
return -1;                                                              // this breaks the infinite loop
}
strlcpy(buf, cp, sizeof(buf));                                                  // kind of strncpy() but BSD compatible

debug3(“secure_filename: checking ‘%s’”, buf);             // “buf” contains the directory name now
if (stat(buf, &st) < 0 ||                                                // reads dir’s info and places into structure
(st.st_uid != 0 && st.st_uid != uid) ||                                 // and here is the check we’re looking for :)
(st.st_mode & 022) != 0) {
snprintf(err, errlen,
bad ownership or modes for directory %s”, buf);
return -1;
}

[...]
return 0;
}

Also if

st.st_uid != 0 && st.st_uid != uid

we have a problem. That means the UID of the directory’s owner must be either the file’s owner itself or an user with UID 0 (root and alike) for every directory all along the descendent path.

Another good example of the geek maxim: “Use the source, Luke” ;)

Playing with gdb. Reverse engineer your way.

Playing a very basic level of a known wargame the other day I was trying to solve the following problem:

Given an executable (ELF, Linux) which accepts a password as an argument and verifies if this is correct, find this string. As most of the problems, it’s quite easy if you have the right tools (and knowledge of course).
Anyway, I thought the solution(s) would make a nice blog entry, so here it is!

In order to play around with it in my own Ubuntu, I wrote a very simple C program, named pass_cli.c


carlos@dell:~/Dropbox/hacking/wargames$ cat pass_cli.c
#include <stdio.h>
#include <string.h>
#include <stdlib.h>

int
main(int argc, char **argv)
{
char password[] = “yomama”;

if(argc < 2)
{
printf(“Usage: %s <password>\n”, argv[0]);
exit(1);
}

if(strncmp(argv[1], password, strlen(password)))
{
printf(“FAIL\n”);
exit(1);
} else {

printf(“WIN\n”);
return(0);
}

return(0); // never reached :)

}

I compiled the program with no special options.

carlos@dell:~/Dropbox/hacking/wargames$ file pass_cli
pass_cli: ELF 32-bit LSB executable, Intel 80386, version 1 (SYSV), dynamically linked (uses shared libs), for GNU/Linux 2.6.15, not stripped

A first tool of the trade when you are looking for strings in a binary is strings, which will look for strings of printable characters inside the binary.

carlos@dell:~/Dropbox/hacking/wargames$ strings pass_cli
/lib/ld-linux.so.2
`:6K*
__gmon_start__
libc.so.6
_IO_stdin_used
exit
strncmp
puts
printf
strlen
__libc_start_main
GLIBC_2.0
PTRh`
yomaf
[^_]
Usage: %s <password>
FAIL

Well, we cannot find the password here (and even if it were displayed here, how could you identify it?) but that gave us some preliminar information about the program. We can see some familiar libc functions (printf, strlen, strncmp, etc.), strncmp will be of interest a bit later.

Another method you could have tried is for example to dump the contents of the .text section inside the binary. This is actually the same idea behind the use of strings, just a lot messier ;)
Remember that the .text section of a binary contains the machine instructions (the compiled code) but that doesn’t mean the strings are neccesarily stored in a readable way. Anyway we could check the contents of this section with the help of objdump.

carlos@dell:~/Dropbox/hacking/wargames$ objdump
Usage: objdump <option(s)> <file(s)>
Display information from object <file(s)>.
At least one of the following switches must be given:
-a, –archive-headers    Display archive header information
-f, –file-headers       Display the contents of the overall file header
-p, –private-headers    Display object format specific file header contents
-h, –[section-]headers  Display the contents of the section headers
-x, –all-headers        Display the contents of all headers
-d, –disassemble        Display assembler contents of executable sections
-D, –disassemble-all    Display assembler contents of all sections
-S, –source             Intermix source code with disassembly
-s, –full-contents      Display the full contents of all sections requested
-g, –debugging          Display debug information in object file
-e, –debugging-tags     Display debug information using ctags style
-G, –stabs              Display (in raw form) any STABS info in the file
-W[lLiaprmfFsoR] or
–dwarf[=rawline,=decodedline,=info,=abbrev,=pubnames,=aranges,=macro,=frames,=str,=loc,=Ranges]
Display DWARF info in the file
-t, –syms               Display the contents of the symbol table(s)
-T, –dynamic-syms       Display the contents of the dynamic symbol table
-r, –reloc              Display the relocation entries in the file
-R, –dynamic-reloc      Display the dynamic relocation entries in the file
@<file>                  Read options from <file>
-v, –version            Display this program’s version number
-i, –info               List object formats and architectures supported
-H, –help               Display this information

carlos@dell:~/Dropbox/hacking/wargames$ objdump -h pass_cli

pass_cli:     file format elf32-i386

Sections:
Idx Name          Size      VMA       LMA       File off  Algn
0 .interp       00000013  08048134  08048134  00000134  2**0
CONTENTS, ALLOC, LOAD, READONLY, DATA
1 .note.ABI-tag 00000020  08048148  08048148  00000148  2**2
CONTENTS, ALLOC, LOAD, READONLY, DATA

[...]

11 .init         00000030  0804834c  0804834c  0000034c  2**2
CONTENTS, ALLOC, LOAD, READONLY, CODE
12 .plt          00000080  0804837c  0804837c  0000037c  2**2
CONTENTS, ALLOC, LOAD, READONLY, CODE
13 .text         000001fc  08048400  08048400  00000400  2**4   <—- here
CONTENTS, ALLOC, LOAD, READONLY, CODE
14 .fini         0000001c  080485fc  080485fc  000005fc  2**2
CONTENTS, ALLOC, LOAD, READONLY, CODE

[...]

This section starts at the address 0×08048400, that is, the offset is 0×400 (the start virtual address is 0×08048000)

Armed with this knowledge we could hexdump this section and manually inspect it

carlos@dell:~/Dropbox/hacking/wargames$ hexdump -C -s 0×400 pass_cli | less

00000400  31 ed 5e 89 e1 83 e4 f0  50 54 52 68 60 85 04 08  |1.^…..PTRh`…|
00000410  68 70 85 04 08 51 56 68  b4 84 04 08 e8 7b ff ff  |hp…QVh…..{..|
[...]
000004a0  00 00 00 00 85 c0 74 09  c7 04 24 1c 9f 04 08 ff  |……t…$…..|
000004b0  d0 c9 c3 90 55 89 e5 83  e4 f0 83 ec 20 c7 44 24  |….U……. .D$|
000004c0  19 79 6f 6d 61 66 c7 44  24 1d 6d 61 c6 44 24 1f  |.yomaf.D$.ma.D$.| <—   :(
000004d0  00 83 7d 08 01 7f 22 8b  45 0c 8b 10 b8 20 86 04  |..}…”.E…. ..|
000004e0  08 89 54 24 04 89 04 24  e8 cf fe ff ff c7 04 24  |..T$…$…….$|
[...]
00000600  83 ec 04 e8 00 00 00 00  5b 81 c3 ec 19 00 00 e8  |……..[.......|
00000610  1c fe ff ff 59 5b c9 c3  03 00 00 00 01 00 02 00  |....Y[..........|
00000620  55 73 61 67 65 3a 20 25  73 20 3c 70 61 73 73 77  |Usage: %s <passw|
00000630  6f 72 64 3e 0a 00 46 41  49 4c 00 57 49 4e 00 00  |ord>..FAIL.WIN..|
00000640  00 00 00 00 00 00 00 00  00 00 00 00 00 00 00 00  |................|

As we can see, the string isn't stored in a readable format, as expected :(
A very useful tool in this case is "ltrace" for we can monitor every system call (with the corresponding arguments!)

carlos@dell:~/Dropbox/hacking/wargames$ ltrace ./pass_cli AAAAA
__libc_start_main(0x80484b4, 2, 0xbf952854, 0x8048570, 0x8048560 <unfinished ...>
strlen("yomama")                                                   = 6
strncmp("AAAAA", "yomama", 6)                                      = -1      <--- TA-DA!!!! :)
puts("FAIL"FAIL
)                                                       = 5
exit(1 <unfinished ...>
+++ exited (status 1) +++

But what if our system doesn't have this tool? Then we have to take the heavy weapons and perform some elegant debugging :)

carlos@dell:~/Dropbox/hacking/wargames$ objdump -T pass_cli

pass_cli:     file format elf32-i386

DYNAMIC SYMBOL TABLE:
00000000  w   D  *UND*  00000000              __gmon_start__
00000000      DF *UND*  00000000  GLIBC_2.0   __libc_start_main
00000000      DF *UND*  00000000  GLIBC_2.0   strlen
00000000      DF *UND*  00000000  GLIBC_2.0   printf
00000000      DF *UND*  00000000  GLIBC_2.0   puts
00000000      DF *UND*  00000000  GLIBC_2.0   strncmp     <---- idea!
00000000      DF *UND*  00000000  GLIBC_2.0   exit
0804861c g    DO .rodata        00000004  Base        _IO_stdin_used

We have very good reasons to suspect that strncmp is being used to check our input against the password so let's start the program in gdb and quickly disassemble it in order to localize the call to strncmp.

carlos@dell:~/Dropbox/hacking/wargames$ gdb -q ./pass_cli
Reading symbols from /home/carlos/Dropbox/hacking/wargames/pass_cli...(no debugging symbols found)...done.

(gdb) set disassembly-flavor intel <---- PLEASE ;)
(gdb) disass main
Dump of assembler code for function main:
0x080484b4 <+0>: push ebp
0x080484b5 <+1>: mov ebp,esp
0x080484b7 <+3>: and esp,0xfffffff0
0x080484ba <+6>: sub esp,0x20
0x080484bd <+9>: mov DWORD PTR [esp+0x19],0x616d6f79
0x080484c5 <+17>: mov WORD PTR [esp+0x1d],0x616d
0x080484cc <+24>: mov BYTE PTR [esp+0x1f],0×0
0x080484d1 <+29>: cmp DWORD PTR [ebp+0x8],0×1
0x080484d5 <+33>: jg 0x80484f9
0x080484d7 <+35>: mov eax,DWORD PTR [ebp+0xc]
0x080484da <+38>: mov edx,DWORD PTR [eax]
0x080484dc <+40>: mov eax,0×8048620
0x080484e1 <+45>: mov DWORD PTR [esp+0x4],edx
0x080484e5 <+49>: mov DWORD PTR [esp],eax
0x080484e8 <+52>: call 0x80483bc
0x080484ed <+57>: mov DWORD PTR [esp],0×1
0x080484f4 <+64>: call 0x80483ec
0x080484f9 <+69>: lea eax,[esp+0x19]
0x080484fd <+73>: mov DWORD PTR [esp],eax
0×08048500 <+76>: call 0x80483ac
0×08048505 <+81>: mov edx,eax
0×08048507 <+83>: mov eax,DWORD PTR [ebp+0xc]
0x0804850a <+86>: add eax,0×4
0x0804850d <+89>: mov eax,DWORD PTR [eax]
0x0804850f <+91>: mov DWORD PTR [esp+0x8],edx
0×08048513 <+95>: lea edx,[esp+0x19]
0×08048517 <+99>: mov DWORD PTR [esp+0x4],edx
0x0804851b <+103>: mov DWORD PTR [esp],eax
0x0804851e <+106>: call 0x80483dc
0×08048523 <+111>: test eax,eax
0×08048525 <+113>: je 0x804853f
0×08048527 <+115>: mov DWORD PTR [esp],0×8048636
[...]

Now I will place a breakpoint exactly on the address of this call instruction.

(gdb) b *0x0804851e
Breakpoint 1 at 0x804851e

Remember to use the asterisk (*) right in front of the address, so gdb understands what follows isn’t a literal.

Why did I do it this way? Think about it the other way. What happens when the call instruction is executed? The whole stack frame stup parafernalia, namely

  • EIP is pushed to the stack (by the call itself)
  • The function prologue is executed, that is
  • the current value of EBP is pushed to the stack (from now on, known as SFP)
  • the current value of ESP passes to be the new EBP (“a new stack frame starts here”)
  • a value is subtracted from ESP (to allocate space for local variables)

That is too messy to keep track of, so if we stop the execution flow right before the call instruction, what we have is the stack right before all this stuff… the function arguments at the top of the stack ;)

(gdb) run AAAAAA
Starting program: /home/carlos/Dropbox/hacking/wargames/pass_cli AAAAAA

Breakpoint 1, 0x0804851e in main () <--- breakpoint is hit
(gdb) info reg
eax 0xbffff620 -1073744352
ecx 0x6 6
edx 0xbffff3c9 -1073744951
ebx 0x283ff4 2637812
esp 0xbffff3b0 0xbffff3b0 <--- "top" of the stack
ebp 0xbffff3d8 0xbffff3d8
esi 0x0 0
edi 0x0 0
eip 0x804851e 0x804851e
eflags 0×286 [ PF SF IF ]
cs 0×73 115
ss 0x7b 123
ds 0x7b 123
es 0x7b 123
fs 0×0 0
gs 0×33 51

Let’s examine the top of the stack. We are actually interested in the first three words.

(gdb) x/12x $esp
0xbffff3b0: 0xbffff620 0xbffff3c9 0×00000006 0xbffff3d8
0xbffff3c0: 0x0015d4a5 0x0011e0c0 0x6d6f797b 0x00616d61
0xbffff3d0: 0×08048570 0×00000000 0xbffff458 0x00144bd6

Without further inspection we can see a 6, the number of char the function has to compare. It looks good at least ;) Let’s remember the exact syntaxis of strncmp()

carlos@dell:~/Dropbox/hacking/wargames$ man 3 strncmp

[...]

SYNOPSIS
#include

int strcmp(const char *s1, const char *s2);

int strncmp(const char *s1, const char *s2, size_t n); <--- allright, three arguments...

[...]

Also one of the first two words must be a pointer to the hardcoded password, the other a pointer to the user input (argv[1] in this case)

(gdb) x/4x 0xbffff620
0xbffff620: 0×41414141 0x4f004141 0×54494252 0x434f535f

Well, this is pretty clearly our string of 6 “A’s” null-terminated. The other address must be the location of our password!

(gdb) x/4x 0xbffff3c9
0xbffff3c9: 0x616d6f79 0×7000616d 0×00080485 0×58000000

OK, another string of 6 characters, null-terminated. The ASCII char associated to these values can be displayed in gdb as follows:

(gdb) p/c *0xbffff3c9
$16 = 121 ‘y
(gdb) p/c *0xbffff3ca
$17 = 111 ‘o
(gdb) p/c *0xbffff3cb
$18 = 109 ‘m
(gdb) p/c *0xbffff3cc
$19 = 97 ‘a
(gdb) p/c *0xbffff3cd
$20 = 109 ‘m
(gdb) p/c *0xbffff3ce
$21 = 97 ‘a
(gdb) p/c *0xbffff3cf
$22 = 0 ‘\000

So here’s the magic password! YOMAMA! ;)

OK, I must admit it. I love to pipe commands, I always thought is one of the most powerful features of the linux command line.

The following case is an excellent example.

Now and then I’ve been experiencing random increments in my hard disk usage. And with increments I mean the whole processor was busy with I/O operations. I asked some colleagues, experienced Linux administrators if there were a tool like top, with which I would be able to find out which process is accessing the disk at most. No one came with an answer.

After some research I found a quite satisfactory solution using a bit of bash.


root@dell:~# pidstat -d | sort -nr -k 4 | head -10

[...]
16:18:50          898      0,00    236,30 0,00  kjournald2
16:18:50            1     28,97     44,90      1,17  init
16:18:50          416      0,00      6,07      0,00  kjournald2
16:18:50         1915      2,05      1,94      0,05  compiz.real
16:18:50         1204      0,90      0,40      0,01  cron
16:18:50        11618      0,00      0,31      0,07  bash
16:18:50         1125      1,54      0,16      0,00  mount.ntfs
16:18:50         8232      0,08      0,15      0,00  liferea
16:18:50         1344      0,09      0,13      0,00  devkit-power-da

This runs the command pidstat -d, which gives info about disk usage per pid. Then uses the fourth column as index to order numerically the ouput. Note the use of the -r modifier, this is because the normal operation of sort is to show the lower values first and we need the opposite in this case. Finally, the head command just show us the first 10 lines, this is more than necessary.

The fourth column of pidstat’s output is the number of kB (read) pro second. In case you cannot find any value really out of bounds, you can give it a try with “sort -nr -k 3″ which would give us the processes that went amok on reading.

As a further investigation you can use the PID of the process (second column) with lsof to find out which files are being accessed by the crazy proc and try to figure out the exact cause of the problem.

What you do now with this info is up to you :)

UPDATE: it looks like this is not the best method and there is already a “top-like” monitor for disk activity, called iotop.

root@dell:~# apt-get install iotop

SLCM: Some Linux CLI Magic

I’m right now taking the PWB course (yes, from the creators of Backtrack!) and I must say it is really well structured. Even at the beginning, where very basic concepts/techniques are introduced, it forces you to review interesting stuff. And this is one of the strong points of the course: it’s mostly practical.

While in the process of enumerating usernames from an insecure mail server I had to write a short Python script and feed it with a wordlist of common usernames. The list I had was written in uppercase but what I wanted was lowercase. After some research about the sed command I found a neat way to do this using the command line:

carlos@dell:~$ sed -i ‘y/’ABCDEFGHIJKLMNOPQRSTUVWXYZ’/'abcdefghijklmnopqrstuvwxyz’/’ 200_usernames.txt

where -i means “in place”, that is, search for the pattern, perform the substitution and write on the same file (use with caution!). If you want to test before destroying the original file, -e can be used instead, which writes to the standard output.

This way, besides the pure offensive security stuff you learn, one is forced to research and learn some basic programming and command line tricks as well. Bonus! ;)

DLL injection, baby

There are a lot of concepts (specially in the world of computer security) which look very mystic and dll injection is, without any doubt, one of those. I’ll just post here a proof of concept because… well, because I think it’s interesting shit! :)

I’ll do it on Linux because I feel more comfortable in this OS but the concept is similar in MS Windows. First of all, an excerpt from an online program library howto:

Shared libraries are libraries that are loaded by programs when they start. When a shared library is installed properly, all programs that start afterwards automatically use the new shared library. It’s actually much more flexible and sophisticated than this, because the approach used by Linux permits you to:

  • update libraries and still support programs that want to use older, non-backward-compatible versions of those libraries;
  • override specific libraries or even specific functions in a library when executing a particular program.
  • do all this while programs are running using existing libraries.

The second point is the interesting one for us, since it will allow us to “impersonate” some of the functions the program calls that are situated inside dynamic link libraries. Several examples crossed my mind right now, all of them containing functions with names like checkPassword() or something similar :)

Instead of giving a boring lecture I’ll try to explain every point on the way. Let’s say our target program is this one (core.c):

#include <stdio.h>
#include <stdint.h>
#include <time.h>

int
main(int argc, char **argv)
{
time_t result;

printf(“I’m about to call time() in time.h\n”);
result = time(NULL);
printf(“The time is %ju secs\n”, (uintmax_t)result);

return(0);
}

It just get the system time using the time() function in glibc 2.0 and prints it to the console.

carlos@pattern:~/Projects/dll_injection$ ./core
I’m about to call time() in time.h
The time is 1253876880 secs
carlos@pattern:~/Projects/dll_injection$ ./core
I’m about to call time() in time.h
The time is 1253876888 secs

Until here, nothing really interesting so let’s get a bit more deep. In order to get the system time, core.c uses a function which code is not in my program but inside a shared library. Our core.c program publishes, after compiling, a series of symbols, that is, information about where should these functions code be inserted. This can be inspected with nm:

carlos@pattern:~/Projects/dll_injection$ nm core
08049f20 d _DYNAMIC
08049ff4 d _GLOBAL_OFFSET_TABLE_
0804853c R _IO_stdin_used
[...]
0804a014 W data_start
0804a020 b dtor_idx.6637
08048400 t frame_dummy
08048424 T main
U printf@@GLIBC_2.0
U puts@@GLIBC_2.0
U time@@GLIBC_2.0

Notice how time and printf are listed here. We can see as well what libraries are linked at runtime with ldd:

carlos@pattern:~/Projects/dll_injection$ ldd core
linux-gate.so.1 =>  (0xb8058000)
libc.so.6 => /lib/tls/i686/cmov/libc.so.6 (0xb7eda000)
/lib/ld-linux.so.2 (0xb8059000)

As expected, the libc is listed here, along with a very special one ld-linux.so.2, the dynamic linker/loader.

From the man page:

ld.so loads the shared libraries needed by a program, prepares the program to run, and then runs it.  Unless  explicitly  specified  via  the -static  option to ld during compilation, all Linux programs are incomplete and require further linking at run time.

[SuperNerd parenthesis]

GCC inserts at compile time an ELF header specifying which dynamic loader will be used at runtime:

carlos@pattern:~/Projects/dll_injection$ readelf -l core

Elf file type is EXEC (Executable file)
Entry point 0×8048370
There are 8 program headers, starting at offset 52

Program Headers:
Type           Offset   VirtAddr   PhysAddr   FileSiz MemSiz  Flg Align
PHDR           0×000034 0×08048034 0×08048034 0×00100 0×00100 R E 0×4
INTERP         0×000134 0×08048134 0×08048134 0×00013 0×00013 R   0×1
[Requesting program interpreter: /lib/ld-linux.so.2]
LOAD           0×000000 0×08048000 0×08048000 0×00580 0×00580 R E 0×1000
LOAD           0x000f0c 0x08049f0c 0x08049f0c 0×00110 0×00118 RW  0×1000
DYNAMIC        0x000f20 0x08049f20 0x08049f20 0x000d0 0x000d0 RW  0×4
NOTE           0×000148 0×08048148 0×08048148 0×00020 0×00020 R   0×4

[...]

That instructs the OS to pass the control of the program to ld-linux.so.2 instead of the normal entry point of the application.

[End of SuperNerd parenthesis]

ld-linux.so.2 checks the symbols (the way nm does), searches for the library files and loads the corresponding code into the process memory.

There’s a way, however, of preloading a shared object (or dll) at run time giving it precedence over this process. Here is where the technical info gets obscure but I guess this lib becomes a preferred target for symbol retrieval, so if it contains a symbol with a matching name, its code will be loaded and this dependency marked as satisfied.

That’s all we need to know. Let’s create our shared object then with a function called… yes, time()

carlos@pattern:~/Projects/dll_injection$ cat lib_evil.c

/* The evil library.
It exports the symbol time()
and overrides glibc
*/

#include <stdio.h>

int time()
{
printf(“FAKE TIME FUNCTION says: No you didn’t!\n”);
return(1234);
}

and compile it as shared object:

To create the object file:

$ gcc -c -fPIC -ggdb -Wall -o lib_evil.o lib_evil.c

To create the shared object (library .so):

$ ld -shared lib_evil.o -o lib_evil.so

Finally, let’s try our cool DLL injection, preloading our evil shared object.

Normal operation

carlos@pattern:~/Projects/dll_injection$ ./core
I’m about to call time() in time.h
The time is 1253881612 secs

DLL injection
carlos@pattern:~/Projects/dll_injection$ LD_PRELOAD=”./lib_evil.so” ./core
I’m about to call time() in time.h
FAKE TIME FUNCTION says: No you didn’t!
The time is 1234 secs

Now find your favourite software and try to bypass authentication following this pseudocode:

function checkPassword

return EverythingCool ;)

Powered by WordPress | Theme: Motion by 85ideas.