Trying to execute a .sh script on DD-WRT but having issues

Post new topic   Reply to topic    DD-WRT Forum Index -> Atheros WiSOC based Hardware
Author Message
Rocketboy235
DD-WRT User


Joined: 14 Oct 2016
Posts: 109
Location: United States

PostPosted: Thu Feb 01, 2018 4:10    Post subject: Trying to execute a .sh script on DD-WRT but having issues Reply with quote
Hello,

I am trying to setup a username/password authentication for my OpenVPN server on my router but am having issues trying to execute the script.

https://www.dd-wrt.com/wiki/index.php/OpenVPN#Auth_with_username_and_password

I'm trying to run verify.sh so I can generate a hash for the password but at first I was getting-sh ./verify.sh: Permission denied. I then did chmod +x verify.sh but am now getting a different issue. I now am getting -sh ./verify.sh: not found. Does anyone know what may be causing this issue? I'm doing this within the /tmp directory.

Thanks!
Sponsor
Rocketboy235
DD-WRT User


Joined: 14 Oct 2016
Posts: 109
Location: United States

PostPosted: Sun Feb 04, 2018 23:56    Post subject: Reply with quote
Thanks eibgrad! Wish I could rep you on here. Anyway, I guess all it needed was to do sh ./verify.sh.

I used notepad++ earlier so should be all good on that part.

Now I'm getting a different error but it's a syntax script error so I think I should be good from here (going to have to do some debugging now...). Thanks again!

Edit: Nevermind. Realized it was the Windows to Linux error. Converted the file and it works like a charm now! Thanks! (Though strange that I'm getting this problem when I was using Notepad++)
ian5142
DD-WRT Guru


Joined: 23 Oct 2013
Posts: 2319
Location: Canada

PostPosted: Mon Feb 05, 2018 0:58    Post subject: Execute Reply with quote
Make sure it is executable, should be 755. Verify it with a gui program (WinSCP is what I use).
_________________
Before asking a question on the forums, update dd-wrt: Where do I download firmware? I suggest reading it all.
QCA Best WiFi Settings


Some dd-wrt wiki pages are up to date, others are not. PM me if you find an old one.

Atheros:
Netgear R7800 x3 - WDS AP / station, gateway, QoS
TP-Link Archer C7 v2 x2 - WDS Station
TP-Link TL-WDR3600 v1 - WDS Station
TP-Link 841nd v8 - NU
D-Link 615 C1/E3/I1 x 7 - 1 WDS station
D-Link 825 B1 - NU
D-Link 862L A1 x2 - WDS Station
Netgear WNDR3700v2 - NU
UBNT loco M2 x2 - airOS

Broadcom
Linksys EA6400 - Gateway, QoS
Asus N66U - AP
Netgear WNDR3700v3 - not used
MediaTek
UBNT EdgeRouter X - switch
Rocketboy235
DD-WRT User


Joined: 14 Oct 2016
Posts: 109
Location: United States

PostPosted: Mon Feb 19, 2018 0:57    Post subject: Reply with quote
Thanks for your help guys.

So now I'm stuck on another issue but related (still a shell script issue)...

So I'm trying to get this verify.sh file to work properly but it seems like it does not execute properly when it reaches this line of code?

Code:

 for i in $USERS; do
                Name=${i%:*}
                PassHash=${i#*:}


My DD-WRT router somehow has trouble trying to parse the for loop statement and I'm not sure why. $USERS does has a value which it is equal to the string of names in the user file (defined at the beginning of the script). I tried running something similar (just as a test) on a Linux computer to see if that worked and it worked fine. But for some reason, it's not working on my router. I'm currently at a lost here Confused Sad .


Thanks for helping guys!

------

My verify.sh file below for reference (also attached) (please don't mind the echo commands below as those are used for debugging purposes).

Code:

#!/bin/sh

USERS=`cat ./users`
genhash() {

        HASHPASS=`echo -n "$1$2" | md5sum | sed s'/\  -//'`
        i=0
        while [ $i -lt 10 ]; do
                HASHPASS=`echo -n $HASHPASS$HASHPASS | md5sum | sed s'/\  -//'`
                i=`expr $i + 1`
        done
      echo -n $HASHPASS
        echo " $HASHPASS ">> /tmp/openvpn.log
}
verify() {
        Login=`echo $1 | awk '{print tolower($0)}'`
      #Take Login argument and convert it to all lowercase
        echo "Logging in as: $Login" >> /tmp/openvpn.log
        echo "Password is: $2" >> /tmp/openvpn.log
      echo "$#" >> /tmp/openvpn.log
        #[[ $# -eq 2 ]] || exit 1
      if [ "$#" -eq 2 ]
      then
      echo "IF comparison is true! Current value of counter i is $i" >> /tmp/openvpn.log
        for i in $USERS; do
                Name=${i%:*}
                PassHash=${i#*:}
            #Convert Name to all lowercase letters
                Logincmp=`echo $Name | awk '{print tolower($0)}'`
                echo "Logincmp is: $Logincmp" >> /tmp/openvpn.log
                if [ "$Logincmp" == "$Login" ]
                then
                        echo "Login('$Login') is equal to Logincmp('$Logincmp')" >> /tmp/openvpn.log
                        GENHASH=`genhash "$Login" "$2"`
                        echo "genhash returned $GENHASH" >> /tmp/openvpn.log
                        echo "and PassHash is: $PassHash" >> /tmp/openvpn.log
                        if [ "$GENHASH" == "$PassHash" ]
                        then
                                echo "Password hashes match" >> /tmp/openvpn.log
                                exit 0
                        fi
                fi
        done
      fi
      echo "Reached end of verify function; counter of i is $i" >> /tmp/openvpn.log
}
if [ "$1" == "--genhash" ]
then
        Login=`echo $2 | awk '{print tolower($0)}'`
        echo `genhash "$Login" "$3"`
        exit 1
fi
verify `cat $*`
echo "Hit the end of the shell script!" >> /tmp/openvpn.log
exit 1
Rocketboy235
DD-WRT User


Joined: 14 Oct 2016
Posts: 109
Location: United States

PostPosted: Mon Feb 19, 2018 4:36    Post subject: Reply with quote
Hi eibgrad,

Sorry for the vague wording. To clarify what I mean by "does not execute properly"... the script is pretty much skipping the For loop and everything contained in it and goes to the bottom of the script where it returns exit 1.
I am expecting it to go through the For Loop and at least execute the echo statements within the loop but it's not even reaching that part.

Also, thanks for the debugging tip. I was trying to have all of the output save into some file but ran into some issues. Haven't tried your method though so will give that a shot.
Rocketboy235
DD-WRT User


Joined: 14 Oct 2016
Posts: 109
Location: United States

PostPosted: Thu Feb 22, 2018 5:39    Post subject: Reply with quote
Hello,

So I found out that when I run the program by normally running it in bash directly, it would work fine. However, when I have it set up so that OpenVPN uses that shell script, it would not work.

I tried the -x and save to the log as you mentioned earlier which worked fine but would when trying to have OpenVPN use the shell script with that in the script, it says it could not execute the external program. I guess this might make sense since maybe OpenVPN isn't expecting that. For my OpenVPN Server configuration specifically for the verify script:

Code:
script-security 2
auth-user-pass-verify /tmp/test.sh via-file


Anyway, what I realized is that when I ran the script by itself and giving it a username and password argument within bash directly, it would work after reviewing the log. But when using that same sh script for OpenVPN, I would get the following Warning error: "WARNING: Failed running command (--auth-user-pass-verify): external program exited with error status: 1 "

I have no idea if maybe there is something in the .sh script that OpenVPN doesn't comprehend or maybe the arguments it is passing to the script aren't correct... though I did check the arguments by making use of the echo commands and saving it to some log and they seem okay. Guess I'm back to the issue where it keeps hitting that For loop and then just going straight to exit 1

Confused Sad

Hopefully someone maybe able to chime in on why this is happening. Thanks guys.
Rocketboy235
DD-WRT User


Joined: 14 Oct 2016
Posts: 109
Location: United States

PostPosted: Thu Mar 01, 2018 6:20    Post subject: Reply with quote
Anyone have any suggestions?
Ah-Pin-Kor
DD-WRT User


Joined: 19 Sep 2015
Posts: 267

PostPosted: Thu Mar 01, 2018 6:52    Post subject: Reply with quote
I see your script logs msgs at each stage to /tmp/openvpn.log. Did you check this file to see how far it went?

Also, there is a line in the script:
USERS=`cat ./users`
This kind of relative path is quite risky, depending on the current dir of the caller. Maybe you can try to fix the absolute path to /tmp/users so that line becomes:
USERS=`cat /tmp/users`
The /tmp/users file has to be there, of course.

_________________

Netgear R7800 kongpro 19.07 20190919 || Netgear R7000 36070M kongac (Client Bridge=5GHz, AP=2.4GHz with bridged VAP)
Linksys WRT32X davidc502 OpenWrt || Linksys WRT1200ACv1 Gargoyle 1.11.x
Linksys WRT1900ACSv2 dd-wrt 39956
Rocketboy235
DD-WRT User


Joined: 14 Oct 2016
Posts: 109
Location: United States

PostPosted: Mon Mar 12, 2018 1:45    Post subject: Reply with quote
Thanks for your help guys!

After deciding to sit down and spend a few hours trying to debug the script, I think I finally got it working. It turns out that when the verify.sh file was taking the inputs from OpenVPN (the username and login), the script was not handling the arguments correctly. I discovered this when I looked at the $1 and $2 argument values. I decided to modify my script to accommodate this.

Now my only last issue is determining where to properly store the verify script and the user list file so when the router reboots, it won't be deleted. I realize the /tmp folder isn't a good place at all after I rebooted the router but didn't bother changing the location since my first concern was fixing the script. Does anyone know a proper place to store the script and user list files? Thanks!

Now back to the script I worked on... I also made it very simple for now by just having it execute in 1 go instead of multiple functions.

It's not a pretty script and definitely could be written better but at least I manage to get it to work...

Here is the final look of the script (removed any unnecessary lines of code). One of the most important changes was how I was doing Login and Password.

I found out that the 'cat $*' was used to interpret the temporary OpenVPN file (based on the via-file argument in the server config) and then I had to separate the lines into 2 variables. From there, it was pretty easy. I also removed the lowercase conversion since I did not really need it and don't mind having the username case sensitive.

Code:

#!/bin/sh

USERS=`cat /tmp/users`

Login=`cat $* | sed '1!d'`
Password=`cat $* | sed '2!d'`

      HASHPASS=`echo -n "$Login$Password" | md5sum | sed s'/\  -//'`
        i=0
        while [ $i -lt 10 ]; do
                HASHPASS=`echo -n $HASHPASS$HASHPASS | md5sum | sed s'/\  -//'`
                i=`expr $i + 1`
        done
      
for i in $USERS; do
    Name=${i%:*}
    PassHash=${i#*:}
    if [ "$Name" == "$Login" ]
    then
        if [ "$HASHPASS" == "$PassHash" ]
      then
            echo "User Authenticated."
            exit 0
        fi
   fi
done
echo "Login credentials failed."
exit 1


Hope this helps anyone who may be having the same issue I was having. If you guys think this looks pretty good, I may go ahead and update the wiki with this though if I ever have free time in the future, I'll fix the code up so it will have multiple functions such as generating a hash value to add future users. Right now, the code is only capable of verifying and authenticating current users.
Rocketboy235
DD-WRT User


Joined: 14 Oct 2016
Posts: 109
Location: United States

PostPosted: Mon Mar 12, 2018 3:54    Post subject: Reply with quote
eibgrad wrote:

You know the irony in all this? It's entirely possible that adding username/password authentication makes your OpenVPN server *more* vulnerable!

What you have to realize is that everything *you* add has to be hardened from a security perspective. What looks like an oh so innocent little script, *might* be exploitable if not done correctly.

For example, are you aware that OpenVPN only allows the following character set for usernames?

A-Za-z0-9_@.-

Why? For fear that someone might produce a script that contains characters the shell *may* expand into executable code! For some reason, they don't place the same restriction on passwords. But if it was *me*, I would, and for the same reasons.

This is a different world than it was in the early days of the internet, when nobody concerned themselves about this kind of thing. But nowadays you have to be *very* security aware, even for little ol' shell scripts. Particularly when the client is interacting directly w/ it. Even the best developers have been burned by such vulnerabilities. And now to have end-users employing their own security scripting just doesn't seem like a good thing.

JMTC


Eibgrad, thank you for the insight. Initially, I was hoping that if someone had the OpenVPN client configuration file (.ovpn), they would still need to authenticate which would act as a 2nd layer of protection. But, if by setting up a script for username/password authentication would lead to more security exploits, what would you suggest? Or if you were in a situation of having to setup an OpenVPN server, how would you go about setting it up?

Thanks again.

Edit: I will update the script to at least make sure username and password characters are limited to certain characters. Not sure if having the username converted to all lowercase is more secure though.
Rocketboy235
DD-WRT User


Joined: 14 Oct 2016
Posts: 109
Location: United States

PostPosted: Fri Mar 30, 2018 23:10    Post subject: Reply with quote
Hello,

After looking into script security for a bit and seeking help on other sites. I have come back with a much improved script in terms of security and possibly performance. I think I learned a bit on how to write a more secure shell script but I still got a long ways to go.

I was wondering if you guys could quickly check it out and let me know if there is anything I'm missing. I hope that I can add this script to the wiki and remove all of the older user scripts that have security exploits.

Thanks!

Also, the USERS file defined below will have to be moved somewhere else instead of /tmp/ but my router doesn't support jffs due to low flash memory space so I'll have to go find some old flash drive and use that.

Code:

#!/bin/sh
#This script was made with via-file in mind

PATH=/usr/bin:/bin

#Function used for generating MD5 hash value of password multiple times
function hashround() {
    local hash rest
    read hash rest
    printf '%s%s' "$hash" "$hash" | /usr/bin/md5sum
}

#Location of the Approved Username/Password File
users="/tmp/users"

#Check to see if generated OpenVPN login file has any special characters
#Terminate script if special characters are used
if /bin/grep -q '[^-_a-zA-Z0-9]' "$1"
then
   echo "Illegal characters found in username/password." >&2
   exit 1
fi

#1st line is the username
username=`/usr/bin/awk 'NR==1' "$1"`
#2nd line is the password
password=`/usr/bin/awk 'NR==2' "$1"`

#Generate MD5 hash of given password and loop it 10 times before comparing with hash value in users file
hashpass=$(printf '%s%s' "$username" "$password" | /usr/bin/md5sum \
           | hashround | hashround | hashround | hashround | hashround \
           | hashround | hashround | hashround | hashround | hashround \
           | /usr/bin/cut -d' ' -f1)
      
if /bin/grep -Fxq "$username:$hashpass" "$users"
then
   echo "User Authenticated." >&2
   exit 0
fi

echo "Login credentials failed." >&2
exit 1


References:

Started asking here:
https://unix.stackexchange.com/questions/431788/how-to-make-sure-my-shell-script-cannot-be-exploited-by-argument-command-injecti
Then moved onto here:
https://codereview.stackexchange.com/questions/190349/openvpn-login-bash-shell-script-for-dd-wrt-router
Display posts from previous:    Page 1 of 1
Post new topic   Reply to topic    DD-WRT Forum Index -> Atheros WiSOC based Hardware All times are GMT

Navigation

 
Jump to:  
You cannot post new topics in this forum
You cannot reply to topics in this forum
You cannot edit your posts in this forum
You cannot delete your posts in this forum
You cannot vote in polls in this forum
You cannot attach files in this forum
You cannot download files in this forum