Giter Site home page Giter Site logo

final-submission-dropbear-u's Introduction

Add a new command-line switch -U to the Dropbear ssh server

Author: Orwa Watad

This command-line switch (e.g. dropbear -U) will make dropbear wait for UDP packet on port 53 (by default).

A specific UDP port can be opened with the command-line -p (e.g. dropbear -Up port_number).

By sending valid packets, you can open new TCP ports for the server. then the server does not need to run again.

Content files

What the folder contains:

  • dropbear-source.zip - this zip file contains the source code from this link Dropbear SSH
  • dropbear-U - this zip file contains the code of the server after my changes to add a new command-line switch -U

build

First, unzip the attached file "dropbear-U.zip", in addition to server files, you will find the following files:

  • client.c - I created it while working on the server for an experiment.
  • client.py - Python script sends a packet to a UDP port (with a specific struct).
  • test.py - Python script to test the server if it is working properly after adding the command-line switch.

To build the server, enter the following commands while you are in the folder (I have been using powers 'sudo'):

make clean
./configure
make

Run

To run the server with and wait for UDP packet on port 53:

dropbear -U

Then the server will open port number 53 and wait for UDP packet.

You can check open ports by this command:

netstat -tulpn

To open a specific new TCP port you should use the python script 'client.py' with the following command:

python3 client.py

Follow the instructions that appear, then send the package.

For Example (with python script - client.py):

ubuntu@ubuntu:~/Documents/GitHub/dropbear$ python3 client.py 
Hello, to send packets please enter the following data:
please enter the destination address (empty is your local address): 
please enter the destination port: 53
please enter the magic number: 0xDEADBEEF
please enter the new port for tcp: 22
please enter the shell command: 
msg from server: The magic number is correct! -> The port opened successfully.

For Example (with c file - client.c):

ubuntu@ubuntu:~/Documents/GitHub/dropbear$ ./client 192.168.146.130 53 3735928559 22 null
Size struct: 264
The magic number is correct! -> The port opened successfully.

You can monitor the ports via the command I mentioned earlier.

NOTICE:

  • To send a packet with 'client.py', the magic number can be written in two ways: 0xDEADBEEF or DEADBEEF.
  • To send a packet with 'client.c', the magic number can be written only in the following way: 3735928559.

The structure of the packet that the client sends is as follows:

struct listen_package_t
{
    uint32_t magic;
    uint16_t port_number;
    char shell_command[256];
};

Testing

Attached a file named: test.py

It can be run by the following command:

python3 test.py

For example:

ubuntu@ubuntu:~/Documents/GitHub/dropbear$ python3 test.py
----------------------------------------------------------------------
Ran 10 tests in 0.052s

OK

Valgrind

I tested the original code with valgrind and my code after changes and get the same result:

The source code with this command: 'sudo valgrind --leak-check=full dropbear', And open some ports.

==18631== Warning: noted but unhandled ioctl 0x5441 with no size/direction hints.
==18631==    This could cause spurious value errors to appear.
==18631==    See README_MISSING_SYSCALL_OR_IOCTL for guidance on writing a proper wrapper.
==18633== could not unlink /tmp/vgdb-pipe-from-vgdb-to-18633-by-root-on-???
==18633== could not unlink /tmp/vgdb-pipe-to-vgdb-from-18633-by-root-on-???
==18633== could not unlink /tmp/vgdb-pipe-shared-mem-vgdb-18633-by-root-on-???
==18631== 
==18631== HEAP SUMMARY:
==18631==     in use at exit: 65 bytes in 1 blocks
==18631==   total heap usage: 4,705 allocs, 4,704 frees, 782,397 bytes allocated
==18631== 
==18631== LEAK SUMMARY:
==18631==    definitely lost: 0 bytes in 0 blocks
==18631==    indirectly lost: 0 bytes in 0 blocks
==18631==      possibly lost: 0 bytes in 0 blocks
==18631==    still reachable: 65 bytes in 1 blocks
==18631==         suppressed: 0 bytes in 0 blocks
==18631== Reachable blocks (those to which a pointer was found) are not shown.
==18631== To see them, rerun with: --leak-check=full --show-leak-kinds=all
==18631== 
==18631== For counts of detected and suppressed errors, rerun with: -v
==18631== ERROR SUMMARY: 0 errors from 0 contexts (suppressed: 0 from 0)

The code after changes with this command: 'sudo valgrind --leak-check=full dropbear -U' And open some ports.

==18565== Warning: noted but unhandled ioctl 0x5441 with no size/direction hints.
==18565==    This could cause spurious value errors to appear.
==18565==    See README_MISSING_SYSCALL_OR_IOCTL for guidance on writing a proper wrapper.
==18566== could not unlink /tmp/vgdb-pipe-from-vgdb-to-18566-by-root-on-???
==18566== could not unlink /tmp/vgdb-pipe-to-vgdb-from-18566-by-root-on-???
==18566== could not unlink /tmp/vgdb-pipe-shared-mem-vgdb-18566-by-root-on-???
==18565== 
==18565== HEAP SUMMARY:
==18565==     in use at exit: 65 bytes in 1 blocks
==18565==   total heap usage: 4,754 allocs, 4,753 frees, 803,759 bytes allocated
==18565== 
==18565== LEAK SUMMARY:
==18565==    definitely lost: 0 bytes in 0 blocks
==18565==    indirectly lost: 0 bytes in 0 blocks
==18565==      possibly lost: 0 bytes in 0 blocks
==18565==    still reachable: 65 bytes in 1 blocks
==18565==         suppressed: 0 bytes in 0 blocks
==18565== Reachable blocks (those to which a pointer was found) are not shown.
==18565== To see them, rerun with: --leak-check=full --show-leak-kinds=all
==18565== 
==18565== For counts of detected and suppressed errors, rerun with: -v
==18565== ERROR SUMMARY: 0 errors from 0 contexts (suppressed: 0 from 0)
==18537== 
==18537== HEAP SUMMARY:
==18537==     in use at exit: 0 bytes in 0 blocks
==18537==   total heap usage: 124 allocs, 124 frees, 81,563 bytes allocated
==18537== 
==18537== All heap blocks were freed -- no leaks are possible
==18537== 
==18537== For counts of detected and suppressed errors, rerun with: -v
==18537== ERROR SUMMARY: 0 errors from 0 contexts (suppressed: 0 from 0)

Where changes have occurred:

-- Complete changes can be found HERE

Most of the changes occurred in the main file: svr_main.c

But I also needed to make minor changes to the following files:

  • default_options.h
#define DROPBEAR_DEFPORT_UDP "53"
  • runopts.h
bool is_udp;
  • svr-runopts.c
"-U   	Listen for UDP packet on port 53" // Orwa Watad

...

case 'U':
	  svr_opts.is_udp = true;
	  break;

...

if (svr_opts.is_udp)
	svr_opts.ports[0] = m_strdup(DROPBEAR_DEFPORT_UDP);
else
	svr_opts.ports[0] = m_strdup(DROPBEAR_DEFPORT);
  • sysoptions.h
#define MAX_LISTEN_ADDR_UDP (DROPBEAR_MAX_PORTS*3) // Orwa Watad
  • netio.c (in the function: dropbear_listen)
if (svr_opts.is_udp){
	hints.ai_socktype = SOCK_DGRAM;
}
else{
	hints.ai_socktype = SOCK_STREAM;
}

...

if (!svr_opts.is_udp) // Orwa Watad
	set_sock_nodelay(sock);

...

if (!svr_opts.is_udp){
	if (listen(sock, DROPBEAR_LISTEN_BACKLOG) < 0){
          // code
	}
}

Changes in the main file (svr_main.c):

#ifndef MAGIC_KEY
#define MAGIC_KEY 0xDEADBEEF
#endif

struct listen_package_t
{
    uint32_t magic;
    uint16_t port_number;
    char shell_command[256];
};

...

int listensocks_udp[MAX_LISTEN_ADDR_UDP]; // Orwa watad
size_t listensockcount_udp = 0; // Orwa watad

...

if (svr_opts.is_udp)
	/* Set up the listening sockets */ // UDP
	listensockcount_udp = listensockets(listensocks_udp, MAX_LISTEN_ADDR_UDP, &maxsock, true);
else
	/* Set up the listening sockets */ // TCP
	listensockcount = listensockets(listensocks, MAX_LISTEN_ADDR, &maxsock, false);

if (listensockcount == 0 && listensockcount_udp == 0)
{
	dropbear_exit("No listening ports available.");
}

for (i = 0; i < listensockcount_udp; i++) {
	FD_SET(listensocks_udp[i], &fds);
}

...

// Inside for(;;) with select

for (i = 0; i < listensockcount_udp; i++) {
	FD_SET(listensocks_udp[i], &fds);
}

...

for (i = 0; i < listensockcount_udp; i++) {
	if (!FD_ISSET(listensocks_udp[i], &fds)) 
		continue;
        .... // handle each UDP socket which has something to say (package has arrived)

...

// 'listensockets' function

svr_opts.is_udp = is_udp; // Enables dropbear_listen function yo open a new TCP port

Things to improve

There are two things that I noticed after I tested the server, but for lack of time and I do not know if it is required to handle the case, I didn't touch that, but I have an idea how to do it.

  1. In the current version, you can open more than one UDP protocol on the same port.
dropbear -U      # open UDP port number 53
dropbear -U      # also open UDP port number 53
  1. In the current version, it is sufficient to use the command-line switch -U once, it opens all ports after with UDP protocol, like this:
dropbear -Up 44 -p 55 -p 88        # it's same with: dropbear -Up 44 -Up 55 -Up 88

What I learned from this task

Screenshots - simulation

  1. Before everything:

SCREESHOT DECSRIPTION

  1. Run the server with this command "dropbear -U" and wait for UDP packet on port 53.

SCREESHOT DECSRIPTION

  1. Send a UDP packet to the port 53, with right magic number, to open TCP port number 4444:

SCREESHOT DECSRIPTION

  1. Send a UDP packet to the port 53, with wrong magic number, to open TCP port number 7777:

SCREESHOT DECSRIPTION

  1. Connect to ssh to TCP port number 4444:

SCREESHOT DECSRIPTION

  1. Connect to ssh to TCP port number 4444 (from another client):

SCREESHOT DECSRIPTION

  1. Close the connection between the second client:

SCREESHOT DECSRIPTION

  1. Close the connection between the first client:

SCREESHOT DECSRIPTION


  • Run the server with this command "dropbear -Up 4444" and wait for UDP packet on port 53.

SCREESHOT DECSRIPTION

  • Send a UDP packet to the port 4444, with right magic number, to open TCP port number 2222:

SCREESHOT DECSRIPTION

Screenshots - scattered

SCREESHOT DECSRIPTION SCREESHOT DECSRIPTION SCREESHOT DECSRIPTION SCREESHOT DECSRIPTION SCREESHOT DECSRIPTION SCREESHOT DECSRIPTION SCREESHOT DECSRIPTION SCREESHOT DECSRIPTION

final-submission-dropbear-u's People

Contributors

theorwa avatar

Watchers

James Cloos avatar  avatar

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.